Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # write PID to pidfile, ensure deletion
- echo $$ >"${1}"
- trap "rm \"${1}\" ; exit 0" 0 1 2 3 15
- # set -x
- # exec 2>>/var/log/sunxi-temp.log
- #
- # A20/AXP209 SoC/HDD/PMU temperature daemon. Writes the current temperatures
- # to /tmp/soctemp, /tmp/pmutemp and /tmp/disktemp (since we're experiencing
- # always timeouts under heavy load when trying to get the temperatures
- # directly from within RPi-Monitor. All temperature values in °C were written
- # to the temp files multiplied with 10 to get 1 decimal place in RPi-Monitor.
- #
- # Please keep in mind that the values you get this way may be inaccurate (that
- # applies especially to the SoC's temperature)
- #
- # Copyright 2015 - Thomas Kaiser - http://kaiser-edv.de/
- #
- # 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, see <http://www.gnu.org/licenses/>.
- SoCTempAdjustment=1447 # default for A20
- CheckInterval=7.5 # time in seconds between two checks
- DiskCheckInterval=60 # time in seconds between disk checks
- CheckAllDisks=FALSE # if set to anything else than FALSE you've to adjust
- # your data collection settings: both name and regexp. And
- # display/graph settings should also match the count of
- # disks since the values for all found disks will be written
- # space delimited to the temp file. With 4 disks you might
- # use
- #
- # dynamic.12.name=hddtemp1,hddtemp2,hddtemp3,hddtemp4
- # dynamic.12.source=/tmp/disktemp
- # dynamic.12.regexp=^(\S+)\s(\S+)\s(\S+)\s(\S+)
- #
- # And please keep in mind that disk enumeration might not
- # be persistent across reboots so become familiar with
- # udev rules, access disks by UUID or use /dev/disk/by-id/
- # 'blkid' and 'udevadm info --query=property --name=/dev/sda'
- # are your friends and help you to get the idea.
- CpuStatCheckInterval=20 # define in which interval CPU statistics should be queried
- FanCheckInterval=120 # if this variable is set then every ${FanCheckInterval} secs
- # the PMU's temperature will be checked (deg celsius * 1000).
- FanTempError=55000 # If it exceeds ${FanTempError} then the fan will switch on.
- FanTempWarn=53000 # Same when exceeding ${FanTempWarn} while CPU utilisation is
- # above 60%
- FanGPIO=7 # Define the GPIO pin that will trigger fan operation
- TempCheckInterval=180 # In case you want to query external weather stations via HTTP
- # define an interval here and adjust the GetExternalTemp function
- # initialize variables we need later
- export PATH=/usr/local/bin:/usr/bin:/bin:
- unset LANG
- LastDiskCheck=0
- LastFanCheck=0
- LastTempCheck=0
- LastUserStat=0
- LastNiceStat=0
- LastSystemStat=0
- LastIdleStat=0
- LastIOWaitStat=0
- LastIrqStat=0
- LastSoftIrqStat=0
- LastCpuStatCheck=0
- Main() {
- # Ensure that we're running as root since otherwise querying SATA/USB disks won't work
- if [ "$(id -u)" != "0" ]; then
- echo "This script must be run as root" >&2
- exit 1
- fi
- # ensure we're writing to files instead of symlinks
- CreateTempDir
- # check whether we've to control a fan
- if [ "X${FanCheckInterval}" != "X" ]; then
- # initialise GPIO pin to be ready to trigger the fan
- echo ${FanGPIO} >/sys/class/gpio/export
- echo "out" >/sys/class/gpio/gpio${FanGPIO}/direction
- fi
- while true ; do
- # enclosures's internal temperature/humidity
- # somewhat inaccurate since we dropped a pullup resistor and sometimes the values
- # are out of range. We fix this with range checks
- EncTemp=$(tail -n 40 /var/log/enclosure.log | grep "^Humidity" | tail -n3 | awk -F" " '{ total += $7*100; count++ } END { print total/count }' | cut -f1 -d.)
- EncHumidity=$(tail -n 40 /var/log/enclosure.log | grep "^Humidity" | tail -n3 | awk -F" " '{ total += $3*100; count++ } END { print total/count }' | cut -f1 -d.)
- if [ ${LastFanCheck} -eq 0 ]; then
- # first run -- we trust the values
- LastEncTemp=${EncTemp}
- echo ${EncTemp} >/tmp/enctemp
- LastEncHumidity=${EncHumidity}
- echo ${EncHumidity} >/tmp/enchumid
- else
- if [ ${EncTemp} -lt $(( ${LastEncTemp} - 4000 )) -o ${EncTemp} -gt $(( ${LastEncTemp} + 4000 )) ]; then
- echo ${LastEncTemp} >/tmp/enctemp
- else
- LastEncTemp=$(SanitizeValue ${EncTemp} ${LastEncTemp} | tee /tmp/enctemp)
- fi
- if [ ${EncHumidity} -lt $(( ${LastEncHumidity} - 4000 )) -o ${EncHumidity} -gt $(( ${LastEncHumidity} + 4000 )) ]; then
- echo ${LastEncHumidity} >/tmp/enchumid
- else
- LastEncHumidity=$(SanitizeValue ${EncHumidity} ${LastEncHumidity} | tee /tmp/enchumid)
- fi
- fi
- # check disk temperature(s). We execute this only every ${DiskCheckInterval} since
- # it's a bit costly (S.M.A.R.T. queries).
- TimeNow=$(( $(date "+%s") / ${DiskCheckInterval} ))
- if [[ ${TimeNow} -gt ${LastDiskCheck} ]]; then
- # time for a disk check. If ${CheckAllDisks} is FALSE and /dev/sda exists we
- # only query this device otherwise all available (might be none)
- CheckDisks
- # update check timestamp
- LastDiskCheck=${TimeNow}
- fi
- # External temperature from weather stations
- TimeNow=$(( $(date "+%s") / ${TempCheckInterval} ))
- if [[ ${TimeNow} -gt ${LastTempCheck} ]]; then
- # read in external temp values from 2 different web sources
- ExternalTemp=$(GetExternalTemp)
- LastExternalTemp=$(SanitizeValue ${ExternalTemp} ${LastExternalTemp} | tee /tmp/externaltemp)
- LastTempCheck=${TimeNow}
- fi
- # cpustat
- TimeNow=$(( $(date "+%s") / ${CpuStatCheckInterval} ))
- if [[ ${TimeNow} -gt ${LastCpuStatCheck} ]]; then
- ProcessStats
- LastCpuStatCheck=${TimeNow}
- fi
- # Soc and PMU temp -- depends on the kernel we're running
- case $(uname -r) in
- 3.4.*)
- if [ -x /usr/share/rpimonitor/scripts/sunxi_tp_temp ]; then
- SoCTemp=$(/usr/share/rpimonitor/scripts/sunxi_tp_temp ${SoCTempAdjustment} | awk '{printf ("%0.0f",$1*1000); }')
- fi
- read PMUTemp </sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input
- ;;
- 4.*)
- # mainline kernel 4.0 or above, SoC temp should be available
- read SoCTemp </sys/class/thermal/thermal_zone0/temp
- esac
- # check whether PMU value could be read before
- if [ "X${PMUTemp}" = "X" ]; then
- # Maybe the patches from http://sunxi.montjoie.ovh are applied and lm-sensors installed
- PMUTemp=$(sensors | awk -F" " '/CHIP: / {printf ("%0.0f",$2*1000); }')
- fi
- LastSocTemp=$(SanitizeValue ${SoCTemp} ${LastSocTemp} | tee /tmp/soctemp)
- LastPMUTemp=$(SanitizeValue ${PMUTemp} ${LastPMUTemp} | tee /tmp/pmutemp)
- # fan check
- TimeNow=$(( $(date "+%s") / ${FanCheckInterval} ))
- # Load1Min=$(awk -F" " '{print $1}' < /proc/loadavg | cut -d. -f1)
- # Load5Min=$(awk -F" " '{print $2}' < /proc/loadavg | cut -d. -f1)
- CPUTotal=$(cut -d" " -f1 </tmp/cpustat)
- TheMinute="$(date "+%M")"
- case ${TheMinute} in
- 59|00|01)
- TempTreshold=${FanTempWarn}
- ;;
- *)
- TempTreshold=${FanTempError}
- ;;
- esac
- if [[ ${TimeNow} -gt ${LastFanCheck} ]]; then
- if [ ${LastPMUTemp} -ge ${TempTreshold} ]; then
- echo 1 >/sys/class/gpio/gpio${FanGPIO}/value
- elif [ ${LastPMUTemp} -ge ${FanTempWarn} -a ${CPUTotal} -ge 60 ]; then
- echo 1 >/sys/class/gpio/gpio${FanGPIO}/value
- else
- echo 0 >/sys/class/gpio/gpio${FanGPIO}/value
- fi
- LastFanCheck=${TimeNow}
- fi
- sleep ${CheckInterval}
- done
- } # Main
- CreateTempDir() {
- # create a safe temporary dir with the three files therein and symlinks to /tmp/
- MyTempDir=$(mktemp -d /tmp/rpimonitor.XXXXXX)
- if [ ! -d "${MyTempDir}" ]; then
- MyTempDir=/tmp/rpimonitor.$RANDOM.$RANDOM.$RANDOM.$$
- (umask 077 && mkdir ${MyTempDir}) || (echo "Failed to create temp dir. Aborting" >&2 ; exit 1)
- fi
- for file in cpustat externaltemp enchumid enctemp ambienttemp soctemp disktemp pmutemp camera1temp camera2temp camera3temp camera4temp camera5temp ; do
- echo -n "0" > "${MyTempDir}/${file}"
- chmod 644 "${MyTempDir}/${file}"
- ln -f -s ${MyTempDir}/${file} /tmp/${file}
- done
- chmod 711 "${MyTempDir}"
- } #CreateTempFiles
- CheckDisks() {
- # We check either /dev/sda or all available block devices -- see above for
- # contents/consequences of $CheckAllDisks
- if [ "X${CheckAllDisks}" = "XFALSE" -a -L /sys/block/sda ]; then
- DiskTemp=$(GetDiskTemp /dev/sda)
- LastDiskTemp=$(SanitizeValue ${DiskTemp} ${LastDiskTemp} | tee /tmp/disktemp)
- else
- DiskTemp=""
- for diskdevice in /sys/block/sd* ; do
- RawDiskTemp=$(GetDiskTemp /dev/${diskdevice##*/})
- DiskTemp="${DiskTemp}$(SanitizeValue ${RawDiskTemp}) "
- done
- if [ "X${DiskTemp}" = "X " ]; then
- echo -n "0" >/tmp/disktemp
- else
- echo "${DiskTemp}" >/tmp/disktemp
- fi
- fi
- } # CheckDisks
- GetDiskTemp() {
- # get disk temperate using hddtemp (doesn't wake up sleeping disks and knows how to deal
- # with different disks due to an included database with known disk models).
- RawTemp=$(/usr/sbin/hddtemp -n ${1} 2>/dev/null)
- if [ "X${RawTemp}" = "X" ]; then
- # drive is sleeping, we take the enclosure's internal temp + 4°C
- read RawTemp </tmp/enctemp
- echo ${RawTemp} | awk '{printf ("%0.0f",$1+4000); }'
- else
- echo ${RawTemp} | awk '{printf ("%0.0f",$1*1000); }'
- fi
- # The commented smartctl call below is meant as an alternative and an example for USB
- # disks in external enclosures that are able to answer S.M.A.R.T. queries since they're
- # SAT capable:
- #
- # /usr/sbin/smartctl -d sat -a ${1} | awk -F" " '/Temperature_Cel/ {printf ("%0.0f",$10*10); }'
- #
- # You should be aware that not every enclosure supports that and that some USB-to-SATA
- # bridges require different parameters (eg. '-d usbjmicron' -- have a close look at
- # https://www.smartmontools.org/wiki/Supported_USB-Devices and test with smartctl to
- # get the correct value of the correct attribute).
- #
- # You should also be aware that a query by smartctl always wakes up sleeping disks. So
- # in case you want to query an external USB disk only if it's neither standby nor sleeping
- # and in case the enclosure is SAT capable think about prefixing the smartctl call with
- # something like:
- #
- # /sbin/hdparm -C ${1} | egrep -q "standby|sleeping" || /usr/sbin/smartctl ...
- #
- # In case you try to query multiple disks you might end up with something like
- #
- # case ${1} in
- # /dev/sda) /usr/sbin/hddtemp -n ${1} ... ;;
- # /dev/sdb) /usr/sbin/smartctl -d usbprolific -a ${1} ... ;;
- # /dev/sdc) /sbin/hdparm -C ${1} | egrep -q "standby|sleeping" || /usr/sbin/smartctl -d sat ... ;;
- # esac
- } # GetDiskTemp
- SanitizeValue() {
- # keep thermal values in the range of 0°C-100°C since sometimes the values are massively out
- # of range and then your graphs suffer from this. If a second argument is supplied then create
- # an average value to smooth graphs (useful for PMU and SoC)
- if [[ ${1} -lt 0 ]]; then
- echo -n 0
- elif [[ ${1} -ge 100000 ]]; then
- echo -n ${1}
- else
- if [[ "X$2" = "X" ]]; then
- echo -n ${1}
- else
- echo -n $(( ( $1 + $2 * 5 ) / 6 ))
- fi
- fi
- } # SanitizeValue
- SanitizeValueFinegrade() {
- # keep thermal values in the range of 0°C-100°C since sometimes the values are massively out
- # of range and then your graphs suffer from this. If a second argument is supplied then create
- # an average value to smooth graphs (useful for enclosure's temperature and humidity -- they
- # are reported as integers and by processing them with one more decimal place we get smoother
- # graphs
- if [[ ${1} -lt 0 ]]; then
- echo -n 0
- elif [[ ${1} -gt 10000 ]]; then
- echo -n 10000
- else
- if [[ "X$2" = "X" ]]; then
- echo -n ${1}
- else
- echo -n $(( ( $1 + $2 * 15 ) / 16 ))
- fi
- fi
- } # SanitizeValueFinegrade
- ProcessStats() {
- set $(awk -F" " '/^cpu / {print $2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8}' </proc/stat)
- UserStat=$1
- NiceStat=$2
- SystemStat=$3
- IdleStat=$4
- IOWaitStat=$5
- IrqStat=$6
- SoftIrqStat=$7
- UserDiff=$(( ${UserStat} - ${LastUserStat} ))
- NiceDiff=$(( ${NiceStat} - ${LastNiceStat} ))
- SystemDiff=$(( ${SystemStat} - ${LastSystemStat} ))
- IdleDiff=$(( ${IdleStat} - ${LastIdleStat} ))
- IOWaitDiff=$(( ${IOWaitStat} - ${LastIOWaitStat} ))
- IrqDiff=$(( ${IrqStat} - ${LastIrqStat} ))
- SoftIrqDiff=$(( ${SoftIrqStat} - ${LastSoftIrqStat} ))
- Total=$(( ${UserDiff} + ${NiceDiff} + ${SystemDiff} + ${IdleDiff} + ${IOWaitDiff} + ${IrqDiff} + ${SoftIrqDiff} ))
- CPULoad=$(( ( ${Total} - ${IdleDiff} ) * 100 / ${Total} ))
- UserLoad=$(( ${UserDiff} *100 / ${Total} ))
- SystemLoad=$(( ${SystemDiff} *100 / ${Total} ))
- NiceLoad=$(( ${NiceDiff} *100 / ${Total} ))
- IOWaitLoad=$(( ${IOWaitDiff} *100 / ${Total} ))
- IrqCombinedLoad=$(( ( ${IrqDiff} + ${SoftIrqDiff} ) *100 / ${Total} ))
- echo "${CPULoad} ${SystemLoad} ${UserLoad} ${NiceLoad} ${IOWaitLoad} ${IrqCombinedLoad}" >/tmp/cpustat
- LastUserStat=${UserStat}
- LastNiceStat=${NiceStat}
- LastSystemStat=${SystemStat}
- LastIdleStat=${IdleStat}
- LastIOWaitStat=${IOWaitStat}
- LastIrqStat=${IrqStat}
- LastSoftIrqStat=${SoftIrqStat}
- } # ProcessStats
- GetExternalTemp() {
- # function that parses meteo.physik.uni-muenchen.de and mingaweda.de
- # temperature values for Munich and compares them. When values are out
- # of bounds then only the other value will be returned otherwise the average
- ExternalTemp1=$(/usr/bin/links -http.fake-user-agent 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.12' -dump "http://www.meteo.physik.uni-muenchen.de/dokuwiki/doku.php?id=wetter:stadt:messung" | awk -F" " '/Lufttemperatur/ {printf ("%0.0f",$4*1000); }')
- ExternalTemp2=$(/usr/bin/links -http.fake-user-agent 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.12' -dump "http://www.mingaweda.de/wetterdaten/" | awk -F" " '/Ausfu:hrliche/ {printf ("%0.0f",$2*1000); }')
- if [ "X${ExternalTemp2}" = "X" ]; then
- ExternalTemp2=${ExternalTemp1}
- elif [ "X${ExternalTemp1}" = "X" ]; then
- ExternalTemp1=${ExternalTemp2}
- fi
- echo $(( ( ${ExternalTemp1} + ${ExternalTemp2} ) / 2 ))
- } # GetExternalTemp
- Main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement