Power-Cycling Watchdog For My Dodgy Router#
I like the convenience of 5G home internet but unfortunately Australian ISPs all seem to use terrible modems. My current Telstra one is okay except it dies horribly maybe once a week and needs to be power cycled. I can live with less-than-perfect uptime but it's quite annoying to try to go online and realise it's been dead for hours. Is there some way I could detect when the modem has failed and turn it off and on automatically?
I wanted to avoid spending much money if I could help it so I took an underutilised Raspberry Pi 4 and ordered a cheap WiFi-controlled power outlet with a relay. This one comes preflashed with the hacker-friendly Tasmota firmware which means that there is minimal stuffing around to get it on a network and control the relay with some simple HTTP requests.
Now, obviously I can't just connect my relay to the router's WiFi network. If I did, as soon as I turned it off I would lose access to the relay and I would be unable to turn it on again. Happily, Raspberry Pis have pretty good support for creating a WiFi access point of their own. My solution then is that the Raspberry Pi connects to the router via wired Ethernet and its WiFi adapter creates a second network to which the relay connects. The Pi can use its wired connection to check whether the internet is working and its wireless connection to tell the relay what to do.
The script in this repo, check.sh, is installed as cron job for the root user on my pi.
# m h dom mon dow command
*/5 * * * * /root/check.sh
This tries to ping a couple of IPs and if they both fail to do so it assumes the modem is toast and restarts it by firing curl commands at the relay.
Notes#
WiFi hotspot#
sudo nmcli con add con-name hotspot ifname wlan0 type wifi ssid "power"
sudo nmcli con modify hotspot wifi-sec.key-mgmt wpa-psk
sudo nmcli con modify hotspot wifi-sec.psk "PasswordGoesHere"
sudo nmcli con modify hotspot 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared
Checking leases#
sudo cat /var/lib/NetworkManager/dnsmasq-wlan0.leases
Output looks like this:
1766054015 78:42:1c:f2:4e:a3 10.42.0.123 tasmota-F24EA3-3747 *
Permanent IP address for client#
Edit a new file like this one:
/etc/NetworkManager/dnsmasq.d/host-reservations.conf
Add a line like so:
dhcp-host=78:42:1c:f2:4e:a3,10.42.0.123
Tasmota access#
First-time setup: connect to its temporary AP on a desktop computer. It pops up a captive portal dialog through which you can authenticate it with another AP.
It is really hard to reach over the network due to its default power-saving mode. Run this in a loop until the curl command succeeds.
while true; do curl -v "http://10.42.0.123/cm?cmnd=Sleep%200"; sleep 1; done
After this it should be solidly available via ping and HTTP.
Relay control#
Check state:
$ curl http://10.42.0.123/cm?cmnd=Power
{"POWER":"ON"}
Power on:
curl "http://10.42.0.123/cm?cmnd=Power%20On"
Power off:
curl "http://10.42.0.123/cm?cmnd=Power%20Off"