User avatar
richiepp
Posts: 140
Joined: Wed Dec 19, 2012 4:56 pm

Handling throtle errors from Adafruit

Fri May 29, 2020 8:19 pm

Hey All,
I've got a python script that sends temperature data to adafruit.io . It works as intended for the most part but crashes occasionally. I live in a rural area where my internet can be flaky from time to time. As far as I can tell there are periods of slow connection and when things come back there is a flood of unsent data that exceeds the throttle. This causes the script to crash and I get the following error.

Code: Select all

Traceback (most recent call last):
  File "temp.py", line 223, in <module>
    aio.send(temperature_feed6.key, str(outside))
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_IO/client.py", line 154,                                               in send_data
    return self.create_data(feed, payload)
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_IO/client.py", line 254,                                               in create_data
    return Data.from_dict(self._post(path, data._asdict()))
  File "/usr/local/lib/python2.7/dist-packages/Adafruit_IO/client.py", line 126,                                               in _post
    data=json.dumps(data))
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 116, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 533, in req                                              uest
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 646, in sen                                              d
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 516, in sen                                              d
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='io.adafruit.com',                                               port=443): Max retries exceeded with url: /api/v2/strawbale/feeds/outside/data                                               (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection objec                                              t at 0x75a70470>: Failed to establish a new connection: [Errno -3] Temporary fai                                              lure in name resolution',))
What is the best way to handle this error? How can I set this up so the script doesn't crash during times of congestion?

Code: Select all

import os
import glob
import time

# import Adafruit IO REST client.
from Adafruit_IO import Client, Feed

# Set to your Adafruit IO key.
# Remember, your key is a secret,
# so make sure not to publish it when you publish this code!
ADAFRUIT_IO_KEY = 'yadayadayada'

# Set to your Adafruit IO username.
# (go to https://accounts.adafruit.com to find your username).
ADAFRUIT_IO_USERNAME = 'hello'

# Create an instance of the REST client.
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)

# Set up Adafruit IO Feeds.
temperature_feed = aio.feeds('bench3')
temperature_feed2 = aio.feeds('bench')
temperature_feed4 = aio.feeds('bench2')

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'

device_folder2 = glob.glob(base_dir + '28-01144a0327aa')[0]
device_file2 = device_folder2 + '/w1_slave'

device_folder3 = glob.glob(base_dir + '28-030797798d33')[0]
device_file3 = device_folder3 + '/w1_slave'

device_folder4 = glob.glob(base_dir + '28-0000084a2941')[0]
device_file4 = device_folder4 + '/w1_slave'

def read_temp_raw2():
    f = open(device_file2, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_raw3():
    f = open(device_file3, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_raw4():
    f = open(device_file4, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp2():
    lines = read_temp_raw2()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000
        temp_f = temp_c * 9 / 5 + 32
        return  round(temp_f,1)

def read_temp3():
    lines = read_temp_raw3()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000
        temp_f = temp_c * 9 / 5 + 32
        return  round(temp_f,1)

def read_temp4():
    lines = read_temp_raw4()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000
        temp_f = temp_c * 9 / 5 + 32
        return  round(temp_f,1)

def read_time():
        now =  datetime.now().strftime('%H:%M%p')
        return now

while True:
        bench = (read_temp3())
        bench2 = (read_temp4())
        bench3 = (read_temp2())

        print (bench)
        print (bench2)
        print (bench3)

#       aio.send(temperature_feed2.key, str(bench))
        time.sleep(20)
        aio.send(temperature_feed4.key, str(bench))
        time.sleep(20)
        aio.send(temperature_feed2.key, str(bench3))
        time.sleep(10)
Thanks
Rich

timboring
Posts: 6
Joined: Sun Jan 19, 2020 4:25 am

Re: Handling throtle errors from Adafruit

Sat May 30, 2020 5:00 am

A common way to handle this kind of situation is to use exponential backoff [1]. Over the last 2-3 years, I've started using the backoff library to handle this (instead of rolling my own) [2].

The thing to be aware of with exponential backoff is that you want to use it with calls that you're confident will eventually succeed. So it's good for things like your situation or other transient issues.

[1] https://aws.amazon.com/blogs/architectu ... nd-jitter/
[2] https://pypi.org/project/backoff/

Return to “Python”