O ventilador está constantemente aceso quando a fonte de alimentação está conectada, mas fica em silêncio quando está apenas na bateria

0

Problema

O ventilador está constantemente ligado quando um laptop é conectado e não está carregando. Não barulhento, mas definitivamente audível.
No entanto, ele ocasionalmente fica em silêncio (girando mais devagar ou sem girar) quando o laptop não está conectado ou ainda está carregando.

Pergunta

Como conseguir o mesmo quando a máquina permanece conectada e não está carregando?
Talvez a solução seja tão simples assim: link

Máquina:

  • HP Elitebook 8470p
  • Ubuntu 13.10 LTS (instalação limpa, na verdade, sabor Lubuntu, mas não faz diferença)
  • intel i5-3360M
  • uname -a : Linux elite 3.11.0-12-genérico # 19-Ubuntu SMP Qua 09 de outubro 16:20:46 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
  • 8 GB de RAM
  • sata3 SSD
  • AMD Radeon HD 7570M
  • power_method : profile , power_profile : auto
por vucalur 03.03.2014 / 09:24

2 respostas

1

Eu tenho um laptop HP 4510s. O controle do ventilador funciona bem no Windows. Não funciona em nenhuma versão / distribuição Linux testada. Sob Linux / Ubuntu, o ventilador roda a uma velocidade muito baixa. Isso não é suficiente para manter as CPUs resfriadas o suficiente sob carga mais alta.

Eu tentei a maioria das dicas da internet sobre o controle do ventilador do laptop Linux, nenhum funcionou. Para listar, eu tentei lm_sensors, pwmconfig, acpi_os = configuração e inúmeras outras coisas sem sucesso. E eu atualizei o BIOS e não há nada além de "Fan always on on AC" e ele não faz o truque.

É possível obter os temps do sistema usando lm_sensors. Além disso, existem pontos de controle de ventilador

/ sys / devices / virtual / thermal / cooling_device * / cur_state (* de 0 a 4 estão ativos)

Acabei pegando o famoso script tp-fancontrol (para IBM ThinkPads) de

link

e estragou tudo como hp-fancontrol. Não me lembro o suficiente de meus estudos de automação (era 20 anos atrás), então ficou muito simples. Mas parece funcionar até agora. Ainda há muitos códigos que sobraram e é feio como ****. Eu instalei como / usr / bin / hp_fancontrol e adicionei o trigger para /etc/rc.local assim

# Start hp-fancontrol on multiuser
/usr/bin/hp-fancontrol -l -d

exit 0

Eu ficaria muito grato por qualquer coisa melhor, mesmo que seja apenas a parte control_loop, então por favor, comente. Além disso, seja gentil e leia as renúncias (feias como ... acima e código em si). O QUIET parece não funcionar, quebra DAEMONIZE.

#!/bin/bash

# hp-fancontrol 0.1 
# Based on tp-fancontrol (http://thinkwiki.org/wiki/ACPI_fan_control_script)
# Provided under the GNU General Public License version 2 or later or
# the GNU Free Documentation License version 1.2 or later, at your option.
# See http://www.gnu.org/copyleft/gpl.html for the Warranty Disclaimer.

# This script dynamically(?) controls fan speed on some HP laptop models 
# (ProBook 4510s) according to user-defined temperature thresholds.  It 
# implements its own decision algorithm, overriding the any embedded
# controller.
#
# Run 'hp-fancontrol --help' for options.
#
# For optimal fan behavior during suspend and resume, invoke 
# "hp-fancontrol -u" during the suspend process.
# 
# WARNING: This script relies on undocumented hardware features and
# overrides nominal hardware behavior. It may thus cause arbitrary
# damage to your laptop or data. Watch your temperatures!
#
# WARNING: The list of temperature ranges used below is much more liberal
# than the rules used by the embedded controller firmware, and is
# derived mostly from anecdotal evidence, hunches and wishful thinking.
# It is also model-specific (see http://thinkwiki.org/wiki/Thermal_sensors).

# Temperature ranges, per core:
# (min temperature: when to step up from 0-th fan level,
#  max temperature: when to step up to maximum fan level)
THRESHOLDS=( #  Core
# min  max   #  ----
  43   65    #  0
  43   65    #  1
)

# LEVELS=0 - 31 (5 bits)             # Fan speed levels
ANTIPULSE=1                          # Prevent fan pulsing noise
                                     # (reduces frequency of fan RPM updates)

OFF_THRESH_DELTA=3 # when gets this much cooler than 'min' above, may turn off fan
MIN_THRESH_SHIFT=0 # increase min thresholds by this much
MAX_THRESH_SHIFT=0 # increase max thresholds by this much
MIN_WAIT=180       # minimum time (seconds) to spend in a given level before 
                   # stepping down

HP_ACPI=/sys/devices/virtual/thermal/cooling_device

PID_FILE=/var/run/hp-fancontrol.pid
LOGGER=/usr/bin/logger
INTERVAL=3        # sample+refresh interval
SETTLE_TIME=6     # wait this many seconds long before applying anti-pulsing
RESETTLE_TIME=600 # briefly disable anti-pulsing at every N seconds
SUSPEND_TIME=5    # seconds to sleep when receiving SIGUSR1

