From e3bf80bbe84be8f85a15dd9fb12f1c4bd9781d20 Mon Sep 17 00:00:00 2001 From: Pierrick C Date: Wed, 25 Mar 2020 16:11:02 +0100 Subject: [PATCH] Move to umqtt.robust Add more info about device Freeze lib with mpy-cross Some code factorization --- code/config_template.py | 16 ++++---- code/lib/bme280_i2c.mpy | Bin 0 -> 4498 bytes code/lib/umqtt/robust.mpy | Bin 0 -> 596 bytes code/lib/umqtt/robust.py | 43 ++++++++++++++++++++ code/lib/umqtt/simple.mpy | Bin 0 -> 2499 bytes code/lib/{mqtt.py => umqtt/simple.py} | 45 +++++++++++---------- code/main.py | 54 +++++++++++++++++--------- 7 files changed, 110 insertions(+), 48 deletions(-) create mode 100644 code/lib/bme280_i2c.mpy create mode 100644 code/lib/umqtt/robust.mpy create mode 100644 code/lib/umqtt/robust.py create mode 100644 code/lib/umqtt/simple.mpy rename code/lib/{mqtt.py => umqtt/simple.py} (86%) diff --git a/code/config_template.py b/code/config_template.py index fd1e88e..5f2bfc8 100644 --- a/code/config_template.py +++ b/code/config_template.py @@ -1,15 +1,13 @@ """Fichier de configuration """ -CLIENT_ID = "" -ADAFRUIT_IO_HOST = "" -ADAFRUIT_IO_USERNAME = "" -ADAFRUIT_IO_KEY = "" +CLIENT_ID = "Test" +LOCATION = "On desk" -MQTT_HOST = "" +MQTT_HOST = "192.168.0.1" MQTT_PORT = 1883 -MQTT_USERNAME = "" -MQTT_PASSWD = "" +MQTT_USERNAME = "user" +MQTT_PASSWD = "passwd" -WIFI_SSID = "" -WIFI_PSK = "" +WIFI_SSID = "my_wifi_ssid" +WIFI_PSK = "my_wifi_wpa_key" diff --git a/code/lib/bme280_i2c.mpy b/code/lib/bme280_i2c.mpy new file mode 100644 index 0000000000000000000000000000000000000000..40963ea238d6a83b00a413cfe2b7297c747e118c GIT binary patch literal 4498 zcmb7HTTC0-86Mk!0f#VvcNP+o3}eDQtUVY*+N=b|CXjG3x81O+H25-rQ+!!_2t|t2 zGsY%F8>u|5s!C1O$G+HLAgC`JAP^qjS zNpYPBRug>`(Km_6EAw8z-T8BpN`1NMfX~yUynb~)Cl$+jp5&SGW2Gcl8klM5h0Gd%rDMp-xBCIcbp!od7gBPWd zl1O2sF;WpBBTR&j6h%IXT!Hb^$hAlZQAT`95frJSh--k@ktXF>8$l6etb)461$euQ zbI!W`oZH1JDT)jFrUjq|d4W|?E!>@1h;o4$mUae80Y2{P_^6>Fa}2W3k@}8;uZpKAmubzNL6EJe%}Hg;5Y%ryc@`^q0a8=A`SX#s;iD|V)O(uH=-|JM=SERm3Y%Q%|WC+(TXBQ zw23Cw&KjCv(9~ZoN;Kju&*VDMsF)Q0`DNr?&!2xeSx(gI6tKk9N`kFDzWF(qw_X6R zb{Cz3CXI1K_giTDw7>`GcG@oB=n27AvCE(>)u5Rv`lm#+LZhXm;}(3WWoQ_2s+{Oz zL{l@kFsUZXH6ic~;e$;t`+rC3%QVP`Gy!_5>((uMfF8RucxTWrSt|}rl%5IPwA*`r_@(#yW@q6^{mkYiVub!^ zKIlN-A~ieA)HgOZ!in9`-hdY)2EzEnZji4I z=EzDhlLD^bN3)7_L4Pc5Vf_?>$@A2>OgK#HBJ@Xh*KF4}>W1cq%v0Y)AThKQjx-nS zNQ375-4tQ@S##kYSrPkSsX#GOF|qdHFX@D#gxi>5sALSBNpdpsWO%UQ3#9?ry8zdN$`$zD6|K-D)50u#p74R7-Q%Bw{7<`hjFezX z-2eZH3;(ltP3q|B^vCJrr>EUcHx#1G012rWc0RlqQ2^>jno3s1KJ*kK{INVl8waEc1|-^IM5kmrbn+W8eopwk(dGfE$YoK7{gk3Du&B$MxUi_!s-qQZMx2*f9C4}u zIaQZp|0Cxjk_PRiT3?0!Gu6dHR5jWvDb)*5uwKW|#L}@;9+t=lH!n2%L@iI8G}*<6rUc)mX42halp$m0bfrCJXQFrz5If#?+A7d z@e8!nhtRk)$v{c!JX+{!U%<(`T4-N@_WA-I`y8&`7+Zp9sj1YItX`j*YKD#=sx31S z=0<5x0wHUCq`3jpEvl&YV+~GB zrq*L19GI|vfO#&19IoXl$=uuKnQANy;RmD^z=Dd4bkXiyMj|p zE51ZETAfr87glhcXd}y|I&oer3URI2KX`lCqS|ILycj z$E%f-?IW@*T^Qug!V)zaSFYGdkmE0oslyLy1GVg}d7;Nq7>V4gRs_-gfq?J5#(j z+c@wSr)cXqT}_@IZl~gX2=U%d#rqKAZC0YS!)>X7kOFRV7qbRqhq1HGWbAxKeD#y| zs+W04ZGCY6;eFe~hhrm_(dIg)`F?L5#C`cCu@kMRV#4ox zzV`LRethF>^9+jv5+EoC>vAPif?0vRWzhgpfI9#bmOqsQKplqrn{rivCj{qILf_t2 z9FAJDpL%2DCHFV76by;ghL@(by5H zIIxKXs1i@WQ#dJbMWmt!j=TUTE<6E8Y^#kpt!6ay`~7E|5oS#uYq=D}gkgVwgIp65oc)g>5>`J`iY2R7M2c|a=&BcoLXUTW&C);-%IJvYOOY>mZ8Hvvs*xpfq? zw@NB`8+*@vxCD@aD;O}(VpyJFPQCx|uAv2Q{qch;VD1I6J4aQ7qjvwmlNp4CAu;>C z9x+{wZZMC$br#{&V6<;r&Pz{TLYRNmvD|joIq*z~JTIi;85##6D{+oZ$iNdt1sQ%8 zfMdoQtDBOTpvh~cCU|02U7=I;G8N!;k)8dmA)}rM3ZCyCy6zphJPezbRhpGsF}L0EL6-Z%()^RD84Tg{{XiEomKz< literal 0 HcmV?d00001 diff --git a/code/lib/umqtt/robust.py b/code/lib/umqtt/robust.py new file mode 100644 index 0000000..7ee40e0 --- /dev/null +++ b/code/lib/umqtt/robust.py @@ -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() diff --git a/code/lib/umqtt/simple.mpy b/code/lib/umqtt/simple.mpy new file mode 100644 index 0000000000000000000000000000000000000000..773e62ec7bbba75da02b96d60220c5883d2df9b6 GIT binary patch literal 2499 zcmZuzOK%(36}~eh^{^#n$Qg`D$*P&5Owt@mR4ImbokdiNZ3UzT#K=tSI0!+G#`aVr zlHpL6voLgLBtK*nMHXFlkwt)Phfgu?rhdt;R}HeL83chBQ8tAkRllI;4n-*{EC{%F z&YXMZ-tYU)cX`1UG-au%$`i%UgTc8x!l{v=Wvw7B%4L3_Gj>Ad(y~NC z)`*#*>+(%ix%zpC8gVV>lzdi`6y>Cir!HTNB4+qP>f*)U-IU~FSt;b5Xe&k6SsZ8Ovb4co(rQ;&-@hPkuys1u8bz<7c#KbC=CxKS-O!?<$Tn}yEVC-k+Q0q z%SwxLI7H7++4*4-RI^$+v!bZ#2O(;H%E1pwg?wI?%F!O4TTry_Q!n3FRPxt4OZ)ht z;&M(^wCk8G>gQeBa!!*Rn{A zJ`R25+7}GhR|Lcv``fcFv{;EzaXL<2HrZZCslcpLjMnsTFh>Bk2!I^vlssl3)C1TI zbg<|FaK1RXM}68=4U5l)-w^};so?B{KXg76m>iD;&Y!;^_`+l1F=|1JMar`wvcwwQWT4F1}OTu!K#JaJ4p|Q#so4o^>K~k zS4!Dprc(&A=1ulDXDQQdbD?P;9iyI*(H5hg-Z%Du0FymbQ;gc%s_46oJ0F^?C5_aN z-zCRz)3EX=c)h>G(hEFpZ#C{*N(=h*t1GbNP(8^oHd#to$LQbt=r!(MN<--0e<8DR z&zcMR>W;N;Jo(!pN?^uc3fJMp6U53*p`K$XCv!av^b|t5emk*AJ7nm69_APRGmfu@p|kqoAU?|4ADrnAaRd!SLAf0L z3Vq@kvMkDh{{)$iZe};(A86yc{#WXcUFUM(rC@l{KQ^&1&7faA9SMtmZy*Tz4Eck8 zM6}}o?KJSEbY0)A5h{o}ppA)`sxWNT@ynzg2;JUl3OYWNz)_kSZ=eZcoozNYb&Dp> zNgRO`6tVdcOT0_p{@6_cf6ou>#6|2RqvXp4;wcT>irazU*=qWFy3AQJxn;zu7Y}gy-tGfE{rW}gK|4v~l$7}UYGM%A zjW)P5v55p+mllt2bcCFJl8{N!ch3EX3LV}J9{fc#D1IsiV*v8|=R#+IC$MG^+DsoQ zOBz)spxa~AV?e-T9pB~QJWS8qiP@TNSRF~=*Z063;|@6b2{?L-3i z=?q%xxGgslM^Ea4&a{)~_RkLTecI5|H6z_l9>WbIU0X|cfoQBjlcP2faRBD9Cjg)c zK1+l<>d{8$yO*7}d!u?4&6_Wjy>OxC>;@cu!~WT9{|WrHDEfs!ATS;h#zY|i*5~(& zp)v7HFc_H#!tsGP!ox!XK2KJwV2NaVyfy6;#&rEKlu?eDsd{D+|pwRN#=dKZMgz>eErln2Nvn@DI s;w=n`>qjJHBfSes`B%<94d@m<%;66PCw?IULJrP3XVJ^XkwlRFA0l@*B>(^b literal 0 HcmV?d00001 diff --git a/code/lib/mqtt.py b/code/lib/umqtt/simple.py similarity index 86% rename from code/lib/mqtt.py rename to code/lib/umqtt/simple.py index d6e5102..8216fa5 100644 --- a/code/lib/mqtt.py +++ b/code/lib/umqtt/simple.py @@ -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 ustruct as struct from ubinascii import hexlify @@ -21,7 +13,8 @@ class MQTTClient: port = 8883 if ssl else 1883 self.client_id = client_id self.sock = None - self.addr = socket.getaddrinfo(server, port)[0][-1] + self.server = server + self.port = port self.ssl = ssl self.ssl_params = ssl_params self.pid = 0 @@ -61,24 +54,36 @@ class MQTTClient: def connect(self, clean_session=True): 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: import ussl self.sock = ussl.wrap_socket(self.sock, **self.ssl_params) - msg = bytearray(b"\x10\0\0\x04MQTT\x04\x02\0\0") - msg[1] = 10 + 2 + len(self.client_id) - msg[9] = clean_session << 1 + premsg = bytearray(b"\x10\0\0\0\0\0") + msg = bytearray(b"\x04MQTT\x04\x02\0\0") + + sz = 10 + 2 + len(self.client_id) + msg[6] = clean_session << 1 if self.user is not None: - msg[1] += 2 + len(self.user) + 2 + len(self.pswd) - msg[9] |= 0xC0 + sz += 2 + len(self.user) + 2 + len(self.pswd) + msg[6] |= 0xC0 if self.keepalive: assert self.keepalive < 65536 - msg[10] |= self.keepalive >> 8 - msg[11] |= self.keepalive & 0x00FF + msg[7] |= self.keepalive >> 8 + msg[8] |= self.keepalive & 0x00FF if self.lw_topic: - msg[1] += 2 + len(self.lw_topic) + 2 + len(self.lw_msg) - msg[9] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3 - msg[9] |= self.lw_retain << 5 + sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg) + msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3 + 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) #print(hex(len(msg)), hexlify(msg, ":")) self._send_str(self.client_id) diff --git a/code/main.py b/code/main.py index 15bd1bd..05103d4 100644 --- a/code/main.py +++ b/code/main.py @@ -1,12 +1,13 @@ """Station météo connectée au service Adafruit IO """ - import time import machine import network +import esp import bme280_i2c -from mqtt import MQTTClient +from ntptime import settime +from umqtt.robust import MQTTClient import config # connect to WLAN @@ -44,6 +45,15 @@ bme.set_measurement_settings({ 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, server=config.MQTT_HOST, user=config.MQTT_USERNAME, @@ -51,34 +61,40 @@ client = MQTTClient(client_id=config.CLIENT_ID, port=config.MQTT_PORT) client.connect() -client.publish("test/bme280/humidity/unit", "%", retain=True, qos=0) -client.publish("test/bme280/humidity/desc", "Capteur Bosch BME280", retain=True, qos=0) -time.sleep_ms(100) -client.publish("test/bme280/pressure/unit", "hPa", retain=True, qos=0) -client.publish("test/bme280/pressure/desc", "Capteur Bosch BME280", retain=True, qos=0) -time.sleep_ms(100) -client.publish("test/bme280/temperature/unit", "degC", retain=True, qos=0) -client.publish("test/bme280/temperature/desc", "Capteur Bosch BME280", retain=True, qos=0) -time.sleep_ms(100) -client.publish("test/esp8266_0/wifi/ssid", config.WIFI_SSID, retain=True, qos=0) -client.publish("test/esp8266_0/wifi/ip", wlan.ifconfig()[0], retain=True, qos=0) +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, "temperature/unit", "degC", retain=True, qos=0) +MqttPublish(client, "temperature/desc", "Capteur Bosch BME280", 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=0) +MqttPublish(client, "wifi/channel", "{:d}".format(net[2]), retain=True, qos=0) +MqttPublish(client, "sys/esp8266_device_id", "{:d}".format(esp.flash_id()), retain=True, qos=0) + time.sleep_ms(1000) -# For each nature, a list describe: +# For each nature, a list describes: # - mqtt topic # - string format # - factor (multiplier) -topics = {"humidity" : ["test/esp8266_0/humidity/value", "{:.0f}", 1], - "pressure" : ["test/esp8266_0/pressure/value", "{:.2f}", 0.01], - "temperature" : ["test/esp8266_0/temperature/value", "{:.1f}", 1]} +# - qos +topics = {"humidity" : ["humidity/value", "{:.0f}", 1, 1], + "pressure" : ["pressure/value", "{:.2f}", 0.01, 1], + "temperature" : ["temperature/value", "{:.1f}", 1, 1]} while 1: bme_data = bme.get_measurement() print(bme_data) 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)