Hello all I am looking for help with a simple python3 code that I am using for taking dht22 sensor readings and logging them for influxdb and grafana (works great by the way), My problem is that the code will run for a random amount of time then just stops, Im sure its from a dht read error but I need it to keep running regardless of a read error. If someone could take my code and fix it (show me where or whats missing) I would be much appreciative :)
import time
import logging
import Adafruit_DHT as adht
logging.basicConfig(filename='temperature.log', filemode='a', format='%(created)f %(message)s', level=logging.INFO)
try:
while True:
h,t = adht.read_retry(adht.DHT22, 23)
logging.info('Temp={0:0.1f} C and Humidity={1:0.1f} %'.format(t, h))
# Wait for * seconds
print("Waiting for 60 seconds… Sensor 0")
time.sleep(60)
else:
print("Failed to retrieve data from DHT22 sensor")
print('------------------------------------')
time.sleep(60) # Delay in seconds.
except:KeyboardInterrupt
pass
Why don't you just catch all exceptions?
If its a ReadError then it will just continue to loop?
How do I go about catching all exceptions?
Based on just reading the code:
else:
part of
while True:
loop is redundant. Nothing in while-loop body sets condition False so else-clause can't be executed. From documentation:
Output:
The "while" statement is used for repeated execution as long as an
expression is true:
while_stmt ::= "while" assignment_expression ":" suite
["else" ":" suite]
This repeatedly tests the expression and, if it is true, executes the
first suite; if the expression is false (which may be the first time
it is tested) the suite of the "else" clause, if present, is executed
and the loop terminates.
So only way out from
while True
is exception raised during execution of loop. If such event occurs in
try:
block then KeyboardInterrupt is raised. From documentation:
Output:
The "except" clause(s) specify one or more exception handlers. When no
exception occurs in the "try" clause, no exception handler is
executed. When an exception occurs in the "try" suite, a search for an
exception handler is started. This search inspects the except clauses
in turn until one is found that matches the exception. An expression-
less except clause, if present, must be last; it matches any
exception.
/../
When a matching except clause is found, the exception is assigned to
the target specified after the "as" keyword in that except clause, if
present, and the except clause’s suite is executed. All except
clauses must have an executable block. When the end of this block is
reached, execution continues normally after the entire try statement.
So 'catch it all'
except:
clause catches any error raised in try block just to raise KeyboardInterrupt.
Thanks for the help dudes :)
If you compare the old Library and the new from Circuit Python, you see that they raise a RuntimeError if something wrong happens.
https://github.com/adafruit/Adafruit_Cir...ht.py#L205
https://github.com/adafruit/Adafruit_Cir...ht.py#L209
https://github.com/adafruit/Adafruit_Cir...ht.py#L237
https://github.com/adafruit/Adafruit_Cir...ht.py#L241
The old library is also raises a RuntimeError:
https://github.com/adafruit/Adafruit_Pyt...erry_Pi.py (just seek "raise ")
Corrected version, but not tested.
import logging
import sys
import time
import Adafruit_DHT as adht
logging.basicConfig(
filename="temperature.log",
filemode="a",
format="%(created)f %(message)s",
level=logging.INFO,
)
log = logging.getLogger()
def main_loop():
while True:
try:
humidity, temperature = adht.read_retry(adht.DHT22, 23)
except RuntimeError as e:
# this block, if RuntimeError were raised from adht.read_retry
log.error(f"RuntimeError: {e}")
else:
# this block, if no Exception were raised by adht.read_retry
log.info(f"Temp={temperature:0.1f} C and Humidity={humidity:0.1f} %")
# this is always executed
print("Waiting for 60 seconds… Sensor 0", file=sys.stderr)
time.sleep(60)
if __name__ == "__main__":
try:
main_loop()
except KeyboardInterrupt:
print("\nCTRL+C\n", file=sys.stderr)
By the way, I use always
black and
isort for code formatting and sorting of imports.
For example the module from Adafruit is a third-party module. This should be imported after first party packages like sys, os, etc.
Other changes:
- f-strings
- log = logging.getLogger() and use this instead of logging.error, logging.info
- printing to sys.stderr
- loop is in a function
- try-except around main_loop