Giter VIP home page Giter VIP logo

micropython-umqtt.simple2's Introduction

umqtt.simple2

umqtt.simple2 is a MQTT client for MicroPython. (Note that it uses some MicroPython shortcuts and doesn't work with CPython).

Support MQTT Version 3.1.1 only.

It certainly works with micropython ports: esp8266 and esp32. It should also work with other ports, but the library was not tested under other ports.

Port Version Normal SSL
esp8266 1.9.1 OK Test fails
esp32 1.9.1 OK OK

MQTT client with more features

There's a separate umqtt.robust2 module which builds on umqtt.simple2 adds the ability to reconnect. It is able to send unsent messages itself. And many more...

Differences between umqtt.simple and umqtt.simple2

  • When sending messages from QoS=1, there is no problem with "suspending" the script while waiting for confirmation of message receipt by the server.
  • When subscribing to a channel, there is no problem with "suspending" the script while waiting for confirmation of the subscription by the server.
  • Information about receiving or failing to receive a message from QoS=1 or subscription can only be received by registering a callback using the set_callback_status() method.
  • Currently, the module informs about errors in more detailed way. See the umqtt/errno.py file.
  • The application should also not hang up when using check_msg()
  • The code compiled for MPY files, is about 30% larger than the original one. So this library has gained more functionality (maybe reliability), but this was done at the expense of the amount of code.

Problems and solutions

  • ImportError: no module named 'umqtt.simple2'

    Versions of micropython from http://micropython.org/download/ since version 1.12 include the umqtt library, which conflicts with the current library. To avoid conflicts, you need to change the order of importing libraries. You need to import the '/lib' libraries first and then the system libraries. Just add the following lines of code to the boot.py file:

import sys
sys.path.reverse()

How and where to install this code?

You can install using the upip:

import upip
upip.install("micropython-umqtt.simple2")

or

micropython -m upip install -p modules micropython-umqtt.simple2

You can also clone this repository, and install it manually:

git clone https://github.com/fizista/micropython-umqtt.simple2.git

Manual installation gives you more possibilities:

  • You can compile this library into MPY files using the compile.sh script.
  • You can remove comments from the code with the command: python setup.py minify
  • You can of course copy the code as it is, if you don't mind.

Please note that the PyPi repositories contain optimized code (no comments).

Design requirements

  • Memory efficiency.
  • Avoid infamous design anti-patterns like "callback hell".
  • Support for both publishing and subscription via a single client object (another alternative would be to have separate client classes for publishing and subscription).

API design

Based on the requirements above, there are following API traits:

  • All data related to MQTT messages is encoded as bytes. This includes both message content AND topic names (even though MQTT spec states that topic name is UTF-8 encoded). The reason for this is simple: what is received over network socket is binary data (bytes) and it would require extra step to convert that to a string, spending memory on that. Note that this applies only to topic names (because they can be both sent and received). Other parameters specified by MQTT as UTF-8 encoded (e.g. ClientID) are accepted as strings.
  • Subscribed messages are delivered via a callback. This is to avoid using a queue for subscribed messages, as otherwise they may be received at any time (including when client expects other type of server response, so there're 2 choices: either deliver them immediately via a callback or queue up until an "expected" response arrives). Note that lack of need for a queue is delusive: the runtime call stack forms an implicit queue in this case. And unlike explicit queue, it's much harder to control. This design was chosen because in a common case of processing subscribed messages it's the most efficient. However, if in subscription callback, new messages of QoS>0 are published, this may lead to deep, or infinite recursion (the latter means an application will terminate with RuntimeException).

API reference

Taking into account API traits described above, umqtt pretty closely follows MQTT control operations, and maps them to class methods:

  • connect(...) - Connect to a server. Returns True if this connection uses persisten session stored on a server (this will be always False if clean_session=True argument is used (default)).
  • disconnect() - Disconnect from a server, release resources.
  • ping() - Ping server (response is processed automatically by wait_msg()).
  • publish() - Publish a message.
  • subscribe() - Subscribe to a topic.
  • set_callback() - Set callback for received subscription messages. call(topic, msg, retained)
  • set_callback_status() - Set callback for received subscription messages. call(pid, status)
  • set_last_will() - Set MQTT "last will" message. Should be called before connect().
  • wait_msg() - Wait for a server message. A subscription message will be delivered to a callback set with set_callback(), any other messages will be processed internally.
  • check_msg() - Check if there's pending message from server. If yes, process the same way as wait_msg(), if not, return immediately.

wait_msg() and check_msg() are "main loop iteration" methods, blocking and non-blocking version. They should be called periodically in a loop, wait_msg() if you don't have any other foreground tasks to perform (i.e. your app just reacts to subscribed MQTT messages), check_msg() if you process other foreground tasks too.

Note that you don't need to call wait_msg()/check_msg() if you only publish messages with QoS==0, never subscribe to them.

If you are using a subscription and/or sending QoS>0 messages, you must run one of these commands ( wait_msg() or check_msg() ).

For more detailed information about API please see the source code (which is quite short and easy to review) and provided examples.

Supported MQTT features

QoS 0 and 1 are supported for both publish and subscribe. QoS2 isn't supported to keep code size small. Besides ClientID, only "clean session" parameter is supported for connect as of now.

Simple library testing

The current tests are not only to test the code, but also to check it in a real environment. Therefore, a good idea, before we use this library in our own project, is to test its operation with the MQTT broker.

To test if the library works well with your device and MQTT broker, use the TestMQTT class from the tests.py module.

If you don't have your own MQTT broker yet, you can use the free MQTT test broker (test.mosquitto.org).

There is also a sample file main.py`(`example_test_main.py), In this file we add only network configuration. Upload this file to your device with umqtt.simple2 library and tests.py module. Then reset the device and watch the results in the console.

How to get tests up and running quickly:

cp example_test_main.py main.py

In the main.py file, assign the appropriate values from your WiFi network to the WIFI_SSID and WIFI_PASSWORD variables.

./upload_to_device.sh

or

./upload_to_device.sh yes # A compiled version that takes up less memory on devices.

Launching the tests:

screen /dev/ttyUSB0  115200 # or screen /dev/ttyACM0  115200
# Ctrl+D - to restart device

Configuring an encrypted connection with test.mosquitto.org:

openssl genrsa -out client.key
openssl req -out client.csr -key client.key -new
cat client.csr # Copy and paste on the page: https://test.mosquitto.org/ssl/ , click "submit"
# Save the certificate to the same directory as client.crt
# Dowlnoad mosquitto.org.crt
# Change key formats:
openssl x509 -in client.crt -out client.crt.der -outform DER
openssl rsa -in client.key -out client.key.der -outform DER
openssl x509 -in mosquitto.org.crt -out mosquitto.org.crt.der -outform DER
# Upload to device
ampy -d1 --baud 115200 --port /dev/ttyACM0 put ./client.key.der
ampy -d1 --baud 115200 --port /dev/ttyACM0 put ./client.crt.der
ampy -d1 --baud 115200 --port /dev/ttyACM0 put ./mosquitto.org.crt.der

Configuring keys for MQTT server(eg. mosquitto):

openssl req -new -x509 -days 365 -extensions v3_ca -keyout ca.key -out ca.crt -subj "/C=XX/ST=Home/L=Home/O=MyCA/OU=MyCA/CN=myca"

openssl genrsa -out server.key 2048
openssl req -new -out server.csr -key server.key -subj "/C=XX/ST=Home/L=Home/O=MQTT Broker/OU=MQTT Broker/CN=YourMQTTserver"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
openssl rsa -in server.key -out server.key
openssl rsa -inform pem -in server.pem -outform der -out key.der

Configuring keys for MQTT server(eg. mosquitto):

openssl genrsa -out client.key 2048
openssl req -new -out client.csr -key client.key -subj "/C=XX/ST=Home/L=Home/O=MQTT Client/OU=MQTT Client/CN=YourDeviceHostName"
openssl x509 -req -in client.csr -CA ../ca.crt -CAkey ../ca.key -CAcreateserial -out client.crt -days 365
openssl rsa -in client.key -out client.key
openssl x509 -in client.crt -out client.crt.der -outform DER
openssl rsa -in client.key -out client.key.der -outform DER
ampy -d1 --baud 115200 --port /dev/ttyACM0 put ./client.key.der
ampy -d1 --baud 115200 --port /dev/ttyACM0 put ./client.crt.der

Configuring mosquitto:

mosquitto_passwd -c /etc/mosquitto/passwd
touch /etc/mosquitto/acl

mosquitto.conf

per_listener_settings true

persistence true
persistence_location /var/lib/mosquitto/
persistent_client_expiration 4m

log_dest file /var/log/mosquitto/mosquitto.log
log_type all

include_dir /etc/mosquitto/conf.d

# MQTT, unencrypted, unauthenticated=anonymous
listener 1883 0.0.0.0
socket_domain ipv4
allow_anonymous true
set_tcp_nodelay true
#keepalive_interval 0
max_keepalive 0

# MQTT, unencrypted, authenticated=password
listener 1884 0.0.0.0
socket_domain ipv4
password_file /etc/mosquitto/passwd
#acl_file /etc/mosquitto/acl
set_tcp_nodelay true
#keepalive 0

# MQTT, encrypted, unauthenticated
listener 8883 0.0.0.0
socket_domain ipv4
allow_anonymous true
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key

# MQTT, encrypted, client certificate required
listener 8884 0.0.0.0
socket_domain ipv4
allow_anonymous true
cafile /etc/mosquitto/certs/ca.crt
capath /etc/mosquitto/certs/certs
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
require_certificate true
use_identity_as_username true # When set to true it tells mosquitto not to use the password file

# MQTT, encrypted, authenticated
listener 8885 0.0.0.0
socket_domain ipv4
password_file /etc/mosquitto/passwd
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
chown -R mosquitto:mosquitto /etc/mosquitto/certs/

Different problems

  • Wrong topic format during subscription - you'll get OSError: [Errno 104] ECONNRESET in subscribe() or MQTTException: 1 in the wait_msg()/check_msg()

Additional resources

micropython-umqtt.simple2's People

Contributors

candale avatar dmascord avatar dvv avatar elvis-epx avatar fizista avatar ironss avatar ngraziano avatar pfalcon avatar puuu avatar tom24 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

micropython-umqtt.simple2's Issues

Internal error in check_msg() using the minimized version of simple2

Describe the bug
Internal error in check_msg() using the minimized version of simple2
line 144 in check_msg
TypeError: function takes 2 positional arguments but 4 were given

To Reproduce
while True:
try:
client.check_msg()
program.run()
except OSError as e:
restart_and_reconnect()

Details (please complete the following information):

  • Device board: ESP32
  • Micropython version: 1.12
  • Library version 2.2.0

connectOSError: -202

Describe the bug
File "/umqtt/simple2.py", line 53, in connectOSError: -202

To Reproduce
I am using your example code from here (https://github.com/fizista/micropython-umqtt.simple2/blob/master/example_sub.py) to publish every 60 seconds a value to my MQTT broker.

def mqtt_pub(server="xx.xx.xx", pub_topic="", pub_value=""):
    c = MQTTClient("umqtt_client_pub", server)
    c.connect()
    time.sleep(.5)
    c.publish(pub_topic, str(pub_value))
    time.sleep(.5)
    c.disconnect()

After a while I am getting the connection error above and no mqtt message is published anymore. Even though the function "mqtt_pub" is called every time.
Any ideas how I can avoid this error?

Details (please complete the following information):

  • Device board: ESP32
  • Micropython version: 1.13
  • Library version: simple2, I guess I am using the latest version as I just installed it via upip yesterday

OSError: [Errno 104] ECONNRESET

Hello :)

I'm trying to setup an MQTT Network.

  • Broker Raspberry Pi4
  • Publisher ESP32

I'm using the simple2.py on the ESP32.
My problem is the errorcode from the title.

Test.txt contains my main code on the ESP32
Test.txt

The "ConnectWifi.connect() function connects the ESP32 to my Network. This part is working.

The detailed error-message:
Traceback (most recent call last):
File "", line 1, in
File "Test.py", line 13, in
File "simple_mqtt2.py", line 323, in connect
File "simple_mqtt2.py", line 128, in _write
OSError: [Errno 104] ECONNRESET

I have no clue what's missing or what else has to be done.

Thanks for every help and suggestions :)

