0

CircuitPython IO minimqtt library loop() function blocking a
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

CircuitPython IO minimqtt library loop() function blocking a

by chriswei on Sat Feb 20, 2021 2:22 am

I'm trying to use Adafruit IO's CircuitPython library on a Feather M4 Express with the Airlift FeatherWing. I want to be able to use MQTT pub/sub to subscribe to a topic and publish to another topic in a loop, but the mqtt_client.loop() functions seems to block waiting for data to be posted to the subscribed topic once, then the loop call continues as expected. If I don't 'kick' the subscribed topic by publishing data to this topic from the adafruit.io Feeds screen once, the loop() will eventually throw MMQTTException: Unable to receive 1 bytes within 60 seconds.

Is this the expected behavior - that the loop() function will block (and eventually time out) unless I publish data to its subscribed topic once? Or am I missing something. I'm using the example code in minimqtt_pub_sub_nonblocking_esp32spi.py from the latest v6 of the CircuitPython IO library (at https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/blob/85d9d846f3fd8f9d3ee8ae354c5c34d2e2970c1a/examples/esp32spi/minimqtt_pub_sub_nonblocking_esp32spi.py).

Thank you!

Code: Select all | TOGGLE FULL SIZE
while True:
   mqtt_client.loop()
   mqtt_client.publish(topic, value)
   time.sleep(5)

chriswei
 
Posts: 8
Joined: Tue Jan 17, 2012 4:38 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by chriswei on Sat Feb 20, 2021 2:39 am

I tried catching and eating the exception, which works intermittently. Sometimes it'll work (i.e. exception caught, publish works fine, repeat), other times loop() will throw:

Traceback (most recent call last):
File "code.py", line 142, in <module>
File "code.py", line 140, in <module>
File "adafruit_minimqtt/adafruit_minimqtt.py", line 809, in loop
File "adafruit_minimqtt/adafruit_minimqtt.py", line 569, in ping
File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 82, in send
File "adafruit_esp32spi/adafruit_esp32spi.py", line 721, in socket_write
RuntimeError: Failed to send 2 bytes (sent 0)

Code: Select all | TOGGLE FULL SIZE
while True:
  try:
    mqtt_client.loop()
  except (MQTT.MMQTTException) as e:
    print(e)
  mqtt_client.publish(topic, value 
  time.sleep(5)

chriswei
 
Posts: 8
Joined: Tue Jan 17, 2012 4:38 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by brubell on Mon Feb 22, 2021 10:59 am

Could you file this as an issue on the MiniMQTT repository directly? https://github.com/adafruit/Adafruit_Ci ... QTT/issues

The latest `master` branch includes a pull request which fixed the blocking issue, please try that and we'll get it officially released:

https://github.com/adafruit/Adafruit_Ci ... master.zip

brubell
 
Posts: 1256
Joined: Fri Jul 17, 2015 10:33 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by chriswei on Mon Feb 22, 2021 12:57 pm

Filed as https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/70

I'll follow your recommendation to try the 'latest' tonight.

chriswei
 
Posts: 8
Joined: Tue Jan 17, 2012 4:38 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by chriswei on Mon Feb 22, 2021 8:12 pm

As requested by brubell above, I ran my code using the adafruit_minimqtt library from the 'master' branch of the library's repo, and the loop() function no longer blocks and throws exceptions.

I also tried the new library code in my code that uses the adafruit_io library with the IO_MQTT wrapper, and that code now runs as expected (the loop() function no longer blocks).

chriswei
 
Posts: 8
Joined: Tue Jan 17, 2012 4:38 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by Chock on Tue Feb 23, 2021 9:29 pm

I've been chasing the problem of the loop() call throwing an exception as well. I'm connecting to a local mqtt server and subscribing to a single topic.

I grabbed the updated version referenced above and my code is still throwing an exception on the loop() call. It only throws an exception on the second and all subsequent calls to loop() (not the first). If there is a message published to the topic on try #1 it seems to read it successfully. I am catching all the loop() exceptions and then after around 60 seconds my script raises an exception elsewhere in the library and terminates:

Code: Select all | TOGGLE FULL SIZE
Connecting to mqtt broker at 192.168.1.249...
Connected to mqtt! Listening for topic changes on bose/volume
looping every 5 seconds
client.loop() call #1
client.loop() call #2
exception:
client.loop() call #3
exception:
client.loop() call #4
exception:
client.loop() call #5
exception:
client.loop() call #6
exception:
client.loop() call #7
exception:
client.loop() call #8
exception:
client.loop() call #9
exception:
client.loop() call #10
exception:
client.loop() call #11
exception:
client.loop() call #12
exception:
client.loop() call #13
Traceback (most recent call last):
  File "code.py", line 101, in <module>
  File "code.py", line 99, in <module>
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 808, in loop
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 569, in ping
OSError: [Errno 9] EBADF

Code done running.

Chock
 
Posts: 11
Joined: Sat May 06, 2017 9:47 am

Re: CircuitPython IO minimqtt library loop() function blocki

by brubell on Wed Feb 24, 2021 12:13 pm

Chock wrote:I've been chasing the problem of the loop() call throwing an exception as well. I'm connecting to a local mqtt server and subscribing to a single topic.

I grabbed the updated version referenced above and my code is still throwing an exception on the loop() call. It only throws an exception on the second and all subsequent calls to loop() (not the first). If there is a message published to the topic on try #1 it seems to read it successfully. I am catching all the loop() exceptions and then after around 60 seconds my script raises an exception elsewhere in the library and terminates:

Code: Select all | TOGGLE FULL SIZE
Connecting to mqtt broker at 192.168.1.249...
Connected to mqtt! Listening for topic changes on bose/volume
looping every 5 seconds
client.loop() call #1
client.loop() call #2
exception:
client.loop() call #3
exception:
client.loop() call #4
exception:
client.loop() call #5
exception:
client.loop() call #6
exception:
client.loop() call #7
exception:
client.loop() call #8
exception:
client.loop() call #9
exception:
client.loop() call #10
exception:
client.loop() call #11
exception:
client.loop() call #12
exception:
client.loop() call #13
Traceback (most recent call last):
  File "code.py", line 101, in <module>
  File "code.py", line 99, in <module>
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 808, in loop
  File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 569, in ping
OSError: [Errno 9] EBADF

Code done running.


Since this is a MiniMQTT issue, but not related to the topic itself, could you please post this on the MiniMQTT issues page?
https://github.com/adafruit/Adafruit_Ci ... QTT/issues

Thanks!

brubell
 
Posts: 1256
Joined: Fri Jul 17, 2015 10:33 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by brubell on Wed Feb 24, 2021 12:13 pm

chriswei wrote:As requested by brubell above, I ran my code using the adafruit_minimqtt library from the 'master' branch of the library's repo, and the loop() function no longer blocks and throws exceptions.

I also tried the new library code in my code that uses the adafruit_io library with the IO_MQTT wrapper, and that code now runs as expected (the loop() function no longer blocks).


We've released the new code, thank you for testing

brubell
 
Posts: 1256
Joined: Fri Jul 17, 2015 10:33 pm

Re: CircuitPython IO minimqtt library loop() function blocki

by Chock on Wed Feb 24, 2021 1:47 pm

I guess I thought this was directly related but I can do that, yes

Chock
 
Posts: 11
Joined: Sat May 06, 2017 9:47 am

Please be positive and constructive with your questions and comments.