99import ST7735
1010import time
1111from bme280 import BME280
12- from pms5003 import PMS5003 , ReadTimeoutError
12+ from pms5003 import PMS5003 , ReadTimeoutError , SerialTimeoutError
1313from enviroplus import gas
1414
1515try :
3737DEFAULT_MQTT_BROKER_IP = "localhost"
3838DEFAULT_MQTT_BROKER_PORT = 1883
3939DEFAULT_MQTT_TOPIC = "enviroplus"
40+ DEFAULT_READ_INTERVAL = 5
4041
4142# mqtt callbacks
4243def on_connect (client , userdata , flags , rc ):
43- print (f"CONNACK received with code { rc } " )
4444 if rc == 0 :
4545 print ("connected OK" )
4646 else :
@@ -51,11 +51,10 @@ def on_publish(client, userdata, mid):
5151 print ("mid: " + str (mid ))
5252
5353
54- # Read values from BME280 and PMS5003 and return as dict
55- def read_values (bme280 , pms5003 ):
54+ # Read values from BME280 and return as dict
55+ def read_bme280 (bme280 ):
5656 # Compensation factor for temperature
5757 comp_factor = 2.25
58-
5958 values = {}
6059 cpu_temp = get_cpu_temperature ()
6160 raw_temp = bme280 .get_temperature () # float
@@ -65,6 +64,17 @@ def read_values(bme280, pms5003):
6564 int (bme280 .get_pressure () * 100 ), - 1
6665 ) # round to nearest 10
6766 values ["humidity" ] = int (bme280 .get_humidity ())
67+ data = gas .read_all ()
68+ values ["oxidised" ] = int (data .oxidising / 1000 )
69+ values ["reduced" ] = int (data .reducing / 1000 )
70+ values ["nh3" ] = int (data .nh3 / 1000 )
71+ values ["lux" ] = int (ltr559 .get_lux ())
72+ return values
73+
74+
75+ # Read values PMS5003 and return as dict
76+ def read_pms5003 (pms5003 ):
77+ values = {}
6878 try :
6979 pm_values = pms5003 .read () # int
7080 values ["pm1" ] = pm_values .pm_ug_per_m3 (1 )
@@ -76,17 +86,14 @@ def read_values(bme280, pms5003):
7686 values ["pm1" ] = pm_values .pm_ug_per_m3 (1 )
7787 values ["pm25" ] = pm_values .pm_ug_per_m3 (2.5 )
7888 values ["pm10" ] = pm_values .pm_ug_per_m3 (10 )
79- data = gas .read_all ()
80- values ["oxidised" ] = int (data .oxidising / 1000 )
81- values ["reduced" ] = int (data .reducing / 1000 )
82- values ["nh3" ] = int (data .nh3 / 1000 )
83- values ["lux" ] = int (ltr559 .get_lux ())
8489 return values
8590
8691
8792# Get CPU temperature to use for compensation
8893def get_cpu_temperature ():
89- process = Popen (["vcgencmd" , "measure_temp" ], stdout = PIPE , universal_newlines = True )
94+ process = Popen (
95+ ["vcgencmd" , "measure_temp" ], stdout = PIPE , universal_newlines = True
96+ )
9097 output , _error = process .communicate ()
9198 return float (output [output .index ("=" ) + 1 : output .rindex ("'" )])
9299
@@ -113,14 +120,16 @@ def display_status(disp, mqtt_broker):
113120 WIDTH = disp .width
114121 HEIGHT = disp .height
115122 # Text settings
116- font_size = 16
123+ font_size = 12
117124 font = ImageFont .truetype (UserFont , font_size )
118125
119126 wifi_status = "connected" if check_wifi () else "disconnected"
120127 text_colour = (255 , 255 , 255 )
121128 back_colour = (0 , 170 , 170 ) if check_wifi () else (85 , 15 , 15 )
122- id = get_serial_number ()
123- message = "{}\n Wi-Fi: {}\n mqtt-broker: {}" .format (id , wifi_status , mqtt_broker )
129+ device_serial_number = get_serial_number ()
130+ message = "{}\n Wi-Fi: {}\n mqtt-broker: {}" .format (
131+ device_serial_number , wifi_status , mqtt_broker
132+ )
124133 img = Image .new ("RGB" , (WIDTH , HEIGHT ), color = (0 , 0 , 0 ))
125134 draw = ImageDraw .Draw (img )
126135 size_x , size_y = draw .textsize (message , font )
@@ -132,34 +141,50 @@ def display_status(disp, mqtt_broker):
132141
133142
134143def main ():
135- parser = argparse .ArgumentParser (description = "Publish enviroplus values over mqtt" )
144+ parser = argparse .ArgumentParser (
145+ description = "Publish enviroplus values over mqtt"
146+ )
136147 parser .add_argument (
137- "--broker" , default = DEFAULT_MQTT_BROKER_IP , type = str , help = "mqtt broker IP" ,
148+ "--broker" ,
149+ default = DEFAULT_MQTT_BROKER_IP ,
150+ type = str ,
151+ help = "mqtt broker IP" ,
138152 )
139153 parser .add_argument (
140- "--port" , default = DEFAULT_MQTT_BROKER_PORT , type = int , help = "mqtt broker port" ,
154+ "--port" ,
155+ default = DEFAULT_MQTT_BROKER_PORT ,
156+ type = int ,
157+ help = "mqtt broker port" ,
141158 )
142159 parser .add_argument (
143160 "--topic" , default = DEFAULT_MQTT_TOPIC , type = str , help = "mqtt topic"
144161 )
162+ parser .add_argument (
163+ "--interval" ,
164+ default = DEFAULT_READ_INTERVAL ,
165+ type = int ,
166+ help = "the read interval in seconds" ,
167+ )
145168 args = parser .parse_args ()
146169
170+ # Raspberry Pi ID
171+ device_serial_number = get_serial_number ()
172+ device_id = "raspi-" + device_serial_number
173+
147174 print (
148- """mqtt-all.py - Reads temperature, pressure, humidity,
149- PM2.5, and PM10 from Enviro plus and sends data over mqtt.
175+ f"""mqtt-all.py - Reads Enviro plus data and sends over mqtt.
150176
151- broker: {}
152- port: {}
153- topic: {}
177+ broker: { args .broker }
178+ client_id: { device_id }
179+ port: { args .port }
180+ topic: { args .topic }
154181
155182 Press Ctrl+C to exit!
156183
157- """ .format (
158- args .broker , args .port , args .topic
159- )
184+ """
160185 )
161186
162- mqtt_client = mqtt .Client ()
187+ mqtt_client = mqtt .Client (client_id = device_id )
163188 mqtt_client .on_connect = on_connect
164189 mqtt_client .on_publish = on_publish
165190 mqtt_client .connect (args .broker , port = args .port )
@@ -177,33 +202,34 @@ def main():
177202 # Initialize display
178203 disp .begin ()
179204
180- # Create PMS5003 instance
181- pms5003 = PMS5003 ()
182-
183- # Raspberry Pi ID
184- device_serial_number = get_serial_number ()
185- id = "raspi-" + device_serial_number
205+ # Try to create PMS5003 instance
206+ HAS_PMS = False
207+ try :
208+ pms5003 = PMS5003 ()
209+ pm_values = pms5003 .read ()
210+ HAS_PMS = True
211+ print ("PMS5003 sensor is connected" )
212+ except SerialTimeoutError :
213+ print ("No PMS5003 sensor connected" )
186214
187215 # Display Raspberry Pi serial and Wi-Fi status
188- print ("Raspberry Pi serial: {}" .format (get_serial_number () ))
216+ print ("RPi serial: {}" .format (device_serial_number ))
189217 print ("Wi-Fi: {}\n " .format ("connected" if check_wifi () else "disconnected" ))
190218 print ("MQTT broker IP: {}" .format (args .broker ))
191219
192- time_since_update = 0
193- update_time = time .time ()
194-
195220 # Main loop to read data, display, and send over mqtt
196221 mqtt_client .loop_start ()
197222 while True :
198223 try :
199- time_since_update = time .time () - update_time
200- values = read_values (bme280 , pms5003 )
224+ values = read_bme280 (bme280 )
225+ if HAS_PMS :
226+ pms_values = read_pms5003 (pms5003 )
227+ values .update (pms_values )
201228 values ["serial" ] = device_serial_number
202229 print (values )
203230 mqtt_client .publish (args .topic , json .dumps (values ))
204- if time_since_update > 145 :
205- update_time = time .time ()
206231 display_status (disp , args .broker )
232+ time .sleep (args .interval )
207233 except Exception as e :
208234 print (e )
209235
0 commit comments