memory allocation failed

esp8266 upip install fail

>>> 
>>> upip.install('micropython-umqtt.simple2')
Installing to: /lib/
Warning: micropython.org SSL certificate is not validated
Error installing 'micropython-umqtt.simple2': memory allocation failed, allocating 8604 bytes, packages may be partially installed
>>> 

ussl wrapped socket has no settimeout method

Trying to use MQTT with ssl=True results in

>>> 
MPY: soft reboot
Traceback (most recent call last):
  File "main.py", line 97, in <module>
  File "main.py", line 92, in main
  File "/lib/umqtt/robust2.py", line 55, in publish
  File "/lib/umqtt/simple2.py", line 72, in publish
  File "/lib/umqtt/simple2.py", line 43, in _sock_timeout
AttributeError: 'ussl' object has no attribute 'settimeout'
MicroPython v1.12-464-gcae77daf0 on 2020-05-24; ESP32 module with ESP32
Type "help()" for more information.

MQTTException(30) #Connection timeout

When I use the umqtt.simple with the same parameters I can publish messages to AWS, but when I want to use want to use umqtt.simple2, I can't connect, even if I put "socket_timeout=None" in init it just keep waiting, it gives me the next error:

Traceback (most recent call last):
File "main.py", line 99, in
File "umqtt/simple2.py", line 289, in connect
File "umqtt/simple2.py", line 92, in _read
File "umqtt/simple2.py", line 89, in _read
File "umqtt/simple2.py", line 162, in _sock_timeout
MQTTException: 30

