Move to umqtt.robust

Add more info about device
Freeze lib with mpy-cross
Some code factorization
This commit is contained in:
Pierrick C 2020-03-25 16:11:02 +01:00
parent 1bbfad291a
commit e3bf80bbe8
7 changed files with 110 additions and 48 deletions

View File

@ -1,15 +1,13 @@
"""Fichier de configuration """Fichier de configuration
""" """
CLIENT_ID = ""
ADAFRUIT_IO_HOST = "" CLIENT_ID = "Test"
ADAFRUIT_IO_USERNAME = "" LOCATION = "On desk"
ADAFRUIT_IO_KEY = ""
MQTT_HOST = "" MQTT_HOST = "192.168.0.1"
MQTT_PORT = 1883 MQTT_PORT = 1883
MQTT_USERNAME = "" MQTT_USERNAME = "user"
MQTT_PASSWD = "" MQTT_PASSWD = "passwd"
WIFI_SSID = "" WIFI_SSID = "my_wifi_ssid"
WIFI_PSK = "" WIFI_PSK = "my_wifi_wpa_key"

BIN
code/lib/bme280_i2c.mpy Normal file

Binary file not shown.

BIN
code/lib/umqtt/robust.mpy Normal file

Binary file not shown.

43
code/lib/umqtt/robust.py Normal file
View File

@ -0,0 +1,43 @@
import utime
from . import simple
class MQTTClient(simple.MQTTClient):
DELAY = 2
DEBUG = False
def delay(self, i):
utime.sleep(self.DELAY)
def log(self, in_reconnect, e):
if self.DEBUG:
if in_reconnect:
print("mqtt reconnect: %r" % e)
else:
print("mqtt: %r" % e)
def reconnect(self):
i = 0
while 1:
try:
return super().connect(False)
except OSError as e:
self.log(True, e)
i += 1
self.delay(i)
def publish(self, topic, msg, retain=False, qos=0):
while 1:
try:
return super().publish(topic, msg, retain, qos)
except OSError as e:
self.log(False, e)
self.reconnect()
def wait_msg(self):
while 1:
try:
return super().wait_msg()
except OSError as e:
self.log(False, e)
self.reconnect()

BIN
code/lib/umqtt/simple.mpy Normal file

Binary file not shown.

View File

@ -1,11 +1,3 @@
# Copyright (c) 2019, Pycom Limited.
#
# This software is licensed under the GNU GPL version 3 or any
# later version, with permitted additional terms. For more information
# see the Pycom Licence v1.0 document supplied with this file, or
# available at https://www.pycom.io/opensource/licensing
#
import usocket as socket import usocket as socket
import ustruct as struct import ustruct as struct
from ubinascii import hexlify from ubinascii import hexlify
@ -21,7 +13,8 @@ class MQTTClient:
port = 8883 if ssl else 1883 port = 8883 if ssl else 1883
self.client_id = client_id self.client_id = client_id
self.sock = None self.sock = None
self.addr = socket.getaddrinfo(server, port)[0][-1] self.server = server
self.port = port
self.ssl = ssl self.ssl = ssl
self.ssl_params = ssl_params self.ssl_params = ssl_params
self.pid = 0 self.pid = 0
@ -61,24 +54,36 @@ class MQTTClient:
def connect(self, clean_session=True): def connect(self, clean_session=True):
self.sock = socket.socket() self.sock = socket.socket()
self.sock.connect(self.addr) addr = socket.getaddrinfo(self.server, self.port)[0][-1]
self.sock.connect(addr)
if self.ssl: if self.ssl:
import ussl import ussl
self.sock = ussl.wrap_socket(self.sock, **self.ssl_params) self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
msg = bytearray(b"\x10\0\0\x04MQTT\x04\x02\0\0") premsg = bytearray(b"\x10\0\0\0\0\0")
msg[1] = 10 + 2 + len(self.client_id) msg = bytearray(b"\x04MQTT\x04\x02\0\0")
msg[9] = clean_session << 1
sz = 10 + 2 + len(self.client_id)
msg[6] = clean_session << 1
if self.user is not None: if self.user is not None:
msg[1] += 2 + len(self.user) + 2 + len(self.pswd) sz += 2 + len(self.user) + 2 + len(self.pswd)
msg[9] |= 0xC0 msg[6] |= 0xC0
if self.keepalive: if self.keepalive:
assert self.keepalive < 65536 assert self.keepalive < 65536
msg[10] |= self.keepalive >> 8 msg[7] |= self.keepalive >> 8
msg[11] |= self.keepalive & 0x00FF msg[8] |= self.keepalive & 0x00FF
if self.lw_topic: if self.lw_topic:
msg[1] += 2 + len(self.lw_topic) + 2 + len(self.lw_msg) sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg)
msg[9] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3 msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3
msg[9] |= self.lw_retain << 5 msg[6] |= self.lw_retain << 5
i = 1
while sz > 0x7f:
premsg[i] = (sz & 0x7f) | 0x80
sz >>= 7
i += 1
premsg[i] = sz
self.sock.write(premsg, i + 2)
self.sock.write(msg) self.sock.write(msg)
#print(hex(len(msg)), hexlify(msg, ":")) #print(hex(len(msg)), hexlify(msg, ":"))
self._send_str(self.client_id) self._send_str(self.client_id)

View File

@ -1,12 +1,13 @@
"""Station météo connectée au service Adafruit IO """Station météo connectée au service Adafruit IO
""" """
import time import time
import machine import machine
import network import network
import esp
import bme280_i2c import bme280_i2c
from mqtt import MQTTClient from ntptime import settime
from umqtt.robust import MQTTClient
import config import config
# connect to WLAN # connect to WLAN
@ -44,6 +45,15 @@ bme.set_measurement_settings({
bme.set_power_mode(bme280_i2c.BME280_NORMAL_MODE) bme.set_power_mode(bme280_i2c.BME280_NORMAL_MODE)
def MqttPublish(client, topic, message, retain=False, qos=0, sleep=10):
"""MQTT publish helper"""
client.publish("test/{device}/{topic}".format(device=config.CLIENT_ID, topic=topic),
message,
retain=retain,
qos=qos)
time.sleep_ms(sleep)
client = MQTTClient(client_id=config.CLIENT_ID, client = MQTTClient(client_id=config.CLIENT_ID,
server=config.MQTT_HOST, server=config.MQTT_HOST,
user=config.MQTT_USERNAME, user=config.MQTT_USERNAME,
@ -51,34 +61,40 @@ client = MQTTClient(client_id=config.CLIENT_ID,
port=config.MQTT_PORT) port=config.MQTT_PORT)
client.connect() client.connect()
client.publish("test/bme280/humidity/unit", "%", retain=True, qos=0) MqttPublish(client, "location", config.LOCATION, retain=True, qos=1)
client.publish("test/bme280/humidity/desc", "Capteur Bosch BME280", retain=True, qos=0) MqttPublish(client, "humidity/unit", "%", retain=True)
time.sleep_ms(100) MqttPublish(client, "humidity/desc", "Capteur Bosch BME280", retain=True, qos=0)
client.publish("test/bme280/pressure/unit", "hPa", retain=True, qos=0) MqttPublish(client, "pressure/unit", "hPa", retain=True, qos=0)
client.publish("test/bme280/pressure/desc", "Capteur Bosch BME280", retain=True, qos=0) MqttPublish(client, "pressure/desc", "Capteur Bosch BME280", retain=True, qos=0)
time.sleep_ms(100) MqttPublish(client, "temperature/unit", "degC", retain=True, qos=0)
client.publish("test/bme280/temperature/unit", "degC", retain=True, qos=0) MqttPublish(client, "temperature/desc", "Capteur Bosch BME280", retain=True, qos=0)
client.publish("test/bme280/temperature/desc", "Capteur Bosch BME280", retain=True, qos=0) MqttPublish(client, "wifi/ssid", config.WIFI_SSID, retain=True, qos=0)
time.sleep_ms(100) MqttPublish(client, "wifi/ip", wlan.ifconfig()[0], retain=True, qos=0)
client.publish("test/esp8266_0/wifi/ssid", config.WIFI_SSID, retain=True, qos=0) MqttPublish(client, "wifi/channel", "{:d}".format(net[2]), retain=True, qos=0)
client.publish("test/esp8266_0/wifi/ip", wlan.ifconfig()[0], retain=True, qos=0) MqttPublish(client, "sys/esp8266_device_id", "{:d}".format(esp.flash_id()), retain=True, qos=0)
time.sleep_ms(1000) time.sleep_ms(1000)
# For each nature, a list describe: # For each nature, a list describes:
# - mqtt topic # - mqtt topic
# - string format # - string format
# - factor (multiplier) # - factor (multiplier)
topics = {"humidity" : ["test/esp8266_0/humidity/value", "{:.0f}", 1], # - qos
"pressure" : ["test/esp8266_0/pressure/value", "{:.2f}", 0.01], topics = {"humidity" : ["humidity/value", "{:.0f}", 1, 1],
"temperature" : ["test/esp8266_0/temperature/value", "{:.1f}", 1]} "pressure" : ["pressure/value", "{:.2f}", 0.01, 1],
"temperature" : ["temperature/value", "{:.1f}", 1, 1]}
while 1: while 1:
bme_data = bme.get_measurement() bme_data = bme.get_measurement()
print(bme_data) print(bme_data)
for nature, param in topics.items(): for nature, param in topics.items():
client.publish(param[0], param[1].format(bme_data[nature]*param[2])) MqttPublish(client,
param[0],
param[1].format(bme_data[nature]*param[2]),
qos=param[3],
sleep=50)
client.publish("test/esp8266_0/wifi/rssi", "{:.0f}".format(wlan.status('rssi'))) MqttPublish(client, "wifi/rssi", "{:.0f}".format(wlan.status('rssi')))
time.sleep_ms(1000) time.sleep_ms(1000)