SEP=','           # Separator char for display

WATCHDOG_DELAY=$(( 3 * INTERVAL ))
HAVE_WATCHDOG=false
HAVE_LEVELCMD=true

QUIET=false
DRY_RUN=false
DAEMONIZE=false
AM_DAEMON=false
KILL_DAEMON=false
SUSPEND_DAEMON=false
SYSLOG=false

usage() {
    echo "
Usage: $0 [OPTION]...

Available options:
   -s N   Shift up the min temperature thresholds by N degrees
          (positive for quieter, negative for cooler).
          Max temperature thresholds are not affected.
   -S N   Shift up the max temperature thresholds by N degrees
          (positive for quieter, negative for cooler). DANGEROUS.
   -t     Test mode
   -q     Quiet mode
   -d     Daemon mode, go into background (implies -q)
   -l     Log to syslog
   -k     Kill already-running daemon
   -u     Tell already-running daemon that the system is being suspended
   -p     Pid file location for daemon mode, default: $PID_FILE
"
    exit 1;
}

while getopts 's:S:qtdlp:kuh' OPT; do
    case "$OPT" in
        s) # shift thresholds
            MIN_THRESH_SHIFT="$OPTARG"
            ;;
        S) # shift thresholds
            MAX_THRESH_SHIFT="$OPTARG"
            ;;
        t) # test mode
            DRY_RUN=true
            ;;
        q) # quiet mode
            QUIET=true
            ;;
        d) # go into background and daemonize
            DAEMONIZE=true
            ;;
        l) # log to syslog
            SYSLOG=true
            ;;
        p) # different pidfile
            PID_FILE="$OPTARG"
            ;;
        k) # kill daemon
            KILL_DAEMON=true
            ;;
        u) # suspend daemon
            SUSPEND_DAEMON=true
            ;;
        h) # short help
            usage
            ;;
        \?) # error
            usage
            ;;
    esac
