I have a little python3 script to control our central heating. It runs through a while true: loop, with time.sleep(-time.time() % 5) to be synchronized to the system clock while checking the if statements forever. Total runtime is over one year.
It runs inside GNU screen on Arch Linux ARM on a Raspberry 2.
Until now, it happened twice, that the program just "sleeps" until I log in and reattach to the screen. Then I can see the output e.g. from five hours ago when it started to sleep and as soon as getting reattached to the screen, it continues to work again and give new output.
I have no idea where to start since I get no errors and the "sleeps" happened to happen without any relation I could think of.
And I have two other python scripts also running on its own GNU screen. One script still recorded temperatures to a database with a time.sleep(-time.time() % 60) and the other still saved values to a database all the time.
Related
Background
I'm struggling to find a example of WDT in the way I want to use it. Wondering if I misunderstanding its use.
my python writing is pure hobby, honestly Classes intimidate me.
in short my program reads a number of sensors connected to a raspberry pi and writes the data to a cloud hosted object database.
i have an intermittent error that while I try to figure out I want to implement a based watchdog timer.
This is what I'd like to implement so in the very least I continue to collect and store data.
I've read about the builtin watchdog timer the raspberry pi has built in here: https://diode.io/raspberry%20pi/running-forever-with-the-raspberry-pi-hardware-watchdog-20202/
The problem I want the raspberry pi to reboot if my program hangs, but when that happens the OS is still fine, so the solution in the link above is not effective.
What I'd like to implement:
set the builtin watchdog timer to reboot the raspberry pi after 200 seconds without restarting (patting?) the timer. I think the instructions for this are in the link above.
Within my python script, after I iterate through each sensor, restart (or pat?) the watchdog timer and if 200 seconds elapse between pattings (meaning my program hangs) then RPi reboots.
is this possible?
can someone help me with some simple code? I was hoping to keep this simple and avoid classes and/or threads...
thank you in advance
The WDT is probably not the right solution for the problem you are describing. Based on your description, it sounds like what you have is a program that is intended to run periodically (either on a fixed schedule or in response to some event), and that program currently has a bug that is causing it to hang intermittently and never complete it's task or terminate.
The first and best way to solve that, I'm sure you can guess, is to fix the bug. But your thinking is not unreasonable either, and doing what you describe is very common. There are many valid approaches that will do what you want without the complexity of trying to deal with a hardware timer. One of the easiest is probably to just wrap the program in a shell script and use the timeout command to limit how long it is allowed to execute before it is terminated.
Assuming the script is located at /home/user/my_script.py, and you want to run it every 10 minutes, allowing it 2 minutes before it is killed, this would work:
create a wrapper shell script:
#!/usr/bin/env bash
if ! timeout 120s python /home/user/my_script.py; then
msg="$(date) - script exceeded timeout and was killed"
else
msg="$(date) - script ran successfully"
fi
echo "${msg}" >> /home/user/my_script.log
put the script in a file, say at /home/user/wrapper_script.sh and run chmod 755 /home/user/wrapper_script.sh to make it executable.
schedule the script to run every 10 minutes using cron. At a shell, use crontab -e to edit the users crontab file and add a new line like this:
*/10 * * * * /home/user/wrapper_script.sh
now, every 10 minutes the wrapper will start automatically, and it will kick off the python script. It will wait 2 minutes for the script to stop normally, after which it will reach the timeout and terminate it.
Note: depending on how your python program is written, you might have to use some other options to the timeout command to specify which signal it should use to stop the program. If it is a very basic python script, it should be fine using the default.
Edit: based on the comments, you might be able to just change the command you're using to this:
xterm -T "HMS" -geometry 100x70+10+35 -hold -e sudo timeout 120s /usr/bin/python3 /home/pi/h$
Doing that won't actually schedule the script to run at any fixed interval, so it assumes you already have something in place to handle that. All this will do is make srue that the script is restricted to 120 seconds of run time before it is killed.
I have a Python script that has an infinite loop in it.
while True:
doStuff()
Now I need to check from some external script in case the program freezes - for example if doStuff() was not executed for five minutes reboot the system. My idea is to save current time to a file every time doStuff runs and then read it from another script and if time saved in that file is 5 minutes less than now then reboot. Is there some better and more elegant solution to this?
Edit: and no - I'm not trying to check if program is running - I need to check in case it is still running but it got stuck somewhere
I am trying to do a simple bot in Python, I have written the body and I wanted to try it on real data. So I ran it, it runs in an infinite loop and at the end of the loop it sleeps for 6 seconds because it gets data from server and needs to sleep so it does not get kicked from server. Anyway, by the time I sat in front of the PC and was doing my stuff the script was running (I am running it from Windows command prompt) but when I turned off the screen and came back, the script was not running anymore. I have tried this few times with different lengths of the runs of script and always it stopped after i turned off the screen.
How to keep python script running once the computer screen is turned off
Check "Power Options" in the Control panel.
You don't need to worry about the screen locking or turning off as these wont affect running processes in python. However, if your system is set to sleep after a set amount of time you may need to change this to Never. Keep in mind there are separate settings depending on whether or not the system is plugged in.
Change "Battery saver" mode to "Best Performance" mode.
This worked for me, in continue running the scripts when screen turned off
So far, I've learned programming using languages that are interpreted (javascript.) So it's easy enough for me to draw shapes, and do cool things while the user is interacting.
But now I want to make a program that does things in the background of the users machine, and doesn't take up a lot of resources.
I'm familiar with python, so I've started making key functions, and I can run them from the terminal, but I'm lost on how I could tell the program to check for hard drives, say, every ten minutes.
Is there an OS feature that my program can get called upon every ten minutes?
Or should I do a while loop, and just wait for something to change?
The latter seems processesor-heavy, but I have no idea.
If you could just give me the keywords to Google, I could follow the rabbit hole, but this isn't something I've ever run across.
If you're on Unix, you can use cron. An example of a crontab entry that runs every ten minutes:
$ crontab -l
*/10 * * * * /home/username/script.py
Here's an intro to cron: http://www.unixgeeks.org/security/newbie/unix/cron-1.html.
On Windows, use Task Scheduler.
A very easy way to run something every 10 minutes is the following:
import time
while(True):
yourFunction(...)
time.sleep(600)
Time.sleep(600) will pause the execution of your program for 600 seconds
I'm turning my raspberry pi running on raspbmc (based on Debian) into an alarm clock that turns my tv on, displays the weather and plays a predifined song at, you guessed it, a specific time. I currently have most of the functionality implemented with Python e.g.: storing the path to a file for the song and filling in the wake-up time via a simple web interface.
I'm wondering what the best way (least intensive) is to run the wake-up routine at a specific time entered by me and, of course, change it when a new time is entered.
Hope you guys can help me out. Thanks!
Just set up a cron task and set up a python script to perform the actions you need when triggered by cron.
Try:
% crontab -e
add a line:
10 7 * * 1-5 /path/to/your/script
Save & exit.
This should run your script at 7:10 Monday-Friday