lost connection recovery

Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Locked
User avatar
Rcayot
 
Posts: 321
Joined: Sat Feb 08, 2020 6:48 pm

lost connection recovery

Post by Rcayot »

I have a weather station that I have feeding AIO. The issue is that I have a poor internet connection by satellite. Every once in a while, depending on weather conditions etc., I temporarily lose my internet connection and the program feeding AIO crashes.

I have placed several tests for connection in the program and do not understand why they are not working. Here is partial code that first uses an 'if adafruit.is_active:' test, where "adafruit=PingServer('adafruit.com', event_delay=20.0)" is set in the early portion of the code.

Code: Select all

while True:
    # Look for a new packet: only accept if addresses to my_node
    packet = rfm9x.receive(with_ack=True, with_header=True)
    # If no packet was received during the timeout then None is returned.
    if packet is not None:
        #print("Received raw packet:", [hex(x) for x in packet])
        payload = str(packet[4:], "utf-8")
        tag = int(payload[0])
        #print(tag)
        if tag == 1:
            temperature = payload[1:]
            temperature = (float(temperature)*1.8 + 32)
            temperature=round(temperature, 2)
            print("temperature = ", temperature, "F")
            if adafruit.is_active:
                aio.send(temperature_feed.key, str(temperature))
            else:
                print("wifi not ready")
        elif tag == 3:
            pressure = payload[1:]
            print("pressure = ", pressure, "mB")
            if adafruit.is_active:
                aio.send(pressure_feed.key, str(pressure))
            else:
                print("wifi not ready")
        elif tag == 2:
            humidity = payload[1:]
            print("humidity = ", humidity, "%")
            if adafruit.is_active:
                aio.send(humidity_feed.key, str(humidity))
            else:
                print("wifi not ready")
Occasionally I get an error message, quite lengthy, but the last portion is the following:


Traceback (most recent call last):
File "/home/pi/backup/Downloads/Adafruit_CircuitPython_RFM9x-main/rfm9x_flag_ack_aio_wind3.py", line 99, in <module>
aio.send(humidity_feed.key, str(humidity))
File "/home/pi/backup/Downloads/Adafruit_CircuitPython_RFM9x-main/Adafruit_IO/client.py", line 154, in send_data
return self.create_data(feed, payload)
File "/home/pi/backup/Downloads/Adafruit_CircuitPython_RFM9x-main/Adafruit_IO/client.py", line 254, in create_data
return Data.from_dict(self._post(path, data._asdict()))
File "/home/pi/backup/Downloads/Adafruit_CircuitPython_RFM9x-main/Adafruit_IO/client.py", line 122, in _post
response = requests.post(self._compose_url(path),
File "/usr/lib/python3/dist-packages/requests/api.py", line 119, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='io.adafruit.com', port=443): Max retries exceeded with url: /api/v2/Rcayot/feeds/humidity/data (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb4fcc3a0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))


What I would like to know is why if adafruit.is_active: is true why does the code fail when the next line is executed:

Code: Select all

if adafruit.is_active:
                aio.send(humidity_feed.key, str(humidity))
            else:
Anyway, Is it the delay of 20s that is too slow? Is there another way in which I could error trap this problem such that the program just skips over that portion and prints "wifi not ready"?

Any help would be welcome.

Roger

User avatar
eherrada
 
Posts: 161
Joined: Thu Jan 04, 2018 4:59 pm

Re: lost connection recovery

Post by eherrada »

I think the best way to go about this would be to put the code in a try/except loop and then use watchdog timer (https://docs.circuitpython.org/en/lates ... index.html) to reset the device after waiting a bit if it gets disconnected

User avatar
Rcayot
 
Posts: 321
Joined: Sat Feb 08, 2020 6:48 pm

Re: lost connection recovery

Post by Rcayot »

Eheradda,

Thank you, I will persue this.

Roger

User avatar
DJDevon3
 
Posts: 210
Joined: Wed Mar 06, 2019 11:02 am

Re: lost connection recovery

Post by DJDevon3 »

Your delay isn't the problem. In my production code I'm posting and getting every 1800 seconds (30 minutes). So, obviously 20 seconds is nothing. Actually, I consider 20 seconds extremely fast and aggressive as a frequency but it depends on your needs.

User avatar
Rcayot
 
Posts: 321
Joined: Sat Feb 08, 2020 6:48 pm

Re: lost connection recovery

Post by Rcayot »

DJ,

The 20s delay is related to the implementation of 'PingServer':

adafruit=PingServer('adafruit.com', event_delay=20.0)

The issue is that when I use PingServer to see if Adafruit.com is available such as:

if adafruit.is_active:
aio.send(pressure_feed.key, str(pressure))

There seems to be an issue with the connection, and the program crashes. I was trying to keep the program running instead of crashing, I do not care if a couple of data points go missing, I just want the program to recover.

The API for PingServer does not go into detail about the function of 'event_delay'

I did not post the entire code as it is somewhat lengthy. I am using adafruits async_io to manage 'cooperative multitasking' instead of the usual time.sleep, or checking for elapsed time using time.monotonic.

Roger

User avatar
Rcayot
 
Posts: 321
Joined: Sat Feb 08, 2020 6:48 pm

Re: lost connection recovery

Post by Rcayot »

eherratta,

I have implemented a try/except in my code, the watchdog time will not work because I am running this code on a Raspberry Pi 4.

What I am having trouble with is how to implement the except portion of the function.

The end of the verbose errors log output is like such:

File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='io.adafruit.com', port=443): Max retries exceeded with url: /api/v2/Rcayot/feeds/humidity/data (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb4fcc3a0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))


I have inserted this at the end of my program lop:

Code: Select all

except (UnicodeDecodeError, RequestError) as exception:
        print("error detected")
    finally:
        continue
The concern I have is that I think 'RequestError' is a failure of the adafruit_io function, and the actual failure is in teh python3 libraries on my Pi-4.

I have yet to experience an error of this type, so, I do not know yet if it will work.

Roger

Locked
Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.

Return to “Internet of Things: Adafruit IO and Wippersnapper”