I guess it just freeze in the line : res = poller.poll(-1 if socket_timeout is None else int(socket_timeout * 1000))
def _sock_timeout(self, poller, socket_timeout): if self.sock: res = poller.poll(-1 if socket_timeout is None else int(socket_timeout * 1000)) if not res: raise MQTTException(30) else: raise MQTTException(28)

Second subscription gives exception 5 in simple2

I have following code on a m5stack Core2.

t='mqttGenericBridge/#' # can only subscribe to one topic tree and only one MQTTClient allowed?
t2='cmnd/#'
c=_MQTTClient('m5core2','192.168.0.40',1883,'','',300)
c.connect()
c.set_callback(fun_mqtt_callback)
c.set_callback_status(fun_mqtt_status_callback)

pid1=c.subscribe(topic=t,qos=1)
pid2=c.subscribe(topic=t2,qos=1)
...
def updateThread():
global c, bThreadsRun
while bThreadsRun:
time.sleep_ms(500)
c.wait_msg() #blocking call
_thread.start_new_thread(updateThread, ())

As soon as a publish of second topic is received, there is an error in line c.wait_msg() for ' if pid in self.rcv_pids:' and raises a MQTTException(5) inside def check_msg(self):... As long as only published topics with first topic are received, there is no error.

        if pid in self.rcv_pids:
            self.last_cpacket = ticks_ms()
            self.rcv_pids.pop(pid)
            self.cbstat(pid, 1)
        else:
            raise MQTTException(5)

