Issue
I'm trying to make a Raspberry Pi 3 REST API that provides temperature and humidity with DHT22. The whole code:
from flask import Flask, jsonify, request
from sds011 import SDS011
from adafruit_dht import DHT22
import board
import os
import time
app = Flask(__name__)
dht = DHT22(board.D4)
def get_dht_data():
while True:
try:
temperature, humidity = dht.temperature, dht.humidity
print(temperature, humidity)
if temperature is not None and humidity is not None:
return temperature, humidity
else:
raise
except:
time.sleep(0.5)
@app.route('/', methods=['GET'])
def status():
temperature, humidity = get_dht_data()
return jsonify({
'temperature': temperature,
'humidity': humidity
})
if __name__ == '__main__':
app.run(debug=True)
I used https://github.com/adafruit/Adafruit_CircuitPython_DHT
However, when I start server, it shows message
'Unable to set line 4 to input'
and temperature and humidity is always None
. If I don't run flask app but just DHT code, it works.
Solution
Short answer
Remove debug=True
and enjoy. :-)
What was going on?
This problem drove me nuts but I think I found the root cause! In my case, I was encapsulating the DHT22 object in another object, like so:
...
class DHT22Custom:
def __init__(self):
print("**** BUILDING by {0}!".format(threading.currentThread().getName()))
self.dht_device = adafruit_dht.DHT22(board.D17)
...
My main.py
looked like:
import RPi.GPIO as GPIO
from sensor.config.app_config import create_app
if __name__ == '__main__':
app = create_app() # builds DHT22Custom inside
app.run(debug=True)
print("Cleaning up GPIO before exiting...")
GPIO.cleanup()
And look what an interesting output I got:
root@05600e5:/app# python -m sensor.main
**** BUILDING by MainThread!
* Serving Flask app "FlaskWS" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
**** BUILDING by MainThread!
Unable to set line 17 to input
The MainThread was initializing my object twice! How was that? Well, if you look at the documentation of Flask's run()
, you'll see the following:
If the :attr:`debug` flag is set the server will automatically reload
for code changes and show a debugger in case an exception happened.
So, it seems that Flask just relaunches the application or something like this. Not clear to me, to be honest. But well, if you just remove debug
, you'll see something like:
root@05600e5:/app# python -m sensor.main
**** BUILDING by MainThread!
* Serving Flask app "FlaskWS" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
I hope this helps. Happy coding!
Answered By - jsubirat Answer Checked By - David Marino (WPSolving Volunteer)