WiFi Reconnection Script[source]

xml
<glacius:metadata>
    <title>WiFi Reconnection Script</title>
    <description>Little script to automatically reconnect to wifi, e.g. on a Raspberry Pi</description>
    <category>Code snippets</category>
    <category>Programming</category>
    <category>Bash</category>
</glacius:metadata>
<p>
    I recently upgraded my magic mirror from a 1st gen Raspberry Pi B to a Raspberry Pi 4.
    The RPi4 has a builtin WiFi adapter so I don't need the dongle. I thought it would be
    more stable, but so far not so much. It can't connect to my 2.4GHz SSID but kinda
    connects to the 5GHz SSID. However, it periodically refuses to reconnect. And since
    the Pi is locked inside a frame, duct-taped to the back of a monitor, it's not easy
    to rip it off the wall to troubleshoot.
</p>
<p>
    Normally what I would so is just unplug and plug it back in to make it reconnect, but
    that only seemed like a reasonable thing to do on a Pi from 2012, but not one from this
    decade. So I wrote this cron script that kind of works.
</p>
<p>
    Basically it uses the 
    <a href="https://www.networkmanager.dev/docs/api/latest/nmcli.html">NetworkManager CLI utility</a> 
    to see if the WiFi is connected,
    and if not, it cycles the radio off and then on. In the event that this doesn't work
    for 15 minutes (900 seconds), it just reboots the whole machine. I'm tired of trying
    to debug this nonsense so I'm taking a scorched Earth approach now.
</p>
<glacius:code lang="bash"><![CDATA[
#!/bin/bash
tempFile=/tmp/wifi-reconnect
if [[ ! -f "${tempFile}" ]]; then
	date +%s > "${tempFile}"
fi
if ! nmcli connection show --active | grep wifi > /dev/null; then
	lastConnected=$(cat "${tempFile}")
	threshold=900
	if [[ -n "${lastConnected}" && $(( lastConnected + threshold )) -lt $(date +%s) ]]; then
		echo "$(date) not connected, haven't connected for ${threshold}s (last: ${lastConnected}), rebooting..."
		/usr/sbin/shutdown -r now
		exit
	fi
	echo "$(date) not connected, cycling wifi radio..."
	nmcli radio wifi off
	nmcli radio wifi on
else
	echo "$(date) connected"
	date +%s > "${tempFile}"
fi
]]></glacius:code>
<p>
    This runs every minute from a cron job in <code>/etc/cron.d/wifi-reconnect</code>:
</p>
<glacius:code lang="cron"><![CDATA[* * * * * root /path/to/script/wifi-reconnect.sh >> /var/log/wifi-reconnect.log 2>&1
]]></glacius:code>
<p>
    The log file looks like this:
</p>
<glacius:code lang="plaintext"><![CDATA[Sat 23 Mar 13:12:01 PDT 2024 connected
Sat 23 Mar 13:13:01 PDT 2024 not connected, cycling wifi radio...
Sat 23 Mar 13:14:01 PDT 2024 connected
Sat 23 Mar 13:15:02 PDT 2024 connected
Sat 23 Mar 13:16:01 PDT 2024 connected
Sat 23 Mar 13:17:01 PDT 2024 connected
Sat 23 Mar 13:18:01 PDT 2024 connected
Sat 23 Mar 13:19:01 PDT 2024 connected
Sat 23 Mar 13:20:01 PDT 2024 connected
Sat 23 Mar 13:21:01 PDT 2024 connected
Sat 23 Mar 13:22:01 PDT 2024 connected
Sat 23 Mar 13:23:02 PDT 2024 connected
]]></glacius:code>