Скрипт, показывающий основные параметры системы, влияющие на энергопотребление

#! /bin/bash
#-------------------------------------------------
# Скрипт отображения состояния системных параметров,
# влияющих на энергопотребление
# v0.01 - начальная версия, отображающая состояние
# v0.1 - текущая версия. Добавлен выбор пользователя
# и показана команда для изменения состояния
# выбранного параметра
# v0.11 - Небольшие изменения для совместимости с 10.04
#
#
# В планах:
# * Вычислять среднее потребление энергии за прошедший период
# * Изменять состояние по выбору пользователя
# * Вычислять эффект по сохранению энергии от изменения
#-------------------------------------------------
# Функция вывода на экран строки
# $1 - h(eader), d(escripion), v(alue), c(ommand), o(out command)
# В зависимости от параметра назначаются цвет фона и шрифта
# $2 - Y
# $3 - X
# $4 - string
# $5 - len string - Длина строки для стирания мусора под выводом
PutStr()
{
DUMMY_STR=" "
case "$1" in
c)
FN_COLOR=4 ;;
h)
BG_COLOR=1 ; FN_COLOR=7 ;;
d)
BG_COLOR=7 ; FN_COLOR=1 ;;
o)
BG_COLOR=3 ; FN_COLOR=0 ;;
v)
BG_COLOR=7 ; FN_COLOR=0 ;;
esac
tput setb $BG_COLOR ; tput setf $FN_COLOR
if [ "$5" ]
then
EMPTY_SRT=${DUMMY_STR:1:$5}
tput cup $2 $3
echo -n "$EMPTY_SRT"
fi
tput cup $2 $3
echo -n "$4"
tput setb 7 ; tput setf 0
}
#-------------------------------------------------
# Выводит на экран строку с командой управления питанием
# для конкретного устройства
# В следующей версии будет ее исполнять
Command()
{
PutStr "o" 21 2 "$1" 76
}
#-------------------------------------------------
# Выводит на экран описаниие команды
Description()
{
if [ "$2" ]
then
PutStr "d" 19 2 "$1" 50
PutStr "d" 20 2 "$2" 50
else
PutStr "d" 19 2 " " 50
PutStr "d" 20 2 "$1" 50
fi
}
#-------------------------------------------------
# Выводит на экран промпт
Prompt()
{
PutStr "v" 18 2 "Command (A,B,C,D,E,F,G,I,K,L,M,P,R,S,T,U,W or Q):"
}
#-------------------------------------------------
# Выаодит на экран статические заголовки и сообщения
Put_Head()
{
PutStr "h" 0 0 "_________CPU1__CPU2__"
PutStr "d" 1 0 "Governor"
PutStr "c" 1 0 "G"
PutStr "d" 2 0 "Throttl"
PutStr "c" 2 0 "T"
PutStr "d" 3 0 "Tune Multi-Core:"
PutStr "c" 3 11 "C"
PutStr "h" 5 0 "SCSI0_____SCSI1_____SCSI2_____SCSI3__"
PutStr "h" 0 26 "USB1___USB2___USB3___USB4___USB5___USB6___USB7___USB8"
PutStr "d" 2 26 "Autosuspend:"
PutStr "c" 2 26 "A"
PutStr "h" 8 0 "Tuning VM_______________"
PutStr "d" 9 0 "Swappiness:"
PutStr "c" 9 0 "S"
PutStr "d" 10 0 "Dirty Writeback:"
PutStr "c" 10 6 "W"
PutStr "d" 11 0 "Dirty Expire:"
PutStr "c" 11 6 "E"
PutStr "d" 12 0 "Dirty Background:"
PutStr "c" 12 6 "B"
PutStr "d" 13 0 "Dirty Ratio:"
PutStr "c" 13 6 "R"
PutStr "h" 8 30 "Misk_______________"
PutStr "d" 9 30 "Fan speed:"
PutStr "c" 9 30 "F"
PutStr "d" 10 30 "CPU Temp:"
PutStr "d" 11 30 "Brightness:"
PutStr "d" 12 30 "WiFi Power:"
PutStr "c" 12 35 "P"
PutStr "d" 13 30 "Intel HDA:"
PutStr "c" 13 30 "I"
PutStr "d" 14 30 "Laptop mode:"
PutStr "c" 14 30 "L"
PutStr "h" 3 53 "HDD" 26
PutStr "d" 4 53 "hdparm -M:"
PutStr "c" 4 61 "M"
PutStr "d" 5 53 "STate:"
PutStr "c" 5 54 "T"
PutStr "h" 8 53 "Ethernet" 26
PutStr "d" 9 53 "SpeeD:"
PutStr "c" 9 57 "D"
PutStr "d" 10 53 "WaKe-on:"
PutStr "c" 10 55 "K"
PutStr "h" 12 53 "Battery" 26
PutStr "d" 13 53 "Capacity:"
PutStr "d" 14 53 "Remain:"
PutStr "d" 15 53 "State:"
PutStr "d" 16 53 "Rate:"
PutStr "d" 23 2 "Start time:"
PutStr "v" 23 14 `eval date +%H:%M:%S`
PutStr "d" 23 24 "Current time:"
PutStr "d" 23 49 "(c) http://axa-ru.blogspot.com"
}
#-------------------------------------------------
# Считывет состояние переменных и выводит их на экран
Put_Value()
{
tput sc #запоминаем положение курсора
read CPU0GOV < "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
if [ $CPU0GOV = "powersave" ]
then
CPU0GOV="psave"
fi
CPU0GOV=${CPU0GOV:0:5}
read CPU1GOV < "/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor"
if [ $CPU1GOV = "powersave" ]
then
CPU1GOV="psave"
fi
CPU1GOV=${CPU1GOV:0:5}
CPU0TX=`eval cat "/proc/acpi/processor/CPU0/throttling" | grep "active state"`
CPU0TX=${CPU0TX:25:2}
CPU1TX=`eval cat "/proc/acpi/processor/CPU1/throttling" | grep "active state"`
CPU1TX=${CPU1TX:25:2}
PutStr "v" 1 9 "$CPU0GOV"
PutStr "v" 1 15 "$CPU1GOV"
PutStr "v" 2 9 "$CPU0TX"
PutStr "v" 2 15 "$CPU1TX"
read MULTI_CORE < "/sys/devices/system/cpu/sched_mc_power_savings"
PutStr "v" 3 18 "$MULTI_CORE"
read SCSI0 < "/sys/class/scsi_host/host0/link_power_management_policy"
read SCSI1 < "/sys/class/scsi_host/host1/link_power_management_policy"
read SCSI2 < "/sys/class/scsi_host/host2/link_power_management_policy"
read SCSI3 < "/sys/class/scsi_host/host3/link_power_management_policy"
SCSI0=${SCSI0:0:7}
SCSI1=${SCSI1:0:7}
SCSI2=${SCSI2:0:7}
SCSI3=${SCSI3:0:7}
PutStr "v" 6 0 "$SCSI0"
PutStr "v" 6 10 "$SCSI1"
PutStr "v" 6 20 "$SCSI2"
PutStr "v" 6 30 "$SCSI3"
read USB1 < "/sys/bus/usb/devices/usb1/power/level"
read USB2 < "/sys/bus/usb/devices/usb2/power/level"
read USB3 < "/sys/bus/usb/devices/usb3/power/level"
read USB4 < "/sys/bus/usb/devices/usb4/power/level"
read USB5 < "/sys/bus/usb/devices/usb5/power/level"
read USB6 < "/sys/bus/usb/devices/usb6/power/level"
read USB7 < "/sys/bus/usb/devices/usb7/power/level"
read USB8 < "/sys/bus/usb/devices/usb8/power/level"
PutStr "v" 1 26 "$USB1"
PutStr "v" 1 33 "$USB2"
PutStr "v" 1 40 "$USB3"
PutStr "v" 1 47 "$USB4"
PutStr "v" 1 54 "$USB5"
PutStr "v" 1 61 "$USB6"
PutStr "v" 1 68 "$USB7"
PutStr "v" 1 75 "$USB8"
read USB_AS < "/sys/module/usbcore/parameters/autosuspend"
PutStr "v" 2 40 "$USB_AS"
read SWAPINESS < "/proc/sys/vm/swappiness"
read DIRTY_WRB < "/proc/sys/vm/dirty_writeback_centisecs"
read DIRTY_EXP < "/proc/sys/vm/dirty_expire_centisecs"
read DIRTY_BKG < "/proc/sys/vm/dirty_background_ratio"
read DIRTY_RAT < "/proc/sys/vm/dirty_ratio"
PutStr "v" 9 18 "$SWAPINESS" 6
PutStr "v" 10 18 "$DIRTY_WRB" 6
PutStr "v" 11 18 "$DIRTY_EXP" 6
PutStr "v" 12 18 "$DIRTY_BKG" 6
PutStr "v" 13 18 "$DIRTY_RAT" 6
FAN=`eval grep "speed:" "/proc/acpi/ibm/fan"`
FAN=${FAN:8:4}
PutStr "v" 9 44 "$FAN" 4
read CPU_THERM < "/proc/acpi/ibm/thermal"
CPU_THERM=${CPU_THERM:14:2}
PutStr "v" 10 44 "$CPU_THERM"
BRIGTH=`eval grep "current" "/proc/acpi/video/VID/LCD0/brightness"`
BRIGTH=${BRIGTH:9:3}
PutStr "v" 11 44 "$BRIGTH" 3
# для Ubuntu < 10.04
# read WIFI < "/sys/bus/pci/drivers/iwlagn/0000:03:00.0/power_level"
# WIFI=${WIFI:29:1}
# для Ubuntu >= 10.04
read WIFI < "/sys/bus/pci/drivers/iwlagn/0000:03:00.0/tx_power"
PutStr "v" 12 44 "$WIFI" 3
read INTEL_HDA < "/sys/module/snd_hda_intel/parameters/power_save"
PutStr "v" 13 44 "$INTEL_HDA"
read LAPTOP_MODE < "/proc/sys/vm/laptop_mode"
PutStr "v" 14 44 "$LAPTOP_MODE"
HDD_ACCUST=`eval hdparm -M /dev/sda | grep "acoustic"`
HDD_ACCUST=${HDD_ACCUST:17:3}
PutStr "v" 4 65 "$HDD_ACCUST"
HDD_STATE=`eval hdparm -C /dev/sda | grep "state is:"`
HDD_STATE=${HDD_STATE:18:12}
PutStr "v" 5 65 "$HDD_STATE" 12
ETH_SPEED=`eval ethtool eth0 | grep "Speed:"`
ETH_SPEED=${ETH_SPEED:8:16}
PutStr "v" 9 63 "$ETH_SPEED" 16
# ethtool eth0 | grep "Wake-on:" > /tmp/tst.tmp
# read ETH_WOL < /tmp/tst.tmp
# read ETH_WOL < "/tmp/tst.tmp"
# ETH_WOL=${ETH_WOL:4:10}
# PutStr "v" 10 63 "$ETH_WOL" 16
BAT_FCAP=`eval cat "/proc/acpi/battery/BAT0/info" | grep "last full capacity:"`
BAT_FCAP=${BAT_FCAP:25:9}
PutStr "v" 13 63 "$BAT_FCAP"
BAT_RCAP=`eval cat "/proc/acpi/battery/BAT0/state" | grep "remaining capacity:"`
BAT_RCAP=${BAT_RCAP:25:9}
PutStr "v" 14 63 "$BAT_RCAP" 9
BAT_CHRG=`eval cat "/proc/acpi/battery/BAT0/state" | grep "charging"`
BAT_CHRG=${BAT_CHRG:25:12}
PutStr "v" 15 63 "$BAT_CHRG" 12
BAT_RATE=`eval cat "/proc/acpi/battery/BAT0/state" | grep "present rate:"`
BAT_RATE=${BAT_RATE:25:9}
PutStr "v" 16 63 "$BAT_RATE" 9
PutStr "v" 23 38 `eval date +%H:%M:%S` 8
tput rc #восстанавливаем положение курсора
}
#-------------------------------------------------
# Обработчики команд пользователя
#A, Autosuspend
CmdAutosusp()
{
Command "echo 1 >/sys/module/usbcore/parameters/autosuspend"
Description "Enable autosuspend for usb devices"
}
#B, Dirty Background
CmdDirtyBkg()
{
Command "echo 60 > /proc/sys/vm/dirty_background_ratio"
Description "Минимальный процент памяти, где позволено" "хранить старые данные вместо записи на диск"
}
#C, Tune Multi-Core
CmdMulticore()
{
Command "echo 1 > /sys/devices/system/cpu/sched_mc_power_savings"
Description "Управление многопоточностью процессора"
}
#D, Ethernet SpeeD
CmdEthspeed()
{
Command "ethtool -s eth0 autoneg off speed 100"
Description "Отключение гигабитного интерфейса"
}
#G, CPU Governor
CmdCPUGov()
{
Command "echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
Description "Управление частотой процессоров"
}
#E, Dirty Expire
CmdDirtyExp()
{
Command "echo 0 > /proc/sys/vm/dirty_expire_centisecs"
Description "Насколько старыми должны быть данные," "что бы ядро записало их на диск"
}
#F, Fan speed
CmdFan()
{
Command ""
Description "Скорость вентилятора охлаждения"
}
#I, Intel HDA powersave
CmdHDA()
{
Command "echo 10 > /sys/module/snd_hda_intel/parameters/power_save"
Description "Управление потреблением звуковой подсистемы"
}
#K, Ethernet WaKe-on
CmdEthwake()
{
Command "ethtool -s eth0 wol d"
Description "Disable WOL"
}
#L, Laptop mode
CmdLaptop()
{
Command "echo 5 > /proc/sys/vm/laptop_mode"
Description "Enable Laptop mode"
}
#M, HDD silent mode
CmdHddSilent()
{
Command "hdparm -M 128 /dev/sda"
Description "set acoustic management (128: quiet, 254: fast)"
}
#P, WiFi Power
CmdWifipower()
{
Command "echo 5 > /sys/bus/pci/drivers/iwlagn/0000:03:00.0/power_level"
Description "Управление мощностью WiFi"
}
#R, Dirty Ratio
CmdDirtyratio()
{
Command "echo 95 > /proc/sys/vm/dirty_ratio"
Description "Максимальный размер памяти в процентах, для хранения" "грязных данных до записи их на диск."
}
#S, Swapiness
CmdSwapiness()
{
Command "echo 10 > /proc/sys/vm/swappiness"
Description "процентах свободной памяти, при котором" "система сбрасывает память в swap"
}
#T, HDD Standby
CmdHddStandby()
{
Command "hdparm -y /dev/sda"
Description "put HDD in standby mode"
}
#U, Ethernet DUplex
CmdEthdupl()
{
Command " "
Description " "
}
#W, Dirty Writeback
CmdDirtywrback()
{
Command "echo 1500 > /proc/sys/vm/dirty_writeback_centisecs"
Description "Как часто ядро должно проверять есть ли измененные" "данные для записи на диск"
}
#-------------------------------------------------
# Чтение команд пользователя
Process()
{
read -n 1 _ANS
case ${_ANS} in
[A]) CmdAutosusp;;
[B]) CmdDirtyBkg;;
[C]) CmdMulticore;;
[D]) CmdEthspeed;;
[E]) CmdDirtyExp;;
[F]) CmdFan;;
[G]) CmdCPUGov;;
[I]) CmdHDA;;
[K]) CmdEthwake;;
[L]) CmdLaptop;;
[M]) CmdHddSilent;;
[P]) CmdWifipower;;
[R]) CmdDirtyratio;;
[S]) CmdSwapiness;;
[T]) CmdHddStandby;;
[U]) CmdEthdupl;;
[W]) CmdDirtywrback;;
[Q]) exit;;
esac
unset _ANS
}
#-------------------------------------------------
#
UpdateValue()
{
tput civis
Put_Value
tput cnorm
}
#-------------------------------------------------
# Обработчик прерываний по таймеру
TIMER_INTERRUPT=14
TIMELIMIT=5 # Сигнал от таймера через 5 сек.
# Ожидает $TIMELIMIT секунд, затем посылает sigalarm в скрипт.
TimerOn()
{
# sleep $TIMELIMIT && kill -s 14 $ &
# В Ubuntu 10.04 работает такая конструкция
sleep $TIMELIMIT && kill -s 14 $$ &
}
# Здесь обрабатываются прерывания по таймеру
Int14Vector()
{
UpdateValue
TimerOn
}
# Установка прерываний по таймеру
# Timer interrupt (14) subverted for our purposes.
trap Int14Vector $TIMER_INTERRUPT
TimerOn # Запускаем таймер
#-------------------------------------------------
# Главный цикл
# Usage: "sudo pchk.sh -b"
# ^
# Можно поставить любой-+
# параметр
tput clear
Put_Head
if [ -z $1 ]
then
Put_Value
else
while [ 1 ]
do
Prompt
Process
done
fi
exit 0