Skip to content

Instantly share code, notes, and snippets.

@iwillspeak
Last active December 17, 2015 11:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iwillspeak/5600085 to your computer and use it in GitHub Desktop.
Save iwillspeak/5600085 to your computer and use it in GitHub Desktop.
Automatic wifi router resetter control scripts. Install `thunker` into your `/usr/local/bin` on the RPi and `thunker_daemon` into your *init.d*. You will need Ruby and the `net-ping` and 'wiringpi' gems. See it in action at https://vimeo.com/66365606
#! /usr/bin/ruby
require 'wiringpi'
require 'net/ping'
require 'syslog'
# Constants
OUTPUT_PINA = 0 # RPi Pin 11
OUTPUT_PINB = 1 # RPi Pin 12
ARM_ON_TIME = 0.1
ARM_RESET_TIME = 0.05
ARM_PAUSE_TIME = 1
# Configs
@logfile_name = "/var/log/syslog"
@router_ip = '192.168.5.2'
# Globals
@resetting = false
# Singletons
@gpio = WiringPi::GPIO.new
@pinger = Net::Ping::ICMP.new
##
# Controls the 'organic rotory button actuator'
#
# This should never be calld with HIGH, HIGH or the battery will short out. Both
# pins should be connected to the inputs of a two output H bridge.
def write_bits(a, b)
if a == HIGH
raise "Can't have two high bits" if b == HIGH
# ensure we never have two high bits by always writing LOW first
@gpio.write OUTPUT_PINB, LOW
@gpio.write OUTPUT_PINA, HIGH
else
# Write out pin values
@gpio.write OUTPUT_PINA, LOW
@gpio.write OUTPUT_PINB, b
end
end
def motor_right
write_bits(HIGH, LOW)
end
def motor_left
write_bits(LOW, HIGH)
end
def motor_stop
write_bits(LOW, LOW)
end
##
# Log a message in the system log so we can keep track of the daemon's actions
def write_to_syslog msg
Syslog.open 'thunker', Syslog::LOG_PID, Syslog::LOG_DAEMON do |log|
log.log Syslog::LOG_NOTICE, "%s", msg
end
end
##
# Check the current status of the wireless network
def wireless_down?
# Try to ping the router, if we can't after five the wireless is down
5.times do
return false if @pinger.ping @router_ip
end
true
rescue
# When the network is unreachable there be errors...
true
end
##
# Does the router need a slap?
def reset_necessary?
down = wireless_down?
# We need to reset if the wireless is down but we aren't yet resetting
ret = down && !@resetting
# Log the network comming back up
write_to_syslog("Network back up") if !down && @resetting
# Store the state for next time
@resetting = down
ret
end
##
# Get the router back up and running
def reset_router
write_to_syslog("Outage detected.")
reset_arm
sleep ARM_PAUSE_TIME
motor_left
sleep ARM_ON_TIME
motor_stop
sleep ARM_PAUSE_TIME
reset_arm
write_to_syslog("Reset complete.")
end
def reset_arm
motor_right
sleep ARM_RESET_TIME
motor_stop
sleep ARM_RESET_TIME
motor_right
sleep ARM_RESET_TIME
motor_stop
end
##
# It all starts here...
def listener_main
# Set up the pins to use as an output pin
@gpio.mode OUTPUT_PINA, OUTPUT
@gpio.mode OUTPUT_PINB, OUTPUT
motor_stop
Signal.trap("TERM") do
motor_stop
exit
end
Signal.trap("USR1") do
reset_router
end
# Listen to the network for failures, with 5 seconds between polls
loop do
reset_router if reset_necessary?
sleep 5
end
end
# Go!
listener_main
#! /usr/bin/env bash
# This is intended for Debain consuption
### BEGIN INIT INFO
# Provides: thunker_daemon
# Required-Start: $all
# Required-Stop:
# Should-Start: $all
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Thunker
# Description: Thunker hits things when wireless drops.
### END INIT INFO
. /lib/lsb/init-functions
exec_name=thunker
exec_path=/usr/local/bin/$exec_name
display_name="Thunker Daemon"
start() {
pgrep ${exec_name} > /dev/null
if [ $? -eq 0 ]; then
log_success_msg "${display_name} is already running"
return
fi
if ${exec_path}&
then
disown
log_success_msg "${display_name} started"
else
log_failure_msg "Failed to start ${display_name}"
fi
}
stop() {
pkill ${exec_name}
pgrep ${exec_name} > /dev/null
if [ $? -ne 0 ]
then
log_success_msg "${display_name} stopped"
else
log_failure_msg "Failed to stop ${display_name}"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
pid=`pgrep ${exec_name}`
if [ $? -eq 0 ]
then
# All OK
echo "${display_name} running as PID:$pid."
exit 0
else
# We are not running
echo "${display_name} is not running."
exit 3
fi
;;
*)
echo "Usage: /etc/init.d/thunker_daemon {start|stop|restart|status}"
exit 1
;;
esac
exit 0
@iwillspeak
Copy link
Author

With thanks to @jstephenson and @tommylommykins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment