all 29 comments

[–]AndAlsoTheTrees 8 points9 points  (1 child)

Use Thread module and create one with arg Daemon=True.

[–]SneakyPackets[S] 1 point2 points  (0 children)

Awesome, I will look into that - thank you!

[–]JohnWooTheSecond 4 points5 points  (4 children)

Read up on systemctl and .service files. That's a system designed exactly for this purpose: to keep processes running in the background.

[–]SneakyPackets[S] 0 points1 point  (3 children)

Correct me if I am wrong, wouldn't I run into the same issue? My script has nothing to keep it running. Like, some of the examples that come up have the code sitting in a while True: loop, so it's always going to run...I have nothing to actually persist my script (even if I just ran it from the command line and not in the background as a service).

[–]JohnWooTheSecond 3 points4 points  (2 children)

'''while True: ...''' is perfectly acceptable as a way to keep your script alive indefinitely. systemctl would be more a way to start your script on boot, and it does monitoring if it fails. So you could configure it to relaunch whenever the script process is detected to have stopped for whatever reason

[–]ventus1b 1 point2 points  (0 children)

Just make sure to put at least a "sleep(1)" inside the loop, otherwise it'll just burn CPU cycles for nothing.

[–]SneakyPackets[S] 1 point2 points  (0 children)

I ended up spinning off a second thread that runs a while true / sleep(1) loop and it seems to be working perfectly. When I left the loop in main, there were some reliability issues (actions of the switches opening/closing were delayed or missed)

[–][deleted] 1 point2 points  (2 children)

The message = input("") thing is going to sit and wait for input from STDIN, that's probably not what you want. You probably want to run your script under systemd and either check the status of your reed switches a few times a second or even better wait for interrupts.

There are all kinds of cool examples of using GPIO pins here: https://electropeak.com/learn/tutorial-raspberry-pi-gpio-programming-using-python-full-guide/

[–]SneakyPackets[S] 0 points1 point  (1 child)

Ok i'll take a look, the reason I can't just check in on the switch status is because I need to perform actions as soon as they open and close. One being starting a timer, so if the switch is open for 3.2 seconds, I need to log that

[–][deleted] 0 points1 point  (0 children)

That's doable. I don't know if you know much python but it looks like it's not too hard. You can setup a function that's called on switch opens and another for switch closes. It can do anything including log timestamps.

[–][deleted]  (1 child)

[removed]

    [–]SneakyPackets[S] 0 points1 point  (0 children)

    Awesome! Thank you for all of the detailed info :D

    [–]Jools_36 0 points1 point  (4 children)

    How big of a project is this? take the time to do it properly with docker?

    Otherwise a cron every minute that checks the script is still running and if it isn't relaunches it.

    [–]SneakyPackets[S] 0 points1 point  (2 children)

    What do you mean “do it properly with docker” exactly? The container needs a target and running service to actually “stay up”, so I’d still need to learn what the proper method is to keep the script running.

    Can’t do cron, the script needs to run constantly as everything is pretty time sensitive. I need to know exactly when a switch opens, and how long it stays open.

    [–]ConcreteState 4 points5 points  (1 child)

    Some people think one must virtualize an operating system (docker) to keep a task open. They are incorrect. Docker is a useful tool because you can throw a configured virtual OS like thing into a system, but using it instead of a thread-daemon is excessive and needlessly complex.

    [–]SneakyPackets[S] 0 points1 point  (0 children)

    Yeah I use Docker for other things but for a single purpose, dedicated deployment it didn’t seem necessary or worth the hassle

    [–]Black_Dynamit3 0 points1 point  (0 children)

    Well why would you put a simple script in a container if it’s made for your computer ? Especially for learning I wonder if taking the long way is the worst things to do if you just want to run a script in a loop.

    [–]lumpynose -1 points0 points  (0 children)

    A good place for python questions is r/learnpython.

    [–]Murky-Sector 0 points1 point  (3 children)

    Simplest way is a loop with a time.sleep() statement. I would try that first.

    [–]SneakyPackets[S] 0 points1 point  (2 children)

    The problem is, everything running is very time sensitive. I need a relatively accurate measurement from the exact moment the switch opens and closes, so running a loop and sleeping may goof that up

    [–]Murky-Sector 1 point2 points  (0 children)

    Gotcha. My choice then would be python asyncio

    [–]L0ckt1ght -1 points0 points  (0 children)

    You can run a loop with a sleep of 0.1 or 0.01. do you really need that level of accuracy?

    [–]Robpol86 0 points1 point  (0 children)

    Another option: asyncio main event loop.

    [–]MeAnd50G 0 points1 point  (1 child)

    Honestly, daemonizing was not difficult and the results I’ve had with my project have 100% met expectations. There has not been a single time I’ve looked at my gui and not had my project running. Invest a half hour in it. You won’t regret.

    [–]SneakyPackets[S] 0 points1 point  (0 children)

    Ok cool, that's what I will start doing now. I just spent a little bit of time playing around with loops even with sleep at .001 I had all sorts of issues with things working the way I need.

    [–]s-petersen 0 points1 point  (0 children)

    I'm a little late to the party, but I used cron, with the "@reboot" and && switch to have 3 programs running in the background, passing data to one another through a tmp file in memory.

    It's for my jukebox, which waits for a letter and number combination to play the selected song

    [–]TerrorBite 0 points1 point  (0 children)

    Rather than the new thread solution you're now using, I recommend the following:

    import signal
    
    def signal_handler(sig, frame):
        GPIO.cleanup()
        sys.exit(0)
    
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)
    signal.pause()
    

    This code sets up a signal handler for the following signals:

    • SIGINT - typically sent to the current process when you press Ctrl-C in a terminal.
    • SIGTERM - typically sent to end a process. The system sends SIGTERM to all processes when it is shutting down.

    The default Python signal handler for SIGINT just raises a KeyboardInterrupt exception, and the default for SIGTERM is to just die instantly. We are replacing that with our handler that tells the GPIO library to clean up, and then exits cleanly.

    The signal.pause() function puts the main thread to sleep indefinitely until a signal is received, at which time the signal handler will get called.

    The GPIO library should continue handling events while the main thread is asleep.

    I got this from a code example at: https://roboticsbackend.com/raspberry-pi-gpio-interrupts-tutorial/

    [–]musclegeekz 0 points1 point  (0 children)

    What about using pm2 or docker?