Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make python script exit after x seconds of inactivity

I have a script for my raspberry pi that continually takes readings and saves data to a file. However I know this is dangerous as there is a real risk of the SD card becoming corrupted if the power is pulled while data is being saved.

Is there a way I can have the script terminate itself if the computer is inactive for a set amount of time?

Sorry if this question is vague but I have no idea where to even begin with this so I can't show any code that I have tried.

like image 728
Pauly D Avatar asked Mar 20 '26 09:03

Pauly D


1 Answers

That is a naive watchdog implementation:

import os
import signal
import threading



class Watchdog():
    def __init__(self, timeout=10):
        self.timeout = timeout
        self._t = None

    def do_expire(self):
        os.kill(os.getpid(),signal.SIGKILL)

    def _expire(self):
        print("\nWatchdog expire")
        self.do_expire()

    def start(self):
        if self._t is None:
            self._t = threading.Timer(self.timeout, self._expire)
            self._t.start()

    def stop(self):
        if self._t is not None:
            self._t.cancel()
            self._t = None

    def refresh(self):
        if self._t is not None:
             self.stop()
             self.start()

Build it by wd = Watchdog() and every time you get something that feed your work call wd.refresh(). If you don't call refresh before timeout ends it will call os.kill(os.getpid(),signal.SIGKILL).

You cannot use just sys.exit() because it raise just a SystemExit exception: use kill works as you want.

Now you can use something to poll the system and use the answer to refresh or not the watch dog. For instance xprintidle tell to you the X idle time, but all depend from what you need to monitoring.

Use example

timeout=10
wd = Watchdog(timeout)
wd.start()
while True:
    a=str(raw_input('Tell me something or I will die in {} seconds: '.format(timeout)))
    wd.refresh()
    print("You wrote '{}'... you win an other cycle".format(a[:-1))
like image 186
Michele d'Amico Avatar answered Mar 22 '26 10:03

Michele d'Amico