#!/bin/bash # # Author: $Author: smurphy $ # Locked by: $Locker: $ # # Programm Version VER="$Revision: 1.17 $" # # Original author: Joerg Mertin <smurphy(-AT-)solsys.org> # Enhancements by Wizardry and Steamworks <office(-AT-)grimore.org> ########################################################################### ## Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 ## ########################################################################### function getCoreTemperatureFile { for i in /sys/devices/platform/coretemp.*/hwmon/hwmon*/*_label; do IFS=' ' read -ra CORE <<< `cat $i` if [ "${CORE[0]}" == "Core" ] && [ "${CORE[1]}" == $1 ]; then echo "${i//label/input}" fi done } # Get Program-Name, shortened Version. PROGNAME="`basename $0 .sh`" LockFile=/var/run/${PROGNAME}..LOCK LOGGER=/usr/bin/logger # Make sure that logger is not used if not found if [ ! -x $LOGGER ] then DOLOGGER=false || : echo "WARNING: $LOGGER program not found - syslog writing disabled" else DOLOGGER=true fi VERBOSE=true POLL_TIME=10 # Poll interval, e.g. checking temperatures DAEMON=false SYSLOG=false # User configurable part - files we find required informations CPU_CORE0=$(getCoreTemperatureFile 0) CPU_CORE1=$(getCoreTemperatureFile 1) #FAN_SPEED=/sys/devices/platform/applesmc.768/fan1_input FAN_SPEED=/sys/devices/platform/applesmc.768/fan1_min FAN_SET=/sys/devices/platform/applesmc.768/fan1_output FAN_MAN=/sys/devices/platform/applesmc.768/fan1_manual # Some very conservative FAN speed settings MIN_SPEED="`cat /sys/devices/platform/applesmc.768/fan1_min`" #MIN_SPEED=2000 # If you want to override - here's your chance. MAX_SPEED="`cat /sys/devices/platform/applesmc.768/fan1_max`" # MAX_SPEED=6000 # If you want to override - here's your chance. FAN_CHANGE=500 # Temperaturs MAX_TEMP=80000 HIGH_TEMP=55000 LOW_TEMP=45000 ############################################################################### # Nothing to change below this point ! ############################################################################### ############################################################################## # Errors function errors() { #DOC: The errors Function is called to control the exit status. # : ${errlvl:=9} : ${MSG:="No Error message - Probably user interruption"} if [ $errlvl -gt 0 ] ; then if [ $errlvl = 15 ] ; then $VERBOSE && echo -e "WARNING: $MSG" log "WARNING: $MSG" else #Usage echo -e "\a" echo "FATAL: An error occured in \"${PROGNAME}(${FUNCTION})\". Bailing out..." echo -e "ERRMSG: $MSG" echo fan_auto_operation auto log "FATAL: $MSG" Unlock $FLock exit $errlvl fi fi } # errors Function # # ############################################################################## # Create Lockfile - prevent double start of app Lock() { # Lockfile to create tolock="$1" Action="$2" # # Lock file if lockfile does not exist. if [ -s $tolock ] then # If we have provided a second Var, set Exit status using it. if [ ! -n "$Action" ] then # Oops, we found a lockfile. Loop while checking if still exists. while [ -s $tolock ] do sleep 5 ; done MSG="Creating lockfile $tolock failed after 5 secs" # write PID into Lock-File. if [ "$DAEMON" == "true" ] then echo $! > $tolock errlvl=$? errors else echo $$ > $tolock errlvl=$? errors fi else Pid="`cat $tolock`" Exists="`ps auxw | grep \" $Pid \" | grep -c $PROGNAME`" if [ $Exists = 1 ] then MSG="\"$PROGNAME\" already running. Exiting..." errlvl=$Action errors else MSG="Found stale lockfile... Removing it..." rm -f $tolock errlvl=$? errors MSG="Creating lockfile $tolock failed" # write PID into Lock-File. if [ "$DAEMON" == "true" ] then echo $! > $tolock errlvl=$? errors else echo $$ > $tolock errlvl=$? errors fi fi fi else # write PID into Lock-File. MSG="Creating lockfile $tolock failed" if [ "$DAEMON" == "true" ] then echo $! > $tolock errlvl=$? errors else echo $$ > $tolock errlvl=$? errors fi fi } # Lock # ############################################################################## # Unlock lockfile Unlock(){ # Name of Lockfile to unlock unlock="$1" # Unlock the file. if [ -s $unlock ] then if [ -n "$DPID" ] then PID=$DPID else PID=$$ fi if [ "`cat $unlock`" -ne "$PID" ] then # Lock it echo -e "WARNING: Wrong lock-file PID. Probably a race-condition happened...\n" else # Removing Lockfile rm -f $unlock fi fi # } # Unlock # ############################################################################### # Usage function - very small - just givs out some help. usage() { echo " Program: ${PROGNAME}.sh version $VER RCS$Id: applesmc.sh,v 1.17 2007/10/09 14:01:03 smurphy Exp $ (c) J. Mertin <smurphy@solsys.org> Usage: $0 [OPTION]... Available options: -s Status - just displays actual status informations -q Quiet mode -v Verbose mode -d Daemon mode, go into background (implies -q) -k Stop daemon -l Log to syslog " exit 1; } # usage end. # ############################################################################### # Log function - very small log() { # Be verbose ! $VERBOSE || echo "> $PROGNAME $*" # no logger found, no syslog capabilities if [ $DOLOGGER ] then ! $SYSLOG || $LOGGER -t "$PROGNAME" "$*" fi } ############################################################################### # Get's CPU Temperature. In dual-core env - returns max temp detected get_temp() { TEMP0=`cat $CPU_CORE0` TEMP1=`cat $CPU_CORE1` # Check max TEMP if [ $TEMP0 -gt $TEMP1 ] then TEMP=$TEMP0 else TEMP=$TEMP1 fi let DTEMP=($TEMP / 1000) } # get_temp ############################################################################### # Get's the FAN Status fan_status() { FSPEED=`cat $FAN_SPEED` let CHECK_SPEED=( $MIN_SPEED + $FAN_CHANGE ) if [ $FSPEED -gt $CHECK_SPEED ] then while [ $FSPEED -lt $CHECK_SPEED ] do if [ $CHECK_SPEED -ge $MAX_SPEED ] then FSPEED=$MAX_SPEED return fi let CHECK_SPEED=( $CHECK_SPEED + $FAN_CHANGE ) done FSPEED=$CHECK_SPEED else FSPEED=$MIN_SPEED fi let SPEED_UP="( $FSPEED + $FAN_CHANGE )" let SPEED_DOWN="( $FSPEED - $FAN_CHANGE )" } # fan_status ############################################################################### # Sets the FAN Manual=1/Automatic=0 operation # It will only be used in Daemon mode ! fan_auto_operation() { if [ "$*" == "auto" ] then log "Mode: auto - CPU ${DTEMP}C, FAN @ ${FSPEED}RPM" echo 0 > $FAN_MAN else log "Mode: manual - CPU ${DTEMP}C, FAN @ ${FSPEED}RPM" echo 1 > $FAN_MAN fi # Enter a little info the Logger } # fan_auto_operation ############################################################################### # Get's CPU Temperature. In dual-core env - returns max temp detected do_status() { get_temp fan_status SPEED=`cat $FAN_SPEED` echo "Status: MAX Core Temp: ${DTEMP}C, FAN @ $SPEED / set ${FSPEED}RPM" } # get_status ############################################################################### # Get's CPU Temperature. In dual-core env - returns max temp detected kill_daemon() { if [ -f "$LockFile" ] then set -e MSG="Extracting PID file of previous process" DPID="`cat \"$LockFile\"`" errlvl=$? errors MSG="Killing PID $DPID failed" kill "$DPID" errlvl=$? errors log "Killed process $DPID" # Set fan operaion mode to auto fan_auto_operation auto # We need to remove lock file Unlock $LockFile else log "No lockfile found. Bailing out" fi } # kill_daemon ############################################################################### # Main loop - the actuall working loop. do_main() { # Enable the fan in default mode if anything goes wrong: set -e -E -u trap "errors; exit 2" HUP INT ABRT QUIT SEGV TERM trap "errors" EXIT trap "log 'Got SIGUSR1'; fan_auto_operation auto; " USR1 # Get the actual Temp and Fan speed get_temp fan_status if [ "$DAEMON" == "true" ] then fan_auto_operation manual else fan_auto_operation auto fi while :; do # Get the actual Temp and Fan speed get_temp fan_status # Special case - if we have reached our set max temp - max FAN Speed ! if [ $TEMP -gt $MAX_TEMP ] then if [ $MAX_SPEED -ne $FSPEED ] then echo $MAX_SPEED > $FAN_SET log "CPU ${DTEMP}C, FAN @ ${FSPEED}RPM > ${MAX_SPEED}RPM" fi elif [ $TEMP -gt $HIGH_TEMP ] then if [ $SPEED_UP -lt $MAX_SPEED ] then if [ $SPEED_UP -gt $FSPEED ] then echo $SPEED_UP > $FAN_SET log "CPU ${DTEMP}C, FAN @ ${FSPEED}RPM > ${SPEED_UP}RPM" fi fi elif [ $TEMP -lt $LOW_TEMP ] then if [ $SPEED_DOWN -gt $MIN_SPEED ] then if [ $SPEED_DOWN -ne $FSPEED ] then echo $SPEED_DOWN > $FAN_SET log "CPU ${DTEMP}C, FAN @ ${FSPEED}RPM > ${SPEED_DOWN}RPM" fi fi else if [ $MIN_SPEED -ne $FSPEED ] then echo $MIN_SPEED > $FAN_SET log "CPU ${DTEMP}C, FAN @ ${FSPEED}RPM > ${MIN_SPEED}RPM" fi fi if [ "$DAEMON" == "true" ] then sleep $POLL_TIME else return fi done } # do_main # ############################################################################### # Parse arguments while getopts 'sqdlhkv' OPT; do case "$OPT" in s) # test mode DAEMON=false VERBOSE=true SYSLOG=false do_status exit 0 ;; d) # go into background and daemonize DAEMON=true VERBOSE=false SYSLOG=true ;; q) # quiet mode VERBOSE=false SYSLOG=true ;; k) # Kill daemon DAEMON=false VERBOSE=true SYSLOG=true log "Daemon shutdown requested" get_temp fan_status kill_daemon exit 0 ;; l) # log to syslog SYSLOG=true ;; v) # log to syslog VERBOSE=true ;; h) # short help usage exit 0 ;; \?) # error usage exit 0 ;; esac done [ $OPTIND -gt $# ] || usage # no non-option args # That's the main loop. if [ "$DAEMON" == "true" ] then # We want to run as daemon - detach all from the console log "Version${VER} initialisation succeeded" Lock $LockFile 1 do_main 0<&- 1>&- 2>&- & # Lock this process. DPID=$! echo $DPID > $LockFile else # Lock this process. Lock $LockFile 1 # Normal run. do_main # Unlock the program. Unlock $LockFile fi exit 0