44import ST7735
55import time
66from bme280 import BME280
7- from pms5003 import PMS5003 , ReadTimeoutError
7+ from pms5003 import PMS5003 , ReadTimeoutError , ChecksumMismatchError
88from subprocess import PIPE , Popen , check_output
99from PIL import Image , ImageDraw , ImageFont
1010from fonts .ttf import RobotoMedium as UserFont
1313 from smbus2 import SMBus
1414except ImportError :
1515 from smbus import SMBus
16+ import logging
1617
17- print ("""luftdaten.py - Reads temperature, pressure, humidity,
18- PM2.5, and PM10 from Enviro plus and sends data to Luftdaten,
19- the citizen science air quality project.
18+ logging .basicConfig (
19+ format = '%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s' ,
20+ level = logging .INFO ,
21+ datefmt = '%Y-%m-%d %H:%M:%S' )
2022
21- Note: you'll need to register with Luftdaten at:
22- https://meine.luftdaten.info/ and enter your Raspberry Pi
23- serial number that's displayed on the Enviro plus LCD along
24- with the other details before the data appears on the
25- Luftdaten map.
23+ logging .info ("""luftdaten.py - Reads temperature, pressure, humidity,
24+ #PM2.5, and PM10 from Enviro plus and sends data to Luftdaten,
25+ #the citizen science air quality project.
2626
27- Press Ctrl+C to exit!
27+ #Note: you'll need to register with Luftdaten at:
28+ #https://meine.luftdaten.info/ and enter your Raspberry Pi
29+ #serial number that's displayed on the Enviro plus LCD along
30+ #with the other details before the data appears on the
31+ #Luftdaten map.
2832
29- """ )
33+ #Press Ctrl+C to exit!
34+
35+ #""" )
3036
3137bus = SMBus (1 )
3238
@@ -63,7 +69,8 @@ def read_values():
6369 pm_values = pms5003 .read ()
6470 values ["P2" ] = str (pm_values .pm_ug_per_m3 (2.5 ))
6571 values ["P1" ] = str (pm_values .pm_ug_per_m3 (10 ))
66- except ReadTimeoutError :
72+ except (ReadTimeoutError , ChecksumMismatchError ):
73+ logging .info ("Failed to read PMS5003. Reseting and retrying." )
6774 pms5003 .reset ()
6875 pm_values = pms5003 .read ()
6976 values ["P2" ] = str (pm_values .pm_ug_per_m3 (2.5 ))
@@ -118,36 +125,59 @@ def send_to_luftdaten(values, id):
118125 pm_values_json = [{"value_type" : key , "value" : val } for key , val in pm_values .items ()]
119126 temp_values_json = [{"value_type" : key , "value" : val } for key , val in temp_values .items ()]
120127
121- resp_1 = requests .post (
122- "https://api.luftdaten.info/v1/push-sensor-data/" ,
123- json = {
124- "software_version" : "enviro-plus 0.0.1" ,
125- "sensordatavalues" : pm_values_json
126- },
127- headers = {
128- "X-PIN" : "1" ,
129- "X-Sensor" : id ,
130- "Content-Type" : "application/json" ,
131- "cache-control" : "no-cache"
132- }
133- )
134-
135- resp_2 = requests .post (
136- "https://api.luftdaten.info/v1/push-sensor-data/" ,
137- json = {
138- "software_version" : "enviro-plus 0.0.1" ,
139- "sensordatavalues" : temp_values_json
140- },
141- headers = {
142- "X-PIN" : "11" ,
143- "X-Sensor" : id ,
144- "Content-Type" : "application/json" ,
145- "cache-control" : "no-cache"
146- }
147- )
148-
149- if resp_1 .ok and resp_2 .ok :
150- return True
128+ resp_pm = None
129+ resp_bmp = None
130+
131+ try :
132+ resp_pm = requests .post (
133+ "https://api.luftdaten.info/v1/push-sensor-data/" ,
134+ json = {
135+ "software_version" : "enviro-plus 0.0.1" ,
136+ "sensordatavalues" : pm_values_json
137+ },
138+ headers = {
139+ "X-PIN" : "1" ,
140+ "X-Sensor" : id ,
141+ "Content-Type" : "application/json" ,
142+ "cache-control" : "no-cache"
143+ },
144+ timeout = 5
145+ )
146+ except requests .exceptions .ConnectionError as e :
147+ logging .warning ('Luftdaten PM Connection Error: {}' .format (e ))
148+ except requests .exceptions .Timeout as e :
149+ logging .warning ('Luftdaten PM Timeout Error: {}' .format (e ))
150+ except requests .exceptions .RequestException as e :
151+ logging .warning ('Luftdaten PM Request Error: {}' .format (e ))
152+
153+ try :
154+ resp_bmp = requests .post (
155+ "https://api.luftdaten.info/v1/push-sensor-data/" ,
156+ json = {
157+ "software_version" : "enviro-plus 0.0.1" ,
158+ "sensordatavalues" : temp_values_json
159+ },
160+ headers = {
161+ "X-PIN" : "11" ,
162+ "X-Sensor" : id ,
163+ "Content-Type" : "application/json" ,
164+ "cache-control" : "no-cache"
165+ },
166+ timeout = 5
167+ )
168+ except requests .exceptions .ConnectionError as e :
169+ logging .warning ('Luftdaten Climate Connection Error: {}' .format (e ))
170+ except requests .exceptions .Timeout as e :
171+ logging .warning ('Luftdaten Climate Timeout Error: {}' .format (e ))
172+ except requests .exceptions .RequestException as e :
173+ logging .warning ('Luftdaten Climate Request Error: {}' .format (e ))
174+
175+ if resp_pm is not None and resp_bmp is not None :
176+ if resp_pm .ok and resp_bmp .ok :
177+ return True
178+ else :
179+ logging .warning ('Luftdaten Error. PM: {}, Climate: {}' .format (resp_pm .reason , resp_bmp .reason ))
180+ return False
151181 else :
152182 return False
153183
@@ -166,23 +196,25 @@ def send_to_luftdaten(values, id):
166196font_size = 16
167197font = ImageFont .truetype (UserFont , font_size )
168198
169- # Display Raspberry Pi serial and Wi-Fi status
170- print ("Raspberry Pi serial: {}" .format (get_serial_number ()))
171- print ("Wi-Fi: {}\n " .format ("connected" if check_wifi () else "disconnected" ))
199+ # Log Raspberry Pi serial and Wi-Fi status
200+ logging . info ("Raspberry Pi serial: {}" .format (get_serial_number ()))
201+ logging . info ("Wi-Fi: {}\n " .format ("connected" if check_wifi () else "disconnected" ))
172202
173203time_since_update = 0
174204update_time = time .time ()
175205
176206# Main loop to read data, display, and send to Luftdaten
177207while True :
178208 try :
179- time_since_update = time .time () - update_time
180209 values = read_values ()
181- print ( values )
210+ time_since_update = time . time () - update_time
182211 if time_since_update > 145 :
183- resp = send_to_luftdaten (values , id )
212+ logging . info (values )
184213 update_time = time .time ()
185- print ("Response: {}\n " .format ("ok" if resp else "failed" ))
214+ if send_to_luftdaten (values , id ):
215+ logging .info ("Luftdaten Response: OK" )
216+ else :
217+ logging .warning ("Luftdaten Response: Failed" )
186218 display_status ()
187219 except Exception as e :
188- print ( e )
220+ logging . warning ( 'Main Loop Exception: {}' . format ( e ) )
0 commit comments