I worked around this using your robust2 MQTTClient.

I a second subscription not supported with simple2?

TLS Connection with Self Signed Certificate

I tried and googled a lot and can't get it to work.
I try to connect to my Mosquitto MQTT Broker which speaks TLS with a self signed certificate. With python and paho mqtt I can connect with these tweaks:

  • client.tls_set(cert_reqs=ssl.CERT_NONE)
  • client.tls_insecure_set(insecure)

I tried same setting on connecting with umqtt.simple2:

client = MQTTClient(mqttclientid, <host>, port=8883, user=<mqttusername>,
                            password=<mqttpassword>, keepalive=30, ssl=True,
                            ssl_params={"cert_reqs":ssl.CERT_NONE})
client.connect()

I get the error:

Traceback (most recent call last):
  File "<stdin>", line 38, in <module>
  File "/lib/umqtt/simple2.py", line 67, in connect
  File "/lib/umqtt/simple2.py", line 19, in _read
  File "/lib/umqtt/simple2.py", line 47, in _sock_timeout
MQTTException: 30

Connecting without TLS to port 1883 is working fine.

Is it possible to connect without importing the SSL Certs on my Pico? I hope so.

Details (please complete the following information):

  • Raspberry PI Pico w
  • Micropython version: rp2-pico-w-20220914-unstable-v1.19.1-409

