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:
crontab -e
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[0]) > 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. 🙂
I wrote a similar autoreboot script that among other things will wait for a longer time after a certain number of reboots.
https://gist.github.com/glowinthedark/56e8dfa9105e1e1c98d6d61b8ac823db
Thanks glowinthedark! Updating the code to allow the time to increase is a good improvement. the particular issue is that if the wifi service/router is shut down, then items requiring access will be rebooting every 5,10 minutes. By automating when the time is increased, the reset period goes up after a few tries, but you still have a chance for the device to auto correct once the service is returned. I actually ended up improving the code on my RPi machines to allow just this feature but had not been able to update the blog. Thank for the comment and contribution
Hello!! Thank you very much for the article. I am trying to install it on my raspberry pi but I have an issue with the python script. Could you please send the file?? I have this error when trying to save the datafile
pickle.dump(timequeue,f)
TypeError: write() argument must be str, not bytes
Thank you very much
Thx 4 this. Unfortunately I get an “IndentationError” on line 16 of the py-Script (the first “try”) and can not get rid of it.
Any clue?
Python is picky about mixing tabs versus spaces as indentation in a file . Check to see that you are using the same type of indentation for each line. I try to use spaces only on my scripts. Let me know if that was the case?
Well, I copied and pasted your script. And I am pretty sure that I already tried to delete all blanks and retyped spaces. Will give it another try anyway…btw.: I have no clue about Python…
Hi Falk,
I updated the code indentations in the blog to match what I’m using on one of my machines. See if you have better luck with this version. Sorry for the trouble. For some reason the indentations on the blog code were incorrect. WordPress changed its editor a year or so ago and this may have had an impact. Probably my mistake. Let me know if you have better luck. Thanks for letting me know. Mark
Thank you. Unfortunately it seems as if the blog is presented totally different to me.
On my side, there are no indentations at all, besides that the bb-code does not seem to work (the code is not displayed as code).
Wish I could show it to you…
Nevertheless I figured out how to run that script (even if I am still not sure if the cronjob is running…). There were some more issues than “just” the indentations. I also had to replace all ” and ‘ – and I was very confused that the interpreter also looks at the comment- lines (it does not like “doesn’t” i.e.)
Last thing to sort out is the question if the cronjob is actually running…
#!/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[0]) > 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)
Hi Falk,
I reformatted the BLOG post so the code NOW shows the proper indentation. Thanks for bringing this to my attention. I have confirmed it looks OK in my browser.
Hey Mark,
looks great now. Thank you for all the work.
I added a line to write another logfile to make sure that the script (and the cron job) is running. Until now it seems to work as it should.
Without this blog I surely would have given up long before any result. So, thank you again for this blog!
Thanks for the feedback and kind words. Have a great weekend.