0

Python: Check/Ping Adafruit IO for connection, and reconnect
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Python: Check/Ping Adafruit IO for connection, and reconnect

by bri_een on Mon Jun 26, 2017 5:16 am

Firstly, I have to say that Adafruit IO is the greatest advance in the IOT for the makers out there in, and for, many years. Well done to all involved!

I have a headless raspberry pi1 with wifi dongle, a DHT11 Temp/Humidity sensor, and three relays out in my garage.
I started with the excellent MQTT_client python example from Github (https://github.com/adafruit/io-client-p ... _client.py) and modified it to subscribe to three Adafruit IO feeds I labeled 'switch1', 'switch2', etc - when the feeds change from OFF/ON the python script picks up the change, and changes the state of the relays through the GPIO pins of the pi impressively quickly! I'm also publishing the temperature and humidity from the DHT11 sensor to feeds called 'temperature1' and 'humidity1' every 30 seconds (instead of the random numbers in the example every 10s).
I think to maintain a connection to Adafruit IO, some data should be sent to a feed at least once per 300 seconds, or the connection gets dropped.

Creating IFTTT widget buttons to change feed values is a cool interface from the homescreen of my phone too - but it is not nearly as fast as using the Adafruit IO dashboard buttons.

My problem is that my connection to Adafruit IO does not last overly long. This might be a current feature/bug of the Beta?
I have the MQTT_client.py script starting on reboot of the pi through the crontab, and because of my limited understanding of coding python, I have (reluctantly) set the pi set to reboot every 4 hours. This forced periodic reboot reconnects my pi to Adafruit IO, and I get temperature & humidity values publishing again.

I know that there must be an elegant way to add into the example MQTT_client.py code; a loop that pings Adafruit IO periodically, and depending on the result (what are the results?) either carries on, or attempts to reconnect. I haven't found many other python/pi examples out there that do this connection check, and building on the excellent MQTT_client.py script that Tony DiCola wrote, I feel would be an excellent contribution to the community.

Could someone with python skills please point me in the right direction? I don't really know what to put in, nor where to put it.

bri_een
 
Posts: 3
Joined: Mon Jun 05, 2017 12:40 am

Re: Python: Check/Ping Adafruit IO for connection, and recon

by jwcooper on Mon Jun 26, 2017 10:37 am

Thank you for the kind feedback on IO.

I think the python library has a bug with reconnect timing. We need to do some testing and work on our python library as there are a few useful pull requests that we haven't gotten to yet. You could try pulling some of them into a fork of the library and see if that fixes your connection issues?

Here is the start of the relevant pull requests that may help you out with losing your connection:
https://github.com/adafruit/io-client-python/pull/27

jwcooper
 
Posts: 664
Joined: Tue May 01, 2012 9:08 pm

Re: Python: Check/Ping Adafruit IO for connection, and recon

by robingreig on Thu May 10, 2018 11:39 am

Good Morning!
I'm having the same issue, using the mqtt_client.py program as my initial starting point, and subscribing to several different feeds of mine. I have modified the program to only subscribe to feeds and not publish any data.

As long as I'm modifying the feeds every 5 minutes (300 seconds), my Raspberry Pi stays connected to the Adafruit IO mqtt broker.
If I don't change my feeds via a web browser within what I believe is the KEEP_ALIVE timeout, the python program disconnects from the broker, and prints out the following: "Disconnected from Adafruit IO!". Or maybe the broker is disconnecting me? (still so much to learn about mqtt!)

Here is the code from mqtt_client.py:
Code: Select all | TOGGLE FULL SIZE
def disconnected(client):
    # Disconnected function will be called when the client disconnects.
    print 'Disconnected from Adafruit IO!'
    sys.exit(1)

I have come up with a HACK to stay connected to the Adafruit IO broker by changing the above code to:
Code: Select all | TOGGLE FULL SIZE
def disconnected(client):
    # Disconnected function will be called when the client disconnects.
    print 'Disconnected from Adafruit IO!'
    #sys.exit(1)
    client.connect()

Essentially what I think I have done, is not allow the program to exit, but to re-connect via the client.connect() function.

I'm sure that there is a better way to ping the broker within the KEEP_ALIVE time (300 seconds?) to stay connected.
So if anyone can point me in the right direction to learn how to ping the broker through Python, I would be very appreciative!

Thanks again Adafruit for providing this service and your tutorials to help us to learn.
Robin

robingreig
 
Posts: 11
Joined: Fri Oct 05, 2012 1:34 pm

Re: Python: Check/Ping Adafruit IO for connection, and recon

by jwcooper on Thu May 10, 2018 12:14 pm

Hey Robin, there are a few fixes on the master branch that should fix your issue. We'll work on releasing a new version with those fixes shortly.

Let us know if you continue to run into issues if you are able to try the master branch:
https://github.com/adafruit/io-client-python

Specifically, the fix is:
https://github.com/adafruit/io-client-p ... 05ce0c9cee

jwcooper
 
Posts: 664
Joined: Tue May 01, 2012 9:08 pm

Re: Python: Check/Ping Adafruit IO for connection, and recon

by robingreig on Thu May 10, 2018 4:31 pm

You guys ROCK!

I notice on github the mention that the files have been updated to add the retain variable?

I think that has caused me some issues?
Code: Select all | TOGGLE FULL SIZE
Traceback (most recent call last):
  File "./raspi-git/Python/Relay8/ZeroRelay4.py", line 131, in <module>
    client.loop_blocking()
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_IO/mqtt_client.py", line 140, in loop_blocking
    self._client.loop_forever()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1481, in loop_forever
    rc = self.loop(timeout, max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1003, in loop
    rc = self.loop_read(max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1284, in loop_read
    rc = self._packet_read()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1849, in _packet_read
    rc = self._packet_handle()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2305, in _packet_handle
    return self._handle_publish()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2500, in _handle_publish
    self._handle_on_message(message)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2647, in _handle_on_message
    self.on_message(self, self._userdata, message)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_IO/mqtt_client.py", line 96, in _mqtt_message
    self.on_message(self, feed, payload, retain)
TypeError: message() takes exactly 3 arguments (4 given)

It appears to me that the retain argument change has thrown me for a loop?

Thanks again for the awesome support and the opportunity to play with this technology.
Robin

robingreig
 
Posts: 11
Joined: Fri Oct 05, 2012 1:34 pm

Please be positive and constructive with your questions and comments.