Library does not work with SSL sockets

Description
umqtt.simple2 uses sock.recv() in _read() and sock.send() in _write() which are not supported by the object returned by ussl.wrap_socket().
This results in the exceptions AttributeError: 'ussl' object has no attribute 'recv' or AttributeError: 'ussl' object has no attribute 'send', respectively.
The reason is documented in https://docs.micropython.org/en/latest/library/ussl.html#functions.

The original exception is obfuscated by the error handling in _read() / _write() which turns any exception into MQTTException(8) (ENOCON - No connection).

Maybe the behaviour of ussl.wrap_socket() has been changed in the past!?

To Reproduce
Initialize mqtt_client with ssl=True:
mqtt_client = MQTTClient(client_id=MQTT_CLIENT_ID, server=MQTT_HOST, port=MQTT_PORT, user=MQTT_USER, password=MQTT_PASSWD, keepalive=5000, ssl=True, ssl_params={"cert":cert, "server_side":False})

Details:

  • Device board: ESP32
  • Micropython version: 1.15, 1.16
  • Library version: v2.1.0

Check multiple opening and closing connections

In report #4 there were reported problems with an unusual error: OSError: -202

The question is whether it is possible to reproduce the problem and whether it is because of this library or micropython itself.

Connection to Azure IoT Hub

I'm unable to connect to Azure IoT Hub using the umqtt.simple2 library with SSL using MicroPython v1.22.2. No error message is provided by the connect method, making it difficult to diagnose the issue further (it fails on line 267 in simple2, when wrapping the socket --> self.sock = ussl.wrap_socket(self.sock_raw, **self.ssl_params))

from umqtt.simple2 import MQTTClient

HUB_HOSTNAME = "AzureIoTHubHostName"
PORT = 8883
CLIENT_ID = "DeviceId"
USERNAME = f"{HUB_HOSTNAME}/{CLIENT_ID}/?api-version=2021-04-12"
PASSWORD = "SASToken"
TOPIC = f"devices/{CLIENT_ID}/messages/events/"
MESSAGE = b"Hello Azure IoT Hub!"
CADATA_PATH = "cadata_path"

with open(CADATA_PATH, "rb") as f:
    cadata = f.read()

ssl_params = {"cert_reqs": ussl.CERT_NONE, "cadata": cadata}

client = MQTTClient(
    CLIENT_ID,
    HUB_HOSTNAME,
    port=PORT,
    user=USERNAME,
    password=PASSWORD,
    ssl=True,
    ssl_params=ssl_params,
)

client.connect()

client.publish(TOPIC, MESSAGE)

client.disconnect()

I have tested my certificate file with openssl to check if the handshake occurs (openssl s_client -connect), and it works ok.

Could anyone advise on how to resolve this connectivity issue with Azure IoT Hub using MicroPython? Any guidance would be greatly appreciated.

'NoneType' object has no attribute 'poll'

I got the error message: 'NoneType' object has no attribute 'poll' that occurred on line 89 of umqtt simple2.py
I am using an ESP32 with micropython version 1.18
I need my ESP32 to continue operating even if the MQTT broker is not running.
I got the above error when I unplugged the broker from the network and called check_msg() as part of a while loop.
Using simple.py the ESP32 would hang with no explanation as to why and required a hard reset when calling check_msg() so I was trying simple2.py

Hope someone can help.

OSError -6

Trying to install like in the wiki, but replacing upip with mip. But I get the OSerror -6:

import mip
mip.install("micropython-umqtt.simple2")
Installing micropython-umqtt.simple2 (latest) from https://micropython.org/pi/v2 to /lib
Traceback (most recent call last):
File "", line 1, in
File "mip/init.py", line 1, in install
File "mip/init.py", line 1, in _install_package
File "mip/init.py", line 1, in _install_json
File "urequests.py", line 180, in get
File "urequests.py", line 76, in request
OSError: -6

