Skip to content

Instantly share code, notes, and snippets.

@tokland
Last active December 17, 2015 18:29
Show Gist options
  • Save tokland/5653079 to your computer and use it in GitHub Desktop.
Save tokland/5653079 to your computer and use it in GitHub Desktop.
Simple generic monitoring tool using a finite-state-machines implementation.
#!/bin/bash
#
# Simple monitoring using a finite state machines
set -e -u -o pipefail
# Print debug output to standard error
debug() {
echo "[${FUNCNAME[1]}] $@" >&2
}
# Say a phrase using the soundarc
say() {
debug "$@"
espeak "$@" 2>/dev/null
}
# Return percentage level of a the battery (BAT0) of laptop
get_battery_percentage() {
local CHARGE_NOW=$(</sys/class/power_supply/BAT0/charge_now)
local CHARGE_FULL=$(</sys/class/power_supply/BAT0/charge_full)
local PERCENTAGE0=$(($CHARGE_NOW * 100 / $CHARGE_FULL))
echo $(($PERCENTAGE0 > 100 ? 100 : $PERCENTAGE0))
}
### Services
# battery_status: Sound notifications of change of state for the BAT0 battery
battery_status_INITIAL_STATE="Full"
battery_status() {
local OLD_STATUS=$1
local STATUS=$(</sys/class/power_supply/BAT0/status)
debug "STATUS=$STATUS"
if test "$STATUS" != "$OLD_STATUS" &&
test "$STATUS" != "Full" -o "$OLD_STATUS" != "Charging"; then
say "$STATUS"
fi
echo $STATUS
}
# battery_status: Suspend the computer when the battery level is too low.
battery_level_INITIAL_STATE="0"
battery_level() {
local STATE=$1
local ABSOLUTE_MINIMUM=5
local THRESHOLD=50
local PERCENTAGE=$(get_battery_percentage)
local STATUS=$(</sys/class/power_supply/BAT0/status)
debug "PERCENTAGE=$PERCENTAGE"
if test $PERCENTAGE -lt $ABSOLUTE_MINIMUM ||
test "$STATUS" = "Discharging" -a $PERCENTAGE -lt $THRESHOLD; then
say "Battery at $PERCENTAGE%, suspending"
sudo pm-suspend
fi
echo $PERCENTAGE
}
### Monitoring infrastructure
monitor() {
local LOOP_WAIT=$1
shift
# Declare state variables (${FUN}_STATE)
for FUN in $*; do
debug "Init service: $FUN"
eval "local ${FUN}_STATE=\$${FUN}_INITIAL_STATE"
done
while true; do
for FUN in $*; do
local STATE_VAR="${FUN}_STATE"
local STATE=${!STATE_VAR}
local NEW_STATE=$($FUN "$STATE")
eval "${STATE_VAR}=\$NEW_STATE"
sleep $LOOP_WAIT
done
done
}
### Main
monitor 1 "battery_status" "battery_level"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment