It seems that all computers at some time or another need a reboot. Whether it is a smartphone, smart TV, laptop, home computer, or even the Raspberry Pi, the first line of defense when things stop working is to simply reboot. On a recent Raspberry Pi project, I would sometimes find that my Raspberry Pi Wi-Fi adapter would lose contact with the access point. I tried several options, but the only full proof solution was to simply reboot.
This Post describes how to implement a simple Cron Job, Bash Shell and Python Script to automatically reboot the Raspberry Pi in case no Wi-Fi is detected. The script will reboot several times if no Wi-Fi is detected. If, after three tries, Wi-Fi is still not available, it will reboot after a longer interval.
The project steps are as follows:
- Create a cron job that runs a bash shell script every 5-10 minutes
- Create a Short bash shell that changes to the correct directory and starts a Python Script
- Create a Python Script that will ping the local access point and reboot if no wifi is found.
- Test the Script
Cron Job setup:
The cron job is setup by simply editing the cron tab file. At a terminal window on the raspberry pi, type the following command:
Now type the following command at the end of the file:
*/5 * * * * <path to bash shell>/wifi_monitor.sh
You need to replace the path above with the path to where the bash shell will be placed when you create it. You can decide, but here is an example /home/pi/LConnect.
The script above will run every 5 minutes with the */5 portion of the command. You can adjust this to your system as required by simply replacing 5 in the command with any number you want (i.e. */10).
Create the Bash Shell Script:
Copy the following into a text editor and save the Script as wifi_monitor.sh in the directory of your choice.
#!/bin/bash cd /home/pi/LConnect sudo python wifi_monitor.py 2>>outlog.log &
You can adjust the path shown in line 2 one of the bash script to point to where you want to put your python script file. The permissions of the bash Script file need to be changed so that the cron job will be able to execute. Change to the directory of the bash Script and perform the following command
chmod +x wifi_monitor.sh
Now we are set to create the python Script that will do all the work
Create the Python Script:
Copy the following into a text editor and save the Script as wifi_monitor.py in the directory you choose from the bash script above.
#!/usr/bin/python import datetime import time import subprocess import pickle filename = "wifi_monitorlog.txt" datafile = "wifi_monitordata.txt" x = 0 CantFindWifi = False if __name__ == "__main__": # we need to load the datafile. # while True: try: with open(datafile,'r') as f: timequeue = pickle.load(f) except : print("the datafile was not found. initializing variables") timequeue =[datetime.datetime(1,1,1),datetime.datetime(1,1,1),datetime.datetime(1,1,1)] # check 20 times every 1s for the wifi in case it can't find it. CantFindWifi = True for x in range (1,20): print "try ",x if (subprocess.call('ping -c4 192.168.1.1',stdout=None,stderr=None, shell=True)) == 0: CantFindWifi = False break time.sleep(1) if (CantFindWifi): timenow = datetime.datetime.now() if (timenow - timequeue) > datetime.timedelta(minutes=60): sout = "wifi is not working -- Rebooting: " + timenow.strftime('%a, %d %b, %Y, %I:%M:%S %p') + "\n" timequeue.append(timenow) timequeue.pop(0) print(sout) with open(filename,'a') as f: f.write(sout) # We need to save datafile here because we are rebooting with open(datafile,'w') as f: pickle.dump(timequeue,f) subprocess.call('sudo reboot',shell = True) else: sout = "wifi is not working -- Not Rebooting: " + timenow.strftime('%a, %d %b, %Y, %I:%M:%S %p') + "\n" print(sout) with open(filename,'a') as f: f.write(sout) else: print("wifi is working") # this datafile save occurs when we don't reboot. with open(datafile,'w') as f: pickle.dump(timequeue,f)
Using the above code as a guide, you may need to correct the IP address and to set the delay the script will wait before testing the Wi-Fi after three failures. Line 27 will send a ping to the IP address 192.168.1.1. You can adjust this to your access code IP address. The best way to test if the IP address will work is to run the following command in a terminal window:
ping <your ip address>
If the ping commands gets a response from the IP address, you are all set. The maximum delay before retesting the Wi-Fi after a reboot is adjusted in line 34. Right now it is set to 60 minutes. The code is designed to test and if needed, reboot the Raspberry Pi three time as set by the cron interval (i.e. 5 minutes). If no Wi-Fi is detected, the retest time will increase to the interval shown in line 34.
Testing the Code:
A log of all the actions from the script is recorded in wifi_monitorlog.txt . So if you simply unplug your router and wait 20 minutes, you may notice that your Raspberry Pi is rebooting every 5 minutes as specified in the cron job. I actually adjusted this interval to just 1 minute for testing. After turning on your access point, you can look at the log file and you should see a log that the Raspberry Pi rebooted three times before going to the longer interval. In this case, it does not reboot until after the longer interval, but records that Wi-Fi is still not working.
wifi is not working -- Rebooting: Wed, 03 May, 2017, 04:30:01 PM wifi is not working -- Rebooting: Wed, 03 May, 2017, 04:35:01 PM wifi is not working -- Rebooting: Wed, 03 May, 2017, 04:40:01 PM wifi is not working -- Not Rebooting: Wed, 03 May, 2017, 04:45:01 PM
Good luck and I hope this helps your next project. Sometimes you just need to reboot. 🙂