From: Philip Howard Date: Wed, 28 Oct 2020 15:44:52 +0000 (+0000) Subject: Merge pull request #75 from tijmenvandenbrink/master X-Git-Url: https://zdv2.bktei.com/gitweb/EVA-2020-02-2.git/commitdiff_plain/744cecb38459b605949321bf74aa47a95d19c4a7?hp=1d82eac50317410ae4dbbbccbde8cdf65e5d0ba6 Merge pull request #75 from tijmenvandenbrink/master Added user project: enviroplus_exporter --- diff --git a/examples/combined.py b/examples/combined.py index b417ccf..6c4ab6f 100755 --- a/examples/combined.py +++ b/examples/combined.py @@ -26,7 +26,7 @@ logging.basicConfig( level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S') -logging.info("""all-in-one.py - Displays readings from all of Enviro plus' sensors +logging.info("""combined.py - Displays readings from all of Enviro plus' sensors Press Ctrl+C to exit! @@ -172,7 +172,7 @@ def display_everything(): variable = variables[i] data_value = values[variable][-1] unit = units[i] - x = x_offset + ((WIDTH / column_count) * (i / row_count)) + x = x_offset + ((WIDTH // column_count) * (i // row_count)) y = y_offset + ((HEIGHT / row_count) * (i % row_count)) message = "{}: {:.1f} {}".format(variable[:4], data_value, unit) lim = limits[i] diff --git a/examples/mqtt-all.py b/examples/mqtt-all.py index 26f46bb..0eff47a 100755 --- a/examples/mqtt-all.py +++ b/examples/mqtt-all.py @@ -9,7 +9,7 @@ import argparse import ST7735 import time from bme280 import BME280 -from pms5003 import PMS5003, ReadTimeoutError +from pms5003 import PMS5003, ReadTimeoutError, SerialTimeoutError from enviroplus import gas try: @@ -37,10 +37,10 @@ except ImportError: DEFAULT_MQTT_BROKER_IP = "localhost" DEFAULT_MQTT_BROKER_PORT = 1883 DEFAULT_MQTT_TOPIC = "enviroplus" +DEFAULT_READ_INTERVAL = 5 # mqtt callbacks def on_connect(client, userdata, flags, rc): - print(f"CONNACK received with code {rc}") if rc == 0: print("connected OK") else: @@ -51,11 +51,10 @@ def on_publish(client, userdata, mid): print("mid: " + str(mid)) -# Read values from BME280 and PMS5003 and return as dict -def read_values(bme280, pms5003): +# Read values from BME280 and return as dict +def read_bme280(bme280): # Compensation factor for temperature comp_factor = 2.25 - values = {} cpu_temp = get_cpu_temperature() raw_temp = bme280.get_temperature() # float @@ -65,6 +64,17 @@ def read_values(bme280, pms5003): int(bme280.get_pressure() * 100), -1 ) # round to nearest 10 values["humidity"] = int(bme280.get_humidity()) + data = gas.read_all() + values["oxidised"] = int(data.oxidising / 1000) + values["reduced"] = int(data.reducing / 1000) + values["nh3"] = int(data.nh3 / 1000) + values["lux"] = int(ltr559.get_lux()) + return values + + +# Read values PMS5003 and return as dict +def read_pms5003(pms5003): + values = {} try: pm_values = pms5003.read() # int values["pm1"] = pm_values.pm_ug_per_m3(1) @@ -76,17 +86,14 @@ def read_values(bme280, pms5003): values["pm1"] = pm_values.pm_ug_per_m3(1) values["pm25"] = pm_values.pm_ug_per_m3(2.5) values["pm10"] = pm_values.pm_ug_per_m3(10) - data = gas.read_all() - values["oxidised"] = int(data.oxidising / 1000) - values["reduced"] = int(data.reducing / 1000) - values["nh3"] = int(data.nh3 / 1000) - values["lux"] = int(ltr559.get_lux()) return values # Get CPU temperature to use for compensation def get_cpu_temperature(): - process = Popen(["vcgencmd", "measure_temp"], stdout=PIPE, universal_newlines=True) + process = Popen( + ["vcgencmd", "measure_temp"], stdout=PIPE, universal_newlines=True + ) output, _error = process.communicate() return float(output[output.index("=") + 1 : output.rindex("'")]) @@ -113,14 +120,16 @@ def display_status(disp, mqtt_broker): WIDTH = disp.width HEIGHT = disp.height # Text settings - font_size = 16 + font_size = 12 font = ImageFont.truetype(UserFont, font_size) wifi_status = "connected" if check_wifi() else "disconnected" text_colour = (255, 255, 255) back_colour = (0, 170, 170) if check_wifi() else (85, 15, 15) - id = get_serial_number() - message = "{}\nWi-Fi: {}\nmqtt-broker: {}".format(id, wifi_status, mqtt_broker) + device_serial_number = get_serial_number() + message = "{}\nWi-Fi: {}\nmqtt-broker: {}".format( + device_serial_number, wifi_status, mqtt_broker + ) img = Image.new("RGB", (WIDTH, HEIGHT), color=(0, 0, 0)) draw = ImageDraw.Draw(img) size_x, size_y = draw.textsize(message, font) @@ -132,34 +141,50 @@ def display_status(disp, mqtt_broker): def main(): - parser = argparse.ArgumentParser(description="Publish enviroplus values over mqtt") + parser = argparse.ArgumentParser( + description="Publish enviroplus values over mqtt" + ) parser.add_argument( - "--broker", default=DEFAULT_MQTT_BROKER_IP, type=str, help="mqtt broker IP", + "--broker", + default=DEFAULT_MQTT_BROKER_IP, + type=str, + help="mqtt broker IP", ) parser.add_argument( - "--port", default=DEFAULT_MQTT_BROKER_PORT, type=int, help="mqtt broker port", + "--port", + default=DEFAULT_MQTT_BROKER_PORT, + type=int, + help="mqtt broker port", ) parser.add_argument( "--topic", default=DEFAULT_MQTT_TOPIC, type=str, help="mqtt topic" ) + parser.add_argument( + "--interval", + default=DEFAULT_READ_INTERVAL, + type=int, + help="the read interval in seconds", + ) args = parser.parse_args() + # Raspberry Pi ID + device_serial_number = get_serial_number() + device_id = "raspi-" + device_serial_number + print( - """mqtt-all.py - Reads temperature, pressure, humidity, - PM2.5, and PM10 from Enviro plus and sends data over mqtt. + f"""mqtt-all.py - Reads Enviro plus data and sends over mqtt. - broker: {} - port: {} - topic: {} + broker: {args.broker} + client_id: {device_id} + port: {args.port} + topic: {args.topic} Press Ctrl+C to exit! - """.format( - args.broker, args.port, args.topic - ) + """ ) - mqtt_client = mqtt.Client() + mqtt_client = mqtt.Client(client_id=device_id) mqtt_client.on_connect = on_connect mqtt_client.on_publish = on_publish mqtt_client.connect(args.broker, port=args.port) @@ -177,33 +202,34 @@ def main(): # Initialize display disp.begin() - # Create PMS5003 instance - pms5003 = PMS5003() - - # Raspberry Pi ID - device_serial_number = get_serial_number() - id = "raspi-" + device_serial_number + # Try to create PMS5003 instance + HAS_PMS = False + try: + pms5003 = PMS5003() + pm_values = pms5003.read() + HAS_PMS = True + print("PMS5003 sensor is connected") + except SerialTimeoutError: + print("No PMS5003 sensor connected") # Display Raspberry Pi serial and Wi-Fi status - print("Raspberry Pi serial: {}".format(get_serial_number())) + print("RPi serial: {}".format(device_serial_number)) print("Wi-Fi: {}\n".format("connected" if check_wifi() else "disconnected")) print("MQTT broker IP: {}".format(args.broker)) - time_since_update = 0 - update_time = time.time() - # Main loop to read data, display, and send over mqtt mqtt_client.loop_start() while True: try: - time_since_update = time.time() - update_time - values = read_values(bme280, pms5003) + values = read_bme280(bme280) + if HAS_PMS: + pms_values = read_pms5003(pms5003) + values.update(pms_values) values["serial"] = device_serial_number print(values) mqtt_client.publish(args.topic, json.dumps(values)) - if time_since_update > 145: - update_time = time.time() display_status(disp, args.broker) + time.sleep(args.interval) except Exception as e: print(e) diff --git a/examples/weather-and-light.py b/examples/weather-and-light.py index bccf7cc..cd8ae96 100755 --- a/examples/weather-and-light.py +++ b/examples/weather-and-light.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +f"Sorry! This program requires Python >= 3.6 😅" import os import time diff --git a/install.sh b/install.sh index 3e5b898..6837697 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/bin/bash CONFIG=/boot/config.txt -DATESTAMP=`date "+%Y-%M-%d-%H-%M-%S"` +DATESTAMP=`date "+%Y-%m-%d-%H-%M-%S"` CONFIG_BACKUP=false APT_HAS_UPDATED=false USER_HOME=/home/$SUDO_USER