Lord of the Rant.
Formerly turtle2472 Join Date: Mar 2005
Location: Upstate South Carolina
|
I need to daemonize a script rather than run it in a screen session. It works now, but once it crashes or whatever I need it to run again without me having to realize it stopped.
The background is I'm using a Raspberry Pi to serve as a temperature and humidity data logger. The original guide I followed use an older Adafruit_Python_DHT that has been deprecated. The newer script version is called CircuitPython-DHT. I've actually modified my copy so it doesn't send the alerts right to my Zabbix server but rather writes the temp and humidity readings to a txt file so it can be pulled by Zabbix. This is my current script with my modifications: Code:
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import adafruit_dht
# Initial the dht device, with data pin connected to:
#dhtDevice = adafruit_dht.DHT22(board.D2)
# you can pass DHT22 use_pulseio=False if you wouldn't like to use pulseio.
# This may be necessary on a Linux single board computer like the Raspberry Pi,
# but it will not work in CircuitPython.
dhtDevice = adafruit_dht.DHT22(board.D2, use_pulseio=False)
while True:
try:
# Print the values to the serial port
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = dhtDevice.humidity
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)
with open('/tmp/temp', 'w') as f:
f.write("{:.1f}".format(
temperature_f
)
)
with open('/tmp/humidity', 'w') as f:
f.write("{}".format(
humidity
)
)
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
dhtDevice.exit()
raise error
time.sleep(5.0) I know I can remove the "print" but I'm using that since I'm running it in screen. If I can demonize it that would go away. I looked at this article that talks about how to daemonize a script but I can't get it to work like I'm expecting and I know it is from my lack of knowledge of Python. Heck, it barked at me because I mixed spaces and tabs to indentation.This is what I came up with but it doesn't do anything and no news is not good news in this case. There is no process running and I would expect nor a PID file ever actually created: Code:
#!/usr/bin/python3
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
from daemonize import Daemonize
import time
import board
import adafruit_dht
pid = "/tmp/dataDHT.pid"
# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT22(board.D2)
def main():
while True:
try:
# Print the values to the serial port
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = dhtDevice.humidity
#print(
# "Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
# temperature_f, temperature_c, humidity
# )
#)
with open('/tmp/temp', 'w') as f:
f.write("{:.1f}".format(
temperature_f
)
)
with open('/tmp/humidity', 'w') as f:
f.write("{}".format(
humidity
)
)
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
dhtDevice.exit()
raise error
time.sleep(5.0)
daemon = Daemonize(app="dataDHT", pid=pid, action=main)
daemon.start() Louis L'Amour, “To make democracy work, we must be a nation of participants, not simply observers. One who does not vote has no right to complain.” Visit our archived Minecraft world! | Maybe someday I'll proof read, until then deal with it. |
quote |
‽
|
So this needs to run every roughly 10 seconds?
Consider getting rid of the loop altogether and instead making a systemd unit that calls the script at an interval. Something like: Code:
[Unit]
Description=Read DHT sensor
[Service]
User=%I
Restart=always
RestartSec=10s
ExecStart=#!/usr/bin/python3 /path/to/your/script.py Put that in /etc/systemd/system/read-dht-sensor.service and then do systemctl enable read-dht-sensor --now (I think).I'm assuming this is on Raspbian and/or that you have systemd. |
quote |
Lord of the Rant.
Formerly turtle2472 Join Date: Mar 2005
Location: Upstate South Carolina
|
Ohhh...
I didn't even think of something like that. I like it! Now I just need to figure out how to get rid of the loop. I'll get it, I just don't know python well at all. Kinda new territory to me. I'll post back for help with it if I can't get it figured out... or even if I do with what my code looks like. Louis L'Amour, “To make democracy work, we must be a nation of participants, not simply observers. One who does not vote has no right to complain.” Visit our archived Minecraft world! | Maybe someday I'll proof read, until then deal with it. |
quote |
Lord of the Rant.
Formerly turtle2472 Join Date: Mar 2005
Location: Upstate South Carolina
|
Well, that seems to work but the errors are a problem. DHT22 is known for having errors on readings so this isn't a shock. I need error handling for this script now. This is my result when manually running it a number of times:
Code:
pi@pitemp:~ $ ./dataDHT.py
Traceback (most recent call last):
File "./dataDHT.py", line 13, in <module>
temperature_c = dhtDevice.temperature
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_dht.py", line 259, in temperature
self.measure()
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_dht.py", line 215, in measure
raise RuntimeError("A full buffer was not returned. Try again.")
RuntimeError: A full buffer was not returned. Try again.
pi@pitemp:~ $ ./dataDHT.py
Traceback (most recent call last):
File "./dataDHT.py", line 13, in <module>
temperature_c = dhtDevice.temperature
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_dht.py", line 259, in temperature
self.measure()
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_dht.py", line 215, in measure
raise RuntimeError("A full buffer was not returned. Try again.")
RuntimeError: A full buffer was not returned. Try again.
pi@pitemp:~ $ ./dataDHT.py
Temp: 74.5 F / 23.6 C Humidity: 53.5% This is the code now, minus some of the commented sections for easy reading:Code:
#!/usr/bin/python3
import time
import board
import adafruit_dht
# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT22(board.D2)
# Print the values to the serial port
temperature_c = dhtDevice.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = dhtDevice.humidity
print(
"Temp: {:.1f} F / {:.1f} C Humidity: {}% ".format(
temperature_f, temperature_c, humidity
)
)
with open('/tmp/temp', 'w') as f:
f.write("{:.1f}".format(
temperature_f
)
)
with open('/tmp/humidity', 'w') as f:
f.write("{}".format(
humidity
)
) I enabled the "print" section so I could see in the terminal what was happening rather than just checking the text files.Louis L'Amour, “To make democracy work, we must be a nation of participants, not simply observers. One who does not vote has no right to complain.” Visit our archived Minecraft world! | Maybe someday I'll proof read, until then deal with it. |
quote |
‽
|
Yeah, I would leave the try/except stuff in.
|
quote |
Lord of the Rant.
Formerly turtle2472 Join Date: Mar 2005
Location: Upstate South Carolina
|
That seems to be helping. I didn't know the format for loops in python so I just stripped everything out based n indention. I put them back and so far it seems to be working. I'm still tweaking it and such so I'll post my end result after I the point I think I'll settle with.
I'm testing right now in screen with this: Code:
watch -n5 ./dataDHT.py It is actually working too.Louis L'Amour, “To make democracy work, we must be a nation of participants, not simply observers. One who does not vote has no right to complain.” Visit our archived Minecraft world! | Maybe someday I'll proof read, until then deal with it. |
quote |
‽
|
Yeah, Python is all about indentation — the while ends wherever the indentation increases. (I get the appeal, but… not a fan.)
|
quote |
Selfish Heathen
Join Date: May 2004
Location: Zone of Pain
|
Looks like you got this solved before I saw it, but I guess I'll add my two cents on a few small things…
Quote:
Quote:
Quote:
I like chucker's systemd service suggestion and would recommend that over manual daemon setup. The quality of this board depends on the quality of the posts. The only way to guarantee thoughtful, informative discussion is to write thoughtful, informative posts. AppleNova is not a real-time chat forum. You have time to compose messages and edit them before and after posting. |
|||
quote |
Lord of the Rant.
Formerly turtle2472 Join Date: Mar 2005
Location: Upstate South Carolina
|
Quote:
I mean, I remember watching these episodes and then hearing about it from my boss who liked it one way over the other. (I completely forgot what it was since I'm not a developer and didn't care and now he's quit our company and is no longer our boss. ) Quote:
In fact, this is how most of my "coding" gets done that isn't bash scripting. I actually am pretty good with bash so I have that going for me. Louis L'Amour, “To make democracy work, we must be a nation of participants, not simply observers. One who does not vote has no right to complain.” Visit our archived Minecraft world! | Maybe someday I'll proof read, until then deal with it. |
||
quote |
Veteran Member
Join Date: Nov 2006
|
❤️ black & flake8 checking. Have both of those setup as pre-commit hooks on my work laptop and as part of the CI/CD.
The logging module can be pretty handy if you want to move beyond print statements, e.g. Code:
import logging
LOGGER = logging.getLogger(__name__)
while True:
try:
# Log variables, return values, etc.
LOGGER.info("Some variable in the code is: {my_variable}".format(my_variable=my_variable))
except RuntimeError as err:
LOGGER.error("Whoops some error occurred", exc_info=True)
LOGGER.info(f"Here is some other variable: {some_other}".format(some_other=some_other)) Seen a man standin' over a dead dog lyin' by the highway in a ditch He's lookin' down kinda puzzled pokin' that dog with a stick |
quote |
Selfish Heathen
Join Date: May 2004
Location: Zone of Pain
|
Quote:
I actually have my local editor set up to automatically run black every time it saves a Python file. I resisted auto-formatters at first, but getting to just turn off that part of the brain and never think about debating style choices is soooooooo good. 100%. The logging module is definitely an upgrade for generating good console output, especially for any long-running code. What's also great about using the logging module (this is probably more for turtle's education…) is that you can configure the logging module at a high level with different handlers and formatters to, for example, send some logs to files on disk and some logs to stdout, or prepend the timestamp and process ID to all messages, or only output things logged at "error" in one part of your code but output everything at "debug" in some other part of your code. Heck, some of our Python services have a logging handler that intercepts log messages and sends them across the internet into AWS CloudWatch storage! Python logging configuration is very powerful, though understanding all the options can be overwhelming at first. The quality of this board depends on the quality of the posts. The only way to guarantee thoughtful, informative discussion is to write thoughtful, informative posts. AppleNova is not a real-time chat forum. You have time to compose messages and edit them before and after posting. |
|
quote |
Selfish Heathen
Join Date: May 2004
Location: Zone of Pain
|
Quote:
For the most part, Python doesn't care whether you use tabs or spaces, but it does need for you to pick a lane. A given file should be indented exclusively by one or the other, never mixing both, because one programmer's definition of a tabstop width may be completely different from the next programmer's (1 tab = 4 spaces? 8? 2???), and Python doesn't want to pick sides in that argument. Instead, it basically throws up its arms and makes you correct the inconsistency. Most editors and IDEs, even vim in the terminal, can be taught to insert the right amount of space characters when you hit the tab key. I'm pretty sure 99% of my indended spaces in recent years originated from me hitting the tab key and trusting my editor to do the right thing. ("The right thing" is "convert to spaces", obviously. ) Quote:
The quality of this board depends on the quality of the posts. The only way to guarantee thoughtful, informative discussion is to write thoughtful, informative posts. AppleNova is not a real-time chat forum. You have time to compose messages and edit them before and after posting. |
||
quote |
‽
|
|
quote |
Selfish Heathen
Join Date: May 2004
Location: Zone of Pain
|
Pretty much all the worthwhile options around me in recent years have been Java (or Scala), Ruby, or Python, and I'll take Python from that list any day of the week. I've seen a small smattering of Node stuff and a light dusting of Go, but those have been few and far between.
Though, for a brief while in 2017 one company desperately tried to get me to write .NET 2.0 (released 2005) running on Windows Server 2008. I've not seen many dumpster fires quite as gnarly as that one. The quality of this board depends on the quality of the posts. The only way to guarantee thoughtful, informative discussion is to write thoughtful, informative posts. AppleNova is not a real-time chat forum. You have time to compose messages and edit them before and after posting. |
quote |
‽
|
Quote:
I used to write some Ruby back in the 2000s, and I think it has some cute features, but I get the sense I could never go back to static typing. |
|
quote |
Veteran Member
Join Date: Nov 2006
|
Quote:
This has been one of the best parts for us as well. There was *one* time where black couldn't reformat a line such that it stayed with 100 characters. However, on inspection in the pull request, I noticed the engineer had tried to commit code that had this insanely nested lambdas of lambdas of lambdas (aka something that was going to be a nightmare to debug & maintain). That...got fixed. Seen a man standin' over a dead dog lyin' by the highway in a ditch He's lookin' down kinda puzzled pokin' that dog with a stick |
|
quote |
Posting Rules | Navigation |
|
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
New to Python, pointers? | turtle | Programmer's Nook | 22 | 2014-11-21 20:45 |
fast python input | evan | Programmer's Nook | 12 | 2010-10-28 15:22 |
Need some massive help in Python... | RowdyScot | Programmer's Nook | 4 | 2006-10-10 00:51 |
Python in Xcode | Oskar | Programmer's Nook | 7 | 2006-02-04 16:23 |
Python vs Alligator | Matsu | AppleOutsider | 3 | 2005-10-06 22:10 |