Как контролировать скорость вентилятора?

Как я могу контролировать скорость вращения вентилятора компьютера?

На Windows есть замечательная программа под названием SpeedFan.

8 ответов

Примечание перед началом:

Эта функциональность зависит как от вашего оборудования, так и от программного обеспечения. Если ваше оборудование не поддерживает элементы управления скоростью вентилятора или не показывает их ОС, очень вероятно, что вы не сможете использовать это решение. Если это так, но программное обеспечение (также известное как ядро) не знает, как им управлять, вам не повезло.


  1. Установите пакеты lm- sensor и fancontrol.
  2. Настроить lm-сенсоры

    1. В терминальном типе sudo sensors-detect и ответьте ДА на все ДА / нет вопросов.
      (Потенциально, это может повредить вашу систему или вызвать сбой системы. Для многих систем это безопасно. Нет никаких гарантий, что этот процесс не навредит вашей системе навсегда, я просто думаю, что вероятность такого критического сбоя действительно очень мала Сохранение всей вашей работы для возможных сбоев / зависаний / перезапусков до обработки конфигурации системы - это всегда хорошая идея. Если вы не уверены, прочитайте комментарии и попробуйте поискать в Интернете и получить общий обзор, прежде чем ДА - все, возможно, отборных с вашими ДА-есами все равно будет достаточно)
    2. В конце обнаружения датчиков будет отображен список модулей, которые необходимо загрузить. Введите "yes", чтобы датчики-детекторы вставили эти модули в / etc / modules, или отредактируйте / etc / modules самостоятельно.
    3. Бегать sudo service module-init-tools restart, Это будет читать изменения, которые вы сделали в /etc/modules на шаге 3 и вставьте новые модули в ядро.
      • Примечание. Если вы работаете в Ubuntu 13.04 или более поздней версии, эту команду третьего шага следует заменить на sudo service kmod start,
  3. Настроить фанконтроль

    1. В терминальном типе sudo pwmconfig, Этот сценарий остановит каждый вентилятор на 5 секунд, чтобы выяснить, какими вентиляторами можно управлять с помощью какого ШИМ. После прохождения скрипта через все вентиляторы вы можете настроить, какой вентилятор соответствует какой температуре.
    2. Вам нужно будет указать, какие датчики использовать. Это немного сложно. Если у вас есть только один вентилятор, обязательно используйте датчик температуры для вашего ядра, чтобы основывать скорость управления вентилятором.
    3. Запустите подсказки и сохраните изменения в расположении по умолчанию.
    4. Внесите коррективы в тонкую настройку /etc/fancontrol и использовать sudo service fancontrol restart применить ваши изменения. (В моем случае я установил интервал в 2 секунды.)
  4. Настроить фанконтроль

    1. Бегать sudo service fancontrol start, Это также заставит службу fancontrol запускаться автоматически при запуске системы.

В моем случае /etc/fancontrol для процессора я использовал:

Настройки для hwmon0 / device / pwm2:
(Зависит от hwmon0/device/temp2_input) (Управляет hwmon0/device/fan2_input)

INTERVAL=2
MINTEMP=40  
MAXTEMP=60  
MINSTART=150  
MINSTOP=0  
MINPWM=0  
MAXPWM=255 

и в другой системе это:

INTERVAL=10
DEVPATH=hwmon1=devices/platform/coretemp.0 hwmon2=devices/platform/nct6775.2608
DEVNAME=hwmon1=coretemp hwmon2=nct6779
FCTEMPS=hwmon2/pwm2=hwmon1/temp2_input
FCFANS=hwmon2/pwm2=hwmon2/fan2_input
MINTEMP=hwmon2/pwm2=49
MAXTEMP=hwmon2/pwm2=83
MINSTART=hwmon2/pwm2=150
MINSTOP=hwmon2/pwm2=15
MINPWM=hwmon2/pwm2=14
MAXPWM=hwmon2/pwm2=255

Вот некоторая полезная информация о настройках и что они действительно делают

Если у вас есть ThinkPad, есть часть программного обеспечения под названием thinkfan это делает именно это. Как видно из названия, оно специально сделано для ThinkPads (thinkpad_acpi).

thinkfan Программное обеспечение доступно в стандартных репозиториях Ubuntu, но для его настройки требуется несколько шагов.

Вот простое пошаговое руководство:

http://staff.science.uva.nl/~kholshei/thinkfan_guide/