done
[ $OPTIND -gt $# ] || usage  # no non-option args

# no logger found, no syslog capabilities
$SYSLOG && [ ! -x $LOGGER ] && SYSLOG=false || :

if $DRY_RUN; then
    echo "$0: Dry run, will not change fan state."
    QUIET=false
    DAEMONIZE=false
fi

thermometer() { # output list of temperatures
    # 2 basic temperatures from CPU cores:
    CPU0='/usr/bin/sensors | /usr/bin/awk '/Core 0/ { print $3 }' | sed -e s/[^0-9]//g'
    CPU1='/usr/bin/sensors | /usr/bin/awk '/Core 1/ { print $3 }' | sed -e s/[^0-9]//g'
    echo -n "$CPU0 $CPU1 ";
    return 0
}

speedometer() { # output fan speed RPM
    read F0 < /sys/devices/virtual/thermal/cooling_device0/cur_state
    read F1 < /sys/devices/virtual/thermal/cooling_device1/cur_state
    read F2 < /sys/devices/virtual/thermal/cooling_device2/cur_state
    read F3 < /sys/devices/virtual/thermal/cooling_device3/cur_state
    read F4 < /sys/devices/virtual/thermal/cooling_device4/cur_state
    FAN=$(($F4+$F3*2+$F2*4+$F1*8+$F0*16))
    echo -n $FAN;
    return 0
}

setlevel() { # set fan speed level
    local LEVEL=$1
    if ! $DRY_RUN; then
        if $HAVE_LEVELCMD; then
        BLEVEL=$(echo "obase=2;$LEVEL" | bc)
        LEN=$(echo ${#BLEVEL})
        BLEVEL5='echo "0000"$BLEVEL'
        B5=${BLEVEL5:(-5)}
        echo ${B5:0:1} > /sys/devices/virtual/thermal/cooling_device0/cur_state
        echo ${B5:1:1} > /sys/devices/virtual/thermal/cooling_device1/cur_state
        echo ${B5:2:1} > /sys/devices/virtual/thermal/cooling_device2/cur_state
        echo ${B5:3:1} > /sys/devices/virtual/thermal/cooling_device3/cur_state
        echo ${B5:4:1} > /sys/devices/virtual/thermal/cooling_device4/cur_state
    else
        case "$LEVEL" in
        (auto)        LEVEL=0x80 ;;
        (disengaged)  LEVEL=0x40 ;;
        esac
            #echo 0x2F $LEVEL > $IBM_ACPI/ecdump
    fi
    fi
}

getlevel() { # get fan speed level
    # perl -e 'm/^EC 0x20: .* .(..)$/ and print $1 and exit 0 while <>; exit 1' < $IBM_ACPI/ecdump
    read F0 < /sys/devices/virtual/thermal/cooling_device0/cur_state
    read F1 < /sys/devices/virtual/thermal/cooling_device1/cur_state
    read F2 < /sys/devices/virtual/thermal/cooling_device2/cur_state
    read F3 < /sys/devices/virtual/thermal/cooling_device3/cur_state
    read F4 < /sys/devices/virtual/thermal/cooling_device4/cur_state
    FAN=$(($F4+$F3*2+$F2*4+$F1*8+$F0*16))
    echo -n $FAN;
}

log() {
    # $QUIET || echo "> $*"
    ! $SYSLOG || $LOGGER -t "'basename $0'[$$]" "$*"
}

cleanup() { # clean up after work
    $AM_DAEMON && rm -f "$PID_FILE" 2> /dev/null
    log "Shutting down, fan turned up"
    if ! $DRY_RUN; then
        if $HAVE_LEVELCMD; then
            setlevel 31
        fi
    fi
}

floor_div() {
    echo $(( (($1)+1000*($2))/($2) - 1000 ))
}

set_priority() {
    ! $DRY_RUN && renice -10 -p $$
}

init_state() {
    IDX=0
    NEW_IDX=0
    START_TIME=0
    MAX_IDX=31
    SETTLE_LEFT=0
    RESETTLE_LEFT=0
    FIRST=true
    RESTART=false
}

control_fan() {
    # Enable the fan in default mode if anything goes wrong:
    set -e -E -u
    trap "cleanup; exit 2" HUP INT ABRT QUIT SEGV TERM
    trap "cleanup" EXIT
    trap "log 'Got SIGUSR1'; setlevel 0; RESTART=true; sleep $SUSPEND_TIME" USR1

    init_state
    log "Starting dynamic fan control"

    # Control loop:
    while true; do
        # Get readouts
        TEMPS='thermometer'
        $QUIET || SPEED='speedometer'
        $QUIET || ECLEVEL='getlevel'
        NOW='date +%s'
        if echo "$TEMPS" | grep -q "[^ 0-9$SEP\n-]"; then
            echo "Invalid character in temperatures: $TEMPS" >&2; exit 1;
        fi

    OLDLEVEL=$ECLEVEL
    NEWLEVEL=$OLDLEVEL
    CHANGE=0

    for TEMP in $TEMPS; do
        if [ $TEMP -gt 430 ] ; then
        if [ $OLDLEVEL -lt 31 ] ; then
            CHANGE=$(($CHANGE+1)) ;
            # NEWLEVEL=$(($OLDLEVEL+1)) ;
        fi
        elif [ $TEMP -gt 410 ] ; then
                # No change between 41-43C
        CHANGE=$(($CHANGE)) ;
        else
        if [ $OLDLEVEL -gt 0 ] ; then
            CHANGE=$(($CHANGE-1)) ;
            # NEWLEVEL=$(($OLDLEVEL-1)) ;
        fi
        fi
        NEWLEVEL=$(($OLDLEVEL+$CHANGE)) ;
        if [ $NEWLEVEL -gt 31 ] ; then
        NEWLEVEL=31 ;
        fi
        if [ $NEWLEVEL -lt 0 ] ; then
                NEWLEVEL=0 ;
            fi
            OLDLEVEL=$NEWLEVEL ;
        done

        # Interrupted by a signal?
        if $RESTART; then
            init_state
            log "Resetting state"
            continue
        fi

        # Transition
        if [ "$ECLEVEL" != "$NEWLEVEL" ]; then
            START_TIME=$NOW
            log "Changing fan level: $ECLEVEL->$NEWLEVEL  (temps: $TEMPS)"
        fi

        setlevel $NEWLEVEL

        sleep $INTERVAL

        IDX=$NEW_IDX
        FIRST=false
    done
}

if $KILL_DAEMON || $SUSPEND_DAEMON; then 
    if [ -f "$PID_FILE" ]; then
    set -e
    DPID="'cat \"$PID_FILE\"'" 
    if $KILL_DAEMON; then
            kill "$DPID"
        rm "$PID_FILE"
        $QUIET || echo "Killed process $DPID"
    else # SUSPEND_DAEMON
        kill -USR1 "$DPID"
        $QUIET || echo "Sent SIGUSR1 to $DPID"
    fi
    else
        $QUIET || echo "Daemon not running."
        exit 1
    fi
elif $DAEMONIZE ; then
    if [ -e "$PID_FILE" ]; then
        echo "$0: File $PID_FILE already exists, refusing to run."
        exit 1
    else
        set_priority
        AM_DAEMON=true QUIET=false control_fan 0<&- 1>&- 2>&- &
    echo "$0: Starting as daemon"
        echo $! > "$PID_FILE"
        exit 0
    fi
else
    [ -e "$PID_FILE" ] && echo "WARNING: daemon already running"
    set_priority
    control_fan
fi
    
por tapiov 26.04.2014 / 16:30
0

As configurações de velocidade do ventilador explicitamente não estão sob o controle do SO ou podem estar erradas.

Mas existem alguns utilitários que eu conheço para o Windows. No entanto, alguns BIOSs oferecem opções para controlar o comportamento do ventilador. Você deve verificar essas opções no BIOS primeiro.

Não é recomendável usar utilitários que alterem o comportamento de algum hardware crucial.

    
por Vikas Swami 03.03.2014 / 10:23