""" Station météo connectée vers MQTT via wifi. A bit longer description. Args: variable (type): description Returns: type: description Raises: Exception: description """ import time import machine import network import esp import bme280_i2c import adafruit_max31865 from ntptime import settime from umqtt.robust import MQTTClient import config def WifiConnect(ssid, psk): """Connect to the wifi with given credentials.""" wlan = network.WLAN(network.STA_IF) wlan.active(True) nets = wlan.scan() for net in nets: net_ssid = net[0].decode() if net_ssid == ssid: print('Network found!') wlan.connect(net_ssid, psk) while not wlan.isconnected(): machine.idle() # save power while waiting print('WLAN connection succeeded!') break if not wlan.isconnected(): print("WLAN not found/not connected") return wlan def now(rtc): """Return a string representing date/time now.""" return "{0:04d}/{1:02d}/{2:02d}_{4:02d}:{5:02d}:{6:02d}".format( *rtc.datetime() ) def MqttPublish(client, topic, message, retain=False, qos=0, sleep=10): """MQTT publish helper.""" client.publish("test/{device}/{topic}".format(device=client.client_id, topic=topic), message, retain=retain, qos=qos) time.sleep_ms(sleep) # Connect to WLAN wlan = WifiConnect(config.WIFI_SSID, config.WIFI_PSK) # Create a micropython I2C object with the appropriate device pins i2c = machine.I2C(scl=machine.Pin(5), sda=machine.Pin(4)) # Create a sensor object to represent the BME280 # Note that this will error if the device can't be reached over I2C. bme = bme280_i2c.BME280_I2C(address=bme280_i2c.BME280_I2C_ADDR_SEC, i2c=i2c) # Configure the sensor for the application in question. bme.set_measurement_settings({ 'filter': bme280_i2c.BME280_FILTER_COEFF_16, 'standby_time': bme280_i2c.BME280_STANDBY_TIME_500_US, 'osr_h': bme280_i2c.BME280_OVERSAMPLING_1X, 'osr_p': bme280_i2c.BME280_OVERSAMPLING_16X, 'osr_t': bme280_i2c.BME280_OVERSAMPLING_2X }) # Start the sensor automatically sensing bme.set_power_mode(bme280_i2c.BME280_NORMAL_MODE) # Conversion coeff. between measured pressure and Seau Mean-level pressure # Source: https://fr.wikipedia.org/wiki/Pression-altitude SMLP_coef = pow(1.0-((0.0065*config.ALTITUDE)/288.15), 5.255) # PT100 (via max81865 module) sensor setup spi = machine.SPI( -1, sck=machine.Pin(14, machine.Pin.OUT), mosi=machine.Pin(13, machine.Pin.OUT), miso=machine.Pin(12, machine.Pin.OUT) ) spi.init(baudrate=115200, polarity=0, phase=1) max31865_cs = machine.Pin(2) max31865 = adafruit_max31865.MAX31865(spi, max31865_cs) # RTC setup rtc = machine.RTC() settime() client = MQTTClient(client_id=config.CLIENT_ID, server=config.MQTT_HOST, user=config.MQTT_USERNAME, password=config.MQTT_PASSWD, port=config.MQTT_PORT) client.DEBUG = True client.connect() MqttPublish(client, "last_boot", now(rtc), retain=True, qos=1) MqttPublish(client, "location", config.LOCATION, retain=True, qos=1) MqttPublish(client, "humidity/unit", "%", retain=True) MqttPublish(client, "humidity/desc", "Capteur Bosch BME280", retain=True, qos=0) MqttPublish(client, "pressure/unit", "hPa", retain=True, qos=0) MqttPublish(client, "pressure/desc", "Capteur Bosch BME280", retain=True, qos=0) MqttPublish(client, "pressure2/unit", "hPa", retain=True, qos=0) MqttPublish(client, "pressure2/desc", "Capteur Bosch BME280 revenu au niveau de la mer", retain=True, qos=0) MqttPublish(client, "temperature/unit", "degC", retain=True, qos=0) MqttPublish(client, "temperature/desc", "Capteur Bosch BME280", retain=True, qos=0) MqttPublish(client, "temperature2/unit", "degC", retain=True, qos=0) MqttPublish(client, "temperature2/desc", "Sonde PT100/MAX31865", retain=True, qos=0) MqttPublish(client, "wifi/ssid", config.WIFI_SSID, retain=True, qos=0) MqttPublish(client, "wifi/ip", wlan.ifconfig()[0], retain=True, qos=1) MqttPublish(client, "sys/esp8266_device_id", "{:d}".format(esp.flash_id()), retain=True, qos=1) time.sleep_ms(1000) # For each nature, a list describes: # - mqtt topic # - string format # - factor (multiplier) # - qos topics = {"time": ["time/last_values", "{}", 1, 1], "humidity": ["humidity/value", "{:.0f}", 1, 0], "pressure": ["pressure/value", "{:.2f}", 0.01, 0], "pressure2": ["pressure2/value", "{:.2f}", 0.01, 0], "temperature": ["temperature/value", "{:.1f}", 1, 0], "temperature2": ["temperature/value2", "{:.1f}", 1, 0], "wifi_rssi": ["wifi/rssi", "{:.0f}", 1, 0], } while 1: bme_data = bme.get_measurement() bme_data['time'] = now(rtc) bme_data['pressure2'] = bme_data['pressure']/SMLP_coef bme_data['temperature2'] = max31865.temperature bme_data['wifi_rssi'] = wlan.status('rssi') print(bme_data) for nature, param in topics.items(): MqttPublish(client, param[0], param[1].format(bme_data[nature]*param[2]), qos=param[3], sleep=20) time.sleep(config.REFRESH_RATE)