(в основном это переведенная версия этого немецкого руководства: http://thinkwiki.de/Thinkfan)


Соответствующая информация из почты:

Шаг 1. Установите программное обеспечение thinkfan и датчики:

sudo apt-get install thinkfan lm-sensors

Шаг 2. Убедитесь, что демон управляет вентилятором, отредактировав файл thinkpad.conf:

sudo nano /etc/modprobe.d/thinkfan.conf

добавив следующую строку:

options thinkpad_acpi fan_control=1

Шаг 3. Сделайте так, чтобы демон автоматически загружался при запуске, отредактировав файл:

sudo nano /etc/default/thinkfan

убедившись, что клавиша СТАРТ установлена ​​на да, то есть должна быть строка, которая говорит:

START=yes

Шаг 4. Определите датчики вашего ноутбука:

sudo sensors-detect

и просто выбирайте ответы по умолчанию всякий раз, когда вам будет предложено нажать Enter.

Шаг 5. Загрузите новые модули. В Ubuntu 13.10 это сделано:

sudo service kmod start

в то время как для предыдущих версий, таких как 13.04, вместо этого вам нужно будет выполнить:

sudo service module-init-tools start

Шаг 6. Определите, какие датчики используются:

sensors

(те, которые указывают 0 градусов, не используются, я не знаю, почему они тоже "обнаружены"). Помните, какие из них используются.

Шаг 7. Узнайте полные пути этих датчиков:

find /sys/devices -type f -name "temp*_input"

Вывод должен быть списком путей, таких как / sys / devices /...

Шаг 8. Скопируйте и вставьте пути к датчикам в файл конфигурации /etc/thinkpad.conf. Для этого сначала откройте файл:

sudo nano /etc/thinkfan.conf

Там уже должна быть строка, как

#sensor /proc/acpi/ibm/thermal (0, 10, 15, 2, 10, 5, 0, 3, 0, 3) 

(#-символ означает, что эта строка закомментирована). Добавьте строку, начинающуюся с датчика (без символа #), и скопируйте и вставьте первый датчик. Повторите это, если у вас есть более одного датчика. Например, на моей машине вывод в шаге 7 дает

/sys/devices/virtual/hwmon/hwmon0/temp1_input
/sys/devices/platform/thinkpad_hwmon/temp3_input
/sys/devices/platform/thinkpad_hwmon/temp4_input
/sys/devices/platform/thinkpad_hwmon/temp5_input
/sys/devices/platform/thinkpad_hwmon/temp6_input
/sys/devices/platform/thinkpad_hwmon/temp7_input
/sys/devices/platform/thinkpad_hwmon/temp1_input
/sys/devices/platform/thinkpad_hwmon/temp8_input
/sys/devices/platform/thinkpad_hwmon/temp2_input
/sys/devices/platform/coretemp.0/temp4_input
/sys/devices/platform/coretemp.0/temp2_input 

В моей машине используются те, которые указаны в первой и последних двух строках, поэтому я добавил три строки:

sensor /sys/devices/virtual/hwmon/hwmon0/temp1_input
sensor /sys/devices/platform/coretemp.0/temp4_input
sensor /sys/devices/platform/coretemp.0/temp2_input 

Шаг 9. Наконец, мы можем установить уровни скорости вентилятора в файле конфигурации. Откройте файл /etc/thinkpad.conf, если он еще не был открыт.

sudo nano /etc/thinkfan.conf

Уровни вентиляторов, которые я использую на ThinkPad X201:

(0, 0, 51)
(1, 50, 52)
(2, 51, 55)
(3, 54, 58)
(4, 56, 63)
(5, 60, 70)
(6, 66, 79)
(7, 74, 92)
(127, 85, 32767) 

Последняя строка обеспечивает полную скорость вращения вентилятора (127 = "отключено", т.е. не регулируется). Вы можете играть с этими уровнями, чтобы соответствовать вашим потребностям / желаниям, но ПОЖАЛУЙСТА, БУДЬТЕ ОСТОРОЖНЫ!

Шаг 10. Перезагрузка. Все должно работать сейчас. Чтобы проверить, правильно ли работает Thinkpad, используйте

sudo thinkfan -n

который запускает thinkfan в подробном режиме. Возможно, вы захотите сначала остановить демон thinkfan:

sudo /etc/init.d/thinkfan stop

Если вы хотите снова запустить демон thinkfan, введите:

sudo /etc/init.d/thinkfan start

Просто чтобы завершить, мой файл конфигурации /etc/thinkfan.conf:

# IMPORTANT:
#
# To keep your HD from overheating, you have to specify a correction value for
# the sensor that has the HD's temperature. You need to do this because
# thinkfan uses only the highest temperature it can find in the system, and
# that'll most likely never be your HD, as most HDs are already out of spec
# when they reach 55 °C.
# Correction values are applied from left to right in the same order as the
# temperatures are read from the file.
#
# For example:
# sensor /proc/acpi/ibm/thermal (0, 0, 10)
# will add a fixed value of 10 °C the 3rd value read from that file. Check out
# http://www.thinkwiki.org/wiki/Thermal_Sensors to find out how much you may
# want to add to certain temperatures.

# Syntax:
# (LEVEL, LOW, HIGH)
# LEVEL is the fan level to use (0-7 with thinkpad_acpi)
# LOW is the temperature at which to step down to the previous level
# HIGH is the temperature at which to step up to the next level
# All numbers are integers.
#

# I use this on my T61p:
#sensor /proc/acpi/ibm/thermal (0, 10, 15, 2, 10, 5, 0, 3, 0, 3)

#(0, 0, 55)
#(1, 48, 60)
#(2, 50, 61)
#(3, 52, 63)
#(4, 56, 65)
#(5, 59, 66)
#(7, 63, 32767)


# My settings for my ThinkPad X201: (kris)

sensor /sys/devices/virtual/hwmon/hwmon0/temp1_input
sensor /sys/devices/platform/coretemp.0/temp4_input
sensor /sys/devices/platform/coretemp.0/temp2_input

(0, 0, 51)
(1, 50, 52)
(2, 51, 55)
(3, 54, 58)
(4, 56, 63)
(5, 60, 70)
(6, 66, 79)
(7, 74, 92)
(127, 85, 32767)

Для нескольких компьютеров Dell вы можете установить пакет i8kutils:

sudo apt install i8kutils

Если у вас не протестированный Dell (например, мой Dell XPS 14z), вам может потребоваться принудительная загрузка модуля ядра:

sudo modprobe i8k force=1

Установите и настройте пакеты lm- sensor и fancontrol:

sudo apt-get install lm-sensors fancontrol

Документация по их настройке доступна на их страницах руководства.

Эта функция должна предоставляться в ACPI-совместимом BIOS, но, похоже, большинство производителей материнских плат не следуют стандарту.

Вот обновленная версия для ответа, рекомендующего thinkfan, работающего с Ubuntu 19.04.

Настроить

Приведенные ниже инструкции относятся к любому ThinkPad, который имеет /proc/acpi/ibm/fan а также /proc/acpi/ibm/thermal "устаревшие" устройства. Это позволяет избежать необходимости устанавливать lm-sensors пакет.

Тем не менее, вы все равно можете установить lm-sensors чтобы увидеть больше датчиков температуры и получить более детальный контроль над вашими вентиляторами (а именно с шагом 256 ШИМ, а не с фиксированными шагами "0-7 и 127" с устаревшими устройствами. Кроме того, так как thinkfan теперь можно работать с lm-sensors датчики, он больше не предназначен для компьютеров IBM / Lenovo ThinkPad. Ссылаться на man thinkfan для использования этих "расширенных" сенсорных устройств. Кроме того, в немецкой Thinkwiki есть актуальная информация.

  1. Установите необходимый пакет:

    sudo apt-get install thinkfan
    
  2. Добавьте следующую строку в /etc/modprobe.d/thinkfan.conf:

    options thinkpad_acpi fan_control=1
    
  3. Настройте thinkfan Сервис запускается автоматически при запуске системы:

    1. Добавить строку START=yes в /etc/default/thinkfan

    2. Выполните следующую команду ( источник):

      sudo systemctl enable thinkfan.service
      
  4. адаптироваться /etc/thinkfan.conf с правильными указателями на устройства и уровни вентиляторов, которые вы хотите. Комментарии там предоставляют документацию. На любом Thinkpad с устаревшим вентилятором и тепловыми устройствами следующее должно обеспечить хорошую отправную точку (также должно быть безопасно для жесткого диска, см. Комментарии в файле для получения дополнительной информации). Обратите внимание, что здесь используются новые ключевые слова - те, что в другом ответе выше, не рекомендуются.

    tp_fan /proc/acpi/ibm/fan
    tp_thermal /proc/acpi/ibm/thermal
    
    (0, 0, 47)
    (1, 43, 52)
    (2, 48, 55)
    (3, 51, 58)
    (4, 54, 63)
    (5, 59, 70)
    (6, 66, 79)
    (7, 74, 92)
    (127, 85, 32767) 
    

Тестовое задание

Чтобы проверить настройки (после перезагрузки), вы можете сделать следующее:

  • В одном окне терминала запустите thinkfan в недемонизированном режиме, чтобы вы могли видеть его сообщения:

    sudo service thinkfan stop && sudo thinkfan -n
    
  • В другом окне терминала следите за текущими значениями температуры, поставляя ваше устройство измерения температуры, если оно отличается:

    while true; do sleep 1; cat /proc/acpi/ibm/thermal; done
    
  • В еще одном окне терминала нагрейте процессор (и прервите его с помощью Ctrl + C, если что-то в управлении температурой не работает должным образом):

    sudo apt install stress-ng
    stress-ng --cpu-1
    

Попробуйте посмотреть в настройках UEFI (или BIOS) вашего ПК. Там может быть настройка для управления вентилятором, где вы можете поместить свой вентилятор в Silent Mode, Performance Mode, Full Speed, Customize, так далее.

Как получить доступ к настройкам UEFI: перезагрузите компьютер, и ключ для их ввода, вероятно, появится в одном из углов (например, Press F2 to enter UEFI setup)

Настройка ASRock UEFI для управления вентиляторами

Сценарий, который я запускаю каждые несколько секунд, чтобы мой сервер Dell оставался прохладным и тихим. Обновите get_temp для вашего оборудования.

      #!/bin/env python3

import os
import json

MIN_FAN = 5
MAX_FAN = 100

MIN_TEMP = 50 # fans at min at this temp
MAX_TEMP = 80 # fans at max at this temp

TEMP_POW = 3 # decrease for cooler server, increase for quiter

def get_temp():
    sensors = json.loads(os.popen('/usr/bin/sensors -j').read())
    temp0 = sensors["coretemp-isa-0000"]["Package id 0"]["temp1_input"]
    temp1 = sensors["coretemp-isa-0001"]["Package id 1"]["temp1_input"]
    return max(temp0, temp1)

def determine_fan_level(temp):
    x = min(1, max(0, (temp - MIN_TEMP) / (MAX_TEMP - MIN_TEMP)))
    return int(min(MAX_FAN, max(MIN_FAN, pow(x, TEMP_POW)*(MAX_FAN-MIN_FAN) + MIN_FAN)))

def set_fan(fan_level):
    # manual fan control
    os.system("ipmitool raw 0x30 0x30 0x01 0x00")
    # set fan level
    cmd = "ipmitool raw 0x30 0x30 0x02 0xff " + hex(fan_level)
    os.system(cmd)

temp = get_temp()
fan = determine_fan_level(temp)
print("temp", temp, "fan", fan)
set_fan(fan)

Для ноутбука HP следующие сценарии (которые я не являюсь автором), похоже, работают для меня, но...

... сначала дайте ссылку на лицензию (она слишком велика для включения сюда): https://www.gnu.org/licenses/gpl-3.0.txt .

      #!/usr/bin/perl -w

# Copyright (C) 2007  Michael Kurz     michi.kurz (at) googlemail.com
# Copyright (C) 2007  Petr Tomasek     tomasek (#) etf,cuni,cz
# Copyright (C) 2007  Carlos Corbacho  cathectic (at) gmail.com
#
# Version 0.6.1 (2007-11-08)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


require 5.004;

use strict;
use Fcntl;
use POSIX;
use File::Basename;

sub initialize_ioports
{
  sysopen (IOPORTS, "/dev/port", O_RDWR)
    or die "/dev/port: $!\n";
  binmode IOPORTS;
}

sub close_ioports
{
  close (IOPORTS)
    or print "Warning: $!\n";
}



sub inb
{
  my ($res,$nrchars);
  sysseek IOPORTS, $_[0], 0 or return -1;
  $nrchars = sysread IOPORTS, $res, 1;
  return -1 if not defined $nrchars or $nrchars != 1;
  $res = unpack "C",$res ;
  return $res;
}

# $_[0]: value to write
# $_[1]: port to write
# Returns: -1 on failure, 0 on success.
sub outb
{
  if ($_[0] > 0xff)
  {
    my ($package, $filename, $line, $sub) = caller(1);
    print "\n*** Called outb with value=$_[1] from line $line\n",
          "*** (in $sub). PLEASE REPORT!\n",
          "*** Terminating.\n";
    exit(-1);
  }
  my $towrite = pack "C", $_[0];
  sysseek IOPORTS, $_[1], 0 or return -1;
  my $nrchars = syswrite IOPORTS, $towrite, 1;
  return -1 if not defined $nrchars or $nrchars != 1;
  return 0;
}

sub wait_write
{
    my $i = 0;
    while ((inb($_[0]) & 0x02) && ($i < 10000)) {
        sleep(0.01);
        $i++;
    }
    return -($i == 10000);
}

sub wait_read
{
    my $i = 0;
    while (!(inb($_[0]) & 0x01) && ($i < 10000)) {
        sleep(0.01);
        $i++;
    }
    return -($i == 10000);
}

sub wait_write_ec
{
    wait_write(0x66);
}

sub wait_read_ec
{
    wait_read(0x66);
}

sub send_ec
{
    if (!wait_write_ec()) { outb($_[0], 0x66); }
    if (!wait_write_ec()) { outb($_[1], 0x62); }
}

sub write_ec
{
    if (!wait_write_ec()) { outb(0x81, 0x66 ); }
    if (!wait_write_ec()) { outb($_[0], 0x62); }
    if (!wait_write_ec()) { outb($_[1], 0x62); }
}

sub read_ec
{
    if (!wait_write_ec()) { outb(0x80, 0x66 ); }
    if (!wait_write_ec()) { outb($_[0], 0x62); }
    if (!wait_read_ec())  { inb(0x62); }
}

sub write_kc
{
    if (!wait_write(0x64)) { outb($_[0], 0x64); }
    if (!wait_write(0x64)) { outb($_[1], 0x60); }
}

sub print_regs
{
    initialize_ioports();

    my @arr = ("00","10","20","30","40","50","60","70","80","90","A0","B0","C0","D0","E0","F0", "");

    my $i = 0;
    my $t = 0;
    print "\n  \t00\t01\t02\t03\t04\t05\t06\t07\t|\t08\t09\t0A\t0B\t0C\t0D\t0E\t0F\n";
    print "  \t__\t__\t__\t__\t__\t__\t__\t__\t|\t__\t__\t__\t__\t__\t__\t__\t__\n";
    print "00 |\t";
    for ($i = 0; $i < 256; $i++)
    {
        $t = read_ec($i);
        print $t;
        print "\t";
        if ((($i + 1) % 8) == 0){
            if ((($i + 1) % 16) == 0) {
                if ($i != 255) { print "\n$arr[(($i-(($i + 1) % 16)) / 16) + 1] |\t"; }
            } else {
                print "|\t";
            }
        }
    }
    
    print "\n";
    
    close_ioports();
}

sub write_temp
{
    initialize_ioports();
    write_ec($_[0],$_[1]);
    close_ioports();
}

sub testnum
{
    my $i;
    for ($i = 0; $i<256;$i++) {
        if ($_[0] eq "$i") { return 1 };
    }
    return 0;
}

my $ii;

if (!$ARGV[0]){
        print "wrong arguments!\n";
    print "usage:\n";
    print "\'probook_ec regs\' \t\t\t\tdumps all ec registers\n";
    print "\'probook_ec ledon\' \t\t\t\tswitch on 'mail LED' (WMID)\n";
    print "\'probook_ec ledoff\' \t\t\t\tswitch off 'mail LED' (WMID)\n";
    print "\'probook_ec getled\' \t\t\t\tget 'mail LED' status (WMID)\n";
    print "\'probook_ec getled2\' \t\t\t\tget 'mail LED' status(AMW0)\n";
    print "\'probook_ec getwireless\' \t\t\t\tget 'wireless' status (AMW0)\n";
    print "\'probook_ec gettouch\' \t\t\t\tis the touchpad disabled?\n";
    print "\'probook_ec setfanthresh <temp>\' \t\t\t\tset temperature threshhold to <temp>, DANGEROUS!\n";
    print "\'probook_ec getfanthresh\' \t\t\t\tget temperature threshhold\n";
    print "\'probook_ec <temp-number> <temperature>\' \tfor setting a temperature\n";
    print "where <temp-number> is from 0-7, and <temperture> is from 0-255\n";
    print "\'probook_ec ?= <reg>\' \t\tQuery register's value\n";
    print "\'probook_ec := <reg> <val>\' \tSet register's value\n";
    print "\'probook_ec +f <reg> <val>\' \tOr register's value with val (to set flags)\n";
    print "\'probook_ec -f <reg> <val>\' \tAnd register's value with ~val (to clear flags)\n";
    print "\'forcekc\' \tTry all possible values on writeable RAM of keyboard controller\n";
    print "\'kcw <cmd> <val>\' \tWrite a command and a value to the keyboard controller\n";
} elsif ($ARGV[0] eq "regs") {
    print_regs();
} elsif ($ARGV[0] eq "getled") {
    # TM2490 only (WMID)
    initialize_ioports();
    if (read_ec(0x9f)&0x01) {
        print "Mail LED on\n";
    } else {
        print "Mail LED off\n"; }
    close_ioports();
} elsif ($ARGV[0] eq "getled2") {
    # Aspire 5020 only (AMW0)
    initialize_ioports();
    if (read_ec(0x0A)&0x80) {
        print "Mail LED on\n";
    } else {
        print "Mail LED off\n"; }
    close_ioports();
} elsif ($ARGV[0] eq "getwireless") {
    # Aspire 5020 only (AMW0)
    initialize_ioports();
    if (read_ec(0x0A)&0x4) {
        print "Wireless on\n";
    } else {
        print "Wireless off\n"; }
    close_ioports();
} elsif ($ARGV[0] eq "gettouch") {
    # TM2490 only - needs testing
    initialize_ioports();
    if (read_ec(0x9e)&0x08) {
        print "touchpad disabled\n";
    } else {
        print "touchpad enabled\n"; }
    close_ioports();
} elsif ($ARGV[0] eq "?=") {
    initialize_ioports();
    my $r = hex($ARGV[1]);
    printf("REG[0x%02x] == 0x%02x\n", $r, read_ec($r));
    close_ioports();
} elsif ($ARGV[0] eq ":=") {
    initialize_ioports();
    my $r = hex($ARGV[1]);
    my $f = hex($ARGV[2]);
    my $val = read_ec($r);
    #printf("REG[0x%02x] == 0x%02x\n", $r, $val);
    #printf("REG[0x%02x] := 0x%02x\n", $r, $f);
        write_ec( $r, $f);
    #printf("REG[0x%02x] == 0x%02x\n", $r, read_ec($r));
    #echo "$r:$f\n" >> regs_set
    close_ioports();
} elsif ($ARGV[0] eq "FANCTL") {
        initialize_ioports();
        write_ec(0x22,1);
        write_ec(0x26,0x1F);
        #write_ec(0x2F,0xFF);
        #printf("REG[0x%02x] == 0x%02x\n", 0x1E, read_ec(0x1E));
        close_ioports();
        #`notify-send FANOFF`;
} elsif ($ARGV[0] eq "FANOFF") {
    initialize_ioports();
    write_ec(0x22,1);
    write_ec(0x26,0x1F);
    write_ec(0x2F,0xFF);
    #printf("REG[0x%02x] == 0x%02x\n", 0x1E, read_ec(0x1E));
    close_ioports();
        #`notify-send FANOFF`;
} elsif ($ARGV[0] eq "FANRST") {
        initialize_ioports();
        write_ec(0x22,0x01);
    write_ec(0x26,0x00);
        #printf("REG[0x%02x] == 0x%02x\n", 0x22, read_ec(0x22));
        close_ioports();
} elsif ($ARGV[0] eq "+f") {
    initialize_ioports();
    my $r = hex($ARGV[1]);
    my $f = hex($ARGV[2]);
    my $val = read_ec($r);
    printf("REG[0x%02x] == 0x%02x\n", $r, $val);
    printf("REG[0x%02x] := 0x%02x\n", $r, $val | $f);
        write_ec( $r, $val | $f);
    printf("REG[0x%02x] == 0x%02x\n", $r, read_ec($r));
    close_ioports();
} elsif ($ARGV[0] eq "-f") {
    initialize_ioports();
    my $r = hex($ARGV[1]);
    my $f = hex($ARGV[2]);
    my $val = read_ec($r);
    printf("REG[0x%02x] == 0x%02x\n", $r, $val);
    printf("REG[0x%02x] := 0x%02x\n", $r, $val & ~$f);
        write_ec( $r, $val & ~$f);
    printf("REG[0x%02x] == 0x%02x\n", $r, read_ec($r));
    close_ioports();
} elsif ($ARGV[0] eq "ledon") {
    # TM2490 only - needs testing
    initialize_ioports();
    if (!wait_write(0x64)) { outb(0x59, 0x64); }
    if (!wait_write(0x64)) { outb(0x92,   0x60); }
    close_ioports();
} elsif ($ARGV[0] eq "ledoff") {
    # TM2490 only - needs testing
    initialize_ioports();
    if (!wait_write(0x64)) { outb(0x59, 0x64); }
    if (!wait_write(0x64)) { outb(0x93,   0x60); }
    close_ioports();
} elsif ($ARGV[0] eq "getfanthresh") {
    initialize_ioports();
    $ii=read_ec(0xa9);
    close_ioports();
        print "Temperature threshhold: $ii (celsius)\n";
} elsif (($ARGV[0] eq "setfanthresh") && testnum($ARGV[1])) {
    write_temp(0xA9,$ARGV[1]);
} elsif ($ARGV[0] eq "setbright") {
    # Aspire 5020 only (AMW0)
    if ($ARGV[1] >= 0 && $ARGV[1] <= 15) {
        write_temp(0x83, $ARGV[1]);
    } else {
        print "second argument must be a number between 0 and 15\n";
    }
} elsif ($ARGV[0] eq "forcekc") {
    # Be smart - we only send the commands for writing to keyboard RAM
    initialize_ioports();
    my ($kbdata, $cont, $kbreg);
    for ($kbreg = 0x40; $kbreg <= 0x5f; $kbreg++) {
        for ($kbdata = 0; $kbdata < 256; $kbdata++) {
            write_kc($kbreg, $kbdata);

            print sprintf("%0#4x", $kbreg), ", ", sprintf("%0#4x", $kbdata), "\n";
            print "Continue? y/n: ";
            $cont = <STDIN>;
            if ($cont eq "n") {
                last;
            }
        }
    }
    close_ioports();
} elsif ($ARGV[0] eq "kcw") {
    initialize_ioports();
    write_kc($ARGV[1], $ARGV[2]);
    close_ioports();
} else {
    print "wrong arguments!\n";
}
      #!/bin/bash

# Copyright (C) 2017  Gregor Bonney
#
# Version 2.0
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

LOGFILE=/var/log/fanspeed.log
ECFILE=/etc/fanspeed/probook_ec.pl
COUNTER=0

######################################################

initFan()
{
  setFan 80
#  sleep 2
  $ECFILE FANOFF
}

setFan()
{
  SPEED=$1
  $ECFILE := 0x2F $SPEED
}

getTempAvg()
{
  CUR=0
  CPUTEMP=0

  while [ $CUR -lt $INTERVAL ]
  do
    #TMP=$(sensors | grep Physical | cut -b 18-19)
    TMP=$(cat /sys/class/hwmon/hwmon*/device/temp1_input | cut -b1-2)
    #TMP=$(sensors | grep "Physical" | awk '{print $4}' | tr -d '+°C' | cut -b 1-2)
    ((CPUTEMP=$CPUTEMP+$TMP))
    ((CUR=$CUR+1))
    sleep 1
  done
  ((CPUTEMP=$CPUTEMP/$INTERVAL))
}

detectNewSpeed()
{
  ((COUNTER=$COUNTER+$INTERVAL))

  if [ $CPUTEMP -le $TEMPFANSTARTSPEED ]
  then
    # CPU COOLED DOWN
     ((INTERVAL=$STEPS))
    if [ $LASTSPEED -gt 75 ]
    then
      if [ $COUNTER -gt $THROTTLEOFF ]
      then
        # STOP FAN AFTER CPU COOLED DOWN
        NEWSPEEDF=FF
      fi
    elif [ "$NEWSPEEDF" == "FF" ]
    then
      NEWSPEEDF=FF
    else
      ((NEWSPEEDF=$NEWSPEEDF+$INTERVAL))
    fi
  elif [ $CPUTEMP -gt $TEMPFANMAXSPEED ]
  then
    # CPU VERY HOT!!!
    NEWSPEEDF=0
    resetCounter
    ((INTERVAL=10))
  else
    # CPU TEMP IS BETWEEN START AND MAX SPEED
    if [ $CPUTEMP -le $LASTTEMP ]
    then
      if [ $COUNTER -gt $THROTTLESEC ]
      then
        #calculate fanspeed after $THROTTLESEC seconds
        calculateFanSpeed
        resetCounter
      fi
    else
      # CPU TEMP RAISED -> CALCULATE AGILITY
      calculateFanSpeed
      calculateNextInterval
      resetCounter
    fi
  fi

  echo $TEMPFANSTARTSPEED:$CPUTEMP:$TEMPFANMAXSPEED:$NEWSPEEDF:$NEXTINT:$INTERVAL:$THROTTLESEC:$COUNTER
  #printf "TMIN:%d TCUR:%d TMAX:%d FSPEED:%s SLEEP:%d CNT:%d\n" $TEMPFANSTARTSPEED $CPUTEMP $TEMPFANMAXSPEED $NEWSPEEDF $INTERVAL $COUNTER

  if [ "$LASTSPEED" != "$NEWSPEEDF" ]
  then
    setFan $NEWSPEEDF
  fi

  ((LASTTEMP=$CPUTEMP))
  ((LASTSPEED=$NEWSPEEDF))
}

calculateFanSpeed() {
  ((LASTSPEED=$NEWSPEEDF))
  ((NEWSPEEDF=($CPUTEMP-$TEMPFANMAXSPEED)*($CPUTEMP+$TEMPFANMAXSPEED)))
  ((NEWSPEEDF=$NEWSPEEDF*-24/1000))
  #if [ "$LASTSPEED" != "FF" ]; then
  #  ((TST=$LASTSPEED+$INTERVAL))
  #  if [ $TST -le $NEWSPEEDF ]
  #  then
  #    ((NEWSPEEDF=$LASTSPEED+$INTERVAL))
  #  fi
  #fi
}

resetCounter() {
  ((COUNTER=0))
}

calculateNextInterval() {
  #calculate next interval
  NEXTINT=0
  for i in `seq 0 $STEPS`;
  do
    if [ $NEXTINT -le $CPUTEMP ]
      then
      ((NEXTINT=($TEMPFANSTARTSPEED+(($TEMPFANMAXSPEED-$TEMPFANSTARTSPEED)*$i/$STEPS))))
      ((INTERVAL=1+$STEPS-$i))
    fi
  done
}

##################################################


sleep 10

initFan

#use the average temperature of $INTERVAL seconds
INTERVAL=5
#throttle down after $THROTTLESEC seconds
THROTTLESEC=30
#set fan off after on lowest setting for $THROTTLEOFF seconds
THROTTLEOFF=80
#temperatures in celsius
TEMPFANSTARTSPEED=52 #56
TEMPFANMAXSPEED=80

STEPS=8


NEWSPEEDF=74
LASTTEMP=55
LASTSPEED=75

while [ true ]
do
  getTempAvg
  detectNewSpeed
done

То, что я изменил в «fanslow.sh», было как минимум:

  • Измененный ECFILE=/etc/fanspeed/probook_ec.plсоответствовать моему пути.
  • Добавлен TMP=$(sensors | grep "Package id 0:" | awk '{print $4}' | tr -d '+°C' | cut -b 1-2)после #TMP=$(sensors | grep "Physical" | awk '{print $4}' | tr -d '+°C' | cut -b 1-2)и закомментировал (добавил "#" в начале строки) значение по умолчанию TMP=$(cat /sys/class/hwmon/hwmon*/device/temp1_input | cut -b1-2).
  • Изменено значение в TEMPFANSTARTSPEED=52 #56в конце скрипта.
  • Изменено значение в TEMPFANMAXSPEED=80в конце скрипта.

Есть еще один скрипт, который я не использовал, я думаю, но, возможно, он окажется кому-то полезным:

      #! /bin/sh
#
# Copyright (C) 2017  Gregor Bonney
#
# Version 2.0
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

case "$1" in
start)
echo "Starting " $0

cd /etc/fanspeed/
./fanslow.sh >> /var/log/fanspeed &>> /dev/null &

;;
stop)
echo "Stopping " $0
killall fanslow.sh
/etc/fanspeed/probook_ec.pl FANRST
#
# Do something to stop the target platform here
#
;;
restart)
echo "Restarting " $0
$0 stop
$0 start
;;
status)
echo  "Status Not Implemented"
#
# Do something to process status checks here.
#
;;
*)
echo "Usage: /etc/init.d/$0 {start|stop}"
exit 1
;;
esac
exit 0

Источник : https://ubuntuforums.org/showthread.php?t=2008756&amp;amp;s=43a5ddf387823582cf47e3b25dbab100&amp;amp;p=12422983#post12422983 , https://ubuntuforums.org/showthread.php?t=2008756&amp;amp;page=24&amp;amp;p=134413447#

Другие вопросы по тегам