I suppose this has something to do with the upip/mip migration. I used to be able to install like this.

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:
For example a piece of code that can be pasted into a micropython console.

Details (please complete the following information):

  • Device board: rpi pico W
  • Micropython version: 1.20
  • Library version [e.g. 0.1]

Platform `umqtt` package masks installed files with that prefix on current micropython.

Describe the bug
With a current version of micropython and upip, installing the package places the required files in the appropriate path, but it seems that something in the library management doesn't handle user-installed libraries with the same directory name as built-in libraries properly:

To Reproduce



>>> import upip
>>> import os
>>> import sys
>>> upip.install("micropython-umqtt.robust2")
Installing to: /lib/
Warning: micropython.org SSL certificate is not validated
Installing micropython-umqtt.simple2 2.1.0 from https://files.pythonhosted.org/packages/a7/75/c80449358ec98512393095b8180f4b59fd0ca9582f27fbb837d160da9e6b/micropython-umqtt.simple2-2.1.0.tar.gz
>>> from umqtt.simple2import MQTTClient
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'umqtt.simple2'
>>> sys.path
['', '/lib']
>>> os.listdir("/lib")
['umqtt']
>>> os.listdir("/lib/umqtt")
['__init__.py', 'errno.py', 'robust2.py', 'simple2.py']
>>> open("/lib/umqtt/simple2.py").read()
"import usocket as socket\nimport uselect\nfrom utime import ticks_add,ticks_ms,ticks_diff\nclass MQTTException(Exception):0\ndef pid_gen(pid=0):\n\tA=pid\n\twhile True:A=A+1 if A<65535 else 1;yield A\nclass MQTTClient:\n\tdef __init__(A,client_id,server,port=0,user=None,password=None,keepalive=0,ssl=False,ssl_params=None,socket_timeout=5,message_timeout=10):\n\t\tC=ssl_params;B=port\n\t\tif B==0:B=8883 if ssl else 1883\n\t\tA.client_id=client_id;A.sock=None;A.poller=None;A.server=server;A.port=B;A.ssl=ssl;A.ssl_params=C if C else{};A.newpid=pid_gen()\n\t\tif not getattr(A,'cb',None):A.cb=None\n\t\tif not getattr(A,'cbstat',None):A.cbstat=lambda p,s:None\n\t\tA.user=user;A.pswd=password;A.keepalive=keepalive;A.lw_topic=None;A.lw_msg=None;A.lw_qos=0;A.lw_retain=False;A.rcv_pids={};A.last_ping=ticks_ms();A.last_cpacket=ticks_ms();A.socket_timeout=socket_timeout;A.message_timeout=message_timeout\n\tdef _read(A,n):\n\t\ttry:\n\t\t\tB=b''\n\t\t\tfor C in range(n):A._sock_timeout(A.poller_r,A.socket_timeout);B+=A.sock.read(1)\n\t\texcept AttributeError:raise MQTTException(8)\n\t\tif B==b'':raise MQTTException(1)\n\t\tif len(B)!=n:raise MQTTException(2)\n\t\treturn B\n\tdef _write(A,bytes_wr,length=-1):\n\t\tD=bytes_wr;B=length\n\t\ttry:A._sock_timeout(A.poller_w,A.socket_timeout);C=A.sock.write(D,B)\n\t\texcept AttributeError:raise MQTTException(8)\n\t\tif B<0:\n\t\t\tif C!=len(D):raise MQTTException(3)\n\t\telif C!=B:raise MQTTException(3)\n\t\treturn C\n\tdef _send_str(A,s):assert len(s)<65536;A._write(len(s).to_bytes(2,'big'));A._write(s)\n\tdef _recv_len(D):\n\t\tA=0;B=0\n\t\twhile 1:\n\t\t\tC=D._read(1)[0];A|=(C&127)<<B\n\t\t\tif not C&128:return A\n\t\t\tB+=7\n\tdef _varlen_encode(C,value,buf,offset=0):\n\t\tB=offset;A=value;assert A<268435456\n\t\twhile A>127:buf[B]=A&127|128;A>>=7;B+=1\n\t\tbuf[B]=A;return B+1\n\tdef _sock_timeout(B,poller,socket_timeout):\n\t\tA=socket_timeout\n\t\tif B.sock:\n\t\t\tC=poller.poll(-1 if A is None else int(A*1000))\n\t\t\tif not C:raise MQTTException(30)\n\t\telse:raise MQTTException(28)\n\tdef set_callback(A,f):A.cb=f\n\tdef set_callback_status(A,f):A.cbstat=f\n\tdef set_last_will(A,topic,msg,retain=False,qos=0):B=topic;assert 0<=qos<=2;assert B;A.lw_topic=B;A.lw_msg=msg;A.lw_qos=qos;A.lw_retain=retain\n\tdef connect(A,clean_session=True):\n\t\tE=clean_session;A.sock=socket.socket();A.poller_r=uselect.poll();A.poller_r.register(A.sock,uselect.POLLIN);A.poller_w=uselect.poll();A.poller_w.register(A.sock,uselect.POLLOUT);G=socket.getaddrinfo(A.server,A.port)[0][-1];A.sock.connect(G)\n\t\tif A.ssl:import ussl;A.sock=ussl.wrap_socket(A.sock,**A.ssl_params)\n\t\tF=bytearray(b'\\x10\\x00\\x00\\x00\\x00\\x00');B=bytearray(b'\\x00\\x04MQTT\\x04\\x00\\x00\\x00');D=10+2+len(A.client_id);B[7]=bool(E)<<1\n\t\tif bool(E):A.rcv_pids.clear()\n\t\tif A.user is not None:\n\t\t\tD+=2+len(A.user);B[7]|=1<<7\n\t\t\tif A.pswd is not None:D+=2+len(A.pswd);B[7]|=1<<6\n\t\tif A.keepalive:assert A.keepalive<65536;B[8]|=A.keepalive>>8;B[9]|=A.keepalive&255\n\t\tif A.lw_topic:D+=2+len(A.lw_topic)+2+len(A.lw_msg);B[7]|=4|(A.lw_qos&1)<<3|(A.lw_qos&2)<<3;B[7]|=A.lw_retain<<5\n\t\tH=A._varlen_encode(D,F,1);A._write(F,H);A._write(B);A._send_str(A.client_id)\n\t\tif A.lw_topic:A._send_str(A.lw_topic);A._send_str(A.lw_msg)\n\t\tif A.user is not None:\n\t\t\tA._send_str(A.user)\n\t\t\tif A.pswd is not None:A._send_str(A.pswd)\n\t\tC=A._read(4)\n\t\tif not(C[0]==32 and C[1]==2):raise MQTTException(29)\n\t\tif C[3]!=0:\n\t\t\tif 1<=C[3]<=5:raise MQTTException(20+C[3])\n\t\t\telse:raise MQTTException(20,C[3])\n\t\tA.last_cpacket=ticks_ms();return C[2]&1\n\tdef disconnect(A):A._write(b'\\xe0\\x00');A.poller_r.unregister(A.sock);A.poller_w.unregister(A.sock);A.sock.close();A.sock=None;A.poller=None\n\tdef ping(A):A._write(b'\\xc0\\x00');A.last_ping=ticks_ms()\n\tdef publish(A,topic,msg,retain=False,qos=0,dup=False):\n\t\tE=topic;B=qos;assert B in(0,1);C=bytearray(b'0\\x00\\x00\\x00\\x00');C[0]|=B<<1|retain|int(dup)<<3;F=2+len(E)+len(msg)\n\t\tif B>0:F+=2\n\t\tG=A._varlen_encode(F,C,1);A._write(C,G);A._send_str(E)\n\t\tif B>0:D=next(A.newpid);A._write(D.to_bytes(2,'big'))\n\t\tA._write(msg)\n\t\tif B>0:A.rcv_pids[D]=ticks_add(ticks_ms(),A.message_timeout*1000);return D\n\tdef subscribe(A,topic,qos=0):E=topic;assert qos in(0,1);assert A.cb is not None,'Subscribe callback is not set';B=bytearray(b'\\x82\\x00\\x00\\x00\\x00\\x00\\x00');C=next(A.newpid);F=2+2+len(E)+1;D=A._varlen_encode(F,B,1);B[D:D+2]=C.to_bytes(2,'big');A._write(B,D+2);A._send_str(E);A._write(qos.to_bytes(1,'little'));A.rcv_pids[C]=ticks_add(ticks_ms(),A.message_timeout*1000);return C\n\tdef _message_timeout(A):\n\t\tC=ticks_ms()\n\t\tfor (B,D) in A.rcv_pids.items():\n\t\t\tif ticks_diff(D,C)<=0:A.rcv_pids.pop(B);A.cbstat(B,0)\n\tdef check_msg(A):\n\t\tif A.sock:\n\t\t\tif not A.poller_r.poll(-1 if A.socket_timeout is None else 1):A._message_timeout();return None\n\t\t\ttry:\n\t\t\t\tG=A._read(1)\n\t\t\t\tif not G:A._message_timeout();return None\n\t\t\texcept OSError as H:\n\t\t\t\tif H.args[0]==110:A._message_timeout();return None\n\t\t\t\telse:raise H\n\t\telse:raise MQTTException(28)\n\t\tif G==b'\\xd0':\n\t\t\tif A._read(1)[0]!=0:MQTTException(-1)\n\t\t\tA.last_cpacket=ticks_ms();return\n\t\tB=G[0]\n\t\tif B==64:\n\t\t\tD=A._read(1)\n\t\t\tif D!=b'\\x02':raise MQTTException(-1)\n\t\t\tF=int.from_bytes(A._read(2),'big')\n\t\t\tif F in A.rcv_pids:A.last_cpacket=ticks_ms();A.rcv_pids.pop(F);A.cbstat(F,1)\n\t\t\telse:A.cbstat(F,2)\n\t\tif B==144:\n\t\t\tC=A._read(4)\n\t\t\tif C[0]!=3:raise MQTTException(40,C)\n\t\t\tif C[3]==128:raise MQTTException(44)\n\t\t\tif C[3]not in(0,1,2):raise MQTTException(40,C)\n\t\t\tE=C[2]|C[1]<<8\n\t\t\tif E in A.rcv_pids:A.last_cpacket=ticks_ms();A.rcv_pids.pop(E);A.cbstat(E,1)\n\t\t\telse:raise MQTTException(5)\n\t\tA._message_timeout()\n\t\tif B&240!=48:return B\n\t\tD=A._recv_len();I=int.from_bytes(A._read(2),'big');J=A._read(I);D-=I+2\n\t\tif B&6:E=int.from_bytes(A._read(2),'big');D-=2\n\t\tK=A._read(D)if D else b'';L=B&1;M=B&8;A.cb(J,K,bool(L),bool(M));A.last_cpacket=ticks_ms()\n\t\tif B&6==2:A._write(b'@\\x02');A._write(E.to_bytes(2,'big'))\n\t\telif B&6==4:raise NotImplementedError()\n\t\telif B&6==6:raise MQTTException(-1)\n\tdef wait_msg(A):B=A.socket_timeout;A.socket_timeout=None;C=A.check_msg();A.socket_timeout=B;return C"

>>> os.listdir("/lib")
['umqtt']
>>> os.listdir("/lib/umqtt")
['__init__.py', 'errno.py', 'robust2.py', 'simple2.py']
>>> os.rename("/lib/umqtt", "/lib/umqtt2")
>>> from umqtt2.simple2 import MQTTClient
>>> 

Steps to reproduce the behavior:

On a blank ESP32 (or similar) with network access and upython 1.13.0.

1: Install package
2: Try to import.

Renaming the umqtt directory that upip places in /lib to something else (I used umqtt2) lets it import correctly. My current guess is that the import system doesn't handle user libraries with the same name as baked in libraries.

Details (please complete the following information):

  • ESP32
  • Micropython version:

    sys.version
    '3.4.0'
    sys.implementation
    (name='micropython', version=(1, 13, 0), mpy=10757)
    Currently using the official download esp32-idf3-20200902-v1.13.bin from https://micropython.org/download/esp32/

  • Library version - Doesn't matter, but what's in micropython pypi

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.