Adafruit Industries, Essential service and business: NYC – Executive Order 202.6 - Read more.
0

Exception during aio.send(...)
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.
Please be positive and constructive with your questions and comments.

Exception during aio.send(...)

by macewmi on Tue Mar 03, 2020 6:02 pm

I've got an app that works 98% of the time. It's running on four separate Raspberry Pi's. But today, they won't run for more than 10 minutes (+/-) without aborting with this error
Code: Select all | TOGGLE FULL SIZE
Traceback (most recent call last):
  File "adaio.py", line 94, in <module>
    aio.send(humidity_feed.key, str(humidity))
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 154, in send_data
    return self.create_data(feed, payload)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 254, in create_data
    return Data.from_dict(self._post(path, data._asdict()))
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 127, in _post
    self._handle_error(response)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 108, in _handle_error
    raise RequestError(response)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/errors.py", line 40, in __init__
    error_message = self._parse_error(response)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/errors.py", line 45, in _parse_error
    content = response.json()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.7/json/decoder.py", line 340, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 5 (char 4)

I've already collected thousands of data points over a period of weeks with this code, so it's probably not a problem in my code.

What I'm looking for is some sort of explanation of the exception. Was the "send" received by IO? Did IO send back a response of some sort? Was that response less that good?

To work around the problem, I've wrapped the aio.send in a try:except: block. The except just logs an failure message and then sleeps until the timer says it's ready for the next aio.send.

But I'd still love to know what's happening because I'm losing observations from my dataset.

macewmi
 
Posts: 6
Joined: Sat Feb 08, 2020 10:26 am

Re: Exception during aio.send(...)

by brubell on Wed Mar 04, 2020 12:37 pm

Hi macewmi,

It's tough to troubleshoot this type of error without your original code (`adaio.py`). Could you post it here? Or, if it's sensitive, you can use the feedback form on io.adafruit.com/feedback.

Did IO send back a response of some sort? Was that response less that good?

It's possible that it sent back some type of error which wasn't parsed properly. Did you see anything on your monitor page (io.adafruit.com/monitor)?

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

Re: Exception during aio.send(...)

by macewmi on Wed Mar 04, 2020 1:28 pm

Thank you.

Nothing appears in the FEEDS that are affected by this failure. The data just stops showing up once the program has an error. I do have a notification set for the FEEDS, so I'm alerted that data has stopped being collected.

Here's the exact error I'm getting redirected to 2>&1

pi@bluepi: ~ $ Traceback (most recent call last):
  File "adaio.py", line 94, in <module>
    aio.send(humidity_feed.key, str(humidity))
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 154, in send_data
    return self.create_data(feed, payload)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 254, in create_data
    return Data.from_dict(self._post(path, data._asdict()))
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 127, in _post
    self._handle_error(response)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/client.py", line 108, in _handle_error
    raise RequestError(response)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/errors.py", line 40, in __init__
    error_message = self._parse_error(response)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_IO/errors.py", line 45, in _parse_error
    content = response.json()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.7/json/decoder.py", line 340, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 5 (char 4)

Here is my complete code:

Code: Select all | TOGGLE FULL SIZE
# import standard python modules.
import time
import sys
import getopt
import datetime

# import adafruit dht library.
import Adafruit_DHT

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

# Set default options
SILENT = True
# Delay in-between sensor readings, in seconds.
DHT_READ_TIMEOUT = 10
# Pin connected to DHT22 data pin
DHT_DATA_PIN = 4

# 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 = '..............'
# Set to your Adafruit IO username.
# (go to https://accounts.adafruit.com to find your username).
ADAFRUIT_IO_USERNAME = '............'

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

# Set up Adafruit IO Feeds.
#temperature_feed = aio.feeds('temperaturef')
#humidity_feed = aio.feeds('humidityf')

# Set up DHT Sensor.
dht_sensor = Adafruit_DHT.DHT22

def setOptions(parameters):
    global DHT_READ_TIMEOUT
    global dht_sensor
    global DHT_DATA_PIN
    global SILENT
    global temperature_feed
    global humidity_feed

    try:
           # v verbose logging
           # i sampling interval in seconds
           # p GPIO pin number to read
           # s sendor model 11 or 22
           opts, args = getopt.getopt(parameters,"vi:p:s:r:")
    except getopt.GetoptError:
        print('there was an error')
        print('test.py -v -i -p -s')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-v':
            SILENT = False
        elif opt in ('-i'):
            DHT_READ_TIMEOUT = int(arg)
        elif opt in ('-p'):
            DHT_DATA_PIN = int(arg)
        elif opt in ('-s'):
            if arg == '11':
                dht_sensor = Adafruit_DHT.DHT11
        elif opt in ('-r'):
            h = 'h' + arg
            t = 't' + arg
            print('Temp to',t)
            print('Humidity to',h)
            temperature_feed = aio.feeds(t)
            humidity_feed = aio.feeds(h)

parameters = sys.argv[1:]
setOptions(parameters)
print('Silent:', SILENT)
print('Interval:', DHT_READ_TIMEOUT)
print('Pin:', DHT_DATA_PIN)
print('Sensor:', dht_sensor)

while True:
    humidity, temperature = Adafruit_DHT.read_retry(dht_sensor, DHT_DATA_PIN)
    if humidity is not None and temperature is not None:
        tempF = temperature * 9 / 5 + 32
        if SILENT == False:
            timestamp = datetime.datetime.now().time()
            print('{} {:0.1f}*C {:0.1f}*F Humidity={:0.1f}% '.format(timestamp, temperature, tempF, humidity))
        # Send humidity and temperature feeds to Adafruit IO
        temperature = '%.2f'%(temperature)
        tempF = '%.2f'%(tempF)
        humidity = '%.2f'%(humidity)
# THIS TRY/EXCEPT BLOCK WAS ADDED ONCE THE ERRORS STARTED HAPPENING
# IN ORDER TO MITIGATE THE EFFECTS OF A .SEND FAILURE
        try:
           timestamp = datetime.datetime.now().time()
           aio.send(temperature_feed.key, str(tempF))
           aio.send(humidity_feed.key, str(humidity))
        except:
           #print('SEND failure @ {} '.format(timestamp))
           continue
## END BLOCK
    else:
        print('Failed to get DHT22 Reading, trying again in ', DHT_READ_TIMEOUT, 'seconds')
    # Timeout to avoid flooding Adafruit IO
    time.sleep(DHT_READ_TIMEOUT)

macewmi
 
Posts: 6
Joined: Sat Feb 08, 2020 10:26 am

Please be positive and constructive with your questions and comments.