pimoroni / enviroplus-python

Python library for the Enviro+ environmental monitoring board
https://shop.pimoroni.com/products/enviro-plus
MIT License
392 stars 181 forks source link

Invalid argument on read() #32

Closed mhawkshaw closed 1 year ago

mhawkshaw commented 5 years ago

After a while, the script will fail with the following printed in the Terminal:

(22, 'Invalid argument')

And when I press Ctrl + C I get the following stack trace:

  File "./luftdaten.py", line 177, in <module>
    values = read_values()
  File "./luftdaten.py", line 62, in read_values
    pm_values = pms5003.read()
  File "/usr/local/lib/python2.7/dist-packages/pms5003-0.0.4-py2.7.egg/pms5003/__init__.py", line 123, in read
    sof = bytearray(self._serial.read(2))
  File "/usr/local/lib/python2.7/dist-packages/pyserial-3.4-py2.7.egg/serial/serialposix.py", line 480, in read
    timeout = Timeout(self._timeout)
  File "/usr/local/lib/python2.7/dist-packages/pyserial-3.4-py2.7.egg/serial/serialutil.py", line 123, in __init__
    def __init__(self, duration):
KeyboardInterrupt

But I can't see why it's failing. Does anyone know the exception to catch in this case?

Gadgetoid commented 5 years ago

I'm not sure what's happening here- this doesn't look like an exception so much as some text being erroneously printed, but the pms5003 library doesn't output anything like this.

Does the script just hang, with (22, 'Invalid argument') being the last thing that's printed?

mhawkshaw commented 5 years ago

It prints it repeatedly and doesn’t submit any results to luftdaten.info

I wonder if it happens more if it gets too hot - it the sun is shining on the sensor (although it’s in a pipe) - as it seems to happen more often then

Gadgetoid commented 4 years ago

I have a suspicion that it's the send_to_luftdaten function that's failing with the (22, 'Invalid argument') and the catch all for Exception is causing it to be printed with every loop, rather than failing with any useful information.

I didn't write this example, so I'm not familiar with the caveats of the Luftdaten API but it looks suspiciously like you don't have a PMS5003 sensor connected, yet the example is still attempting to submit PMS5003 data resulting in an empty set of "sensordatavalues" being submitted which causes this error.

Is this the case?

Gadgetoid commented 4 years ago

I've mocked up a couple of test cases against the luftdaten API and my tests don't seem to support this theory.

Since the exception handling is catching all exceptions and printing them, it's not very conductive to finding the source. You could modify the example to swap out the main portion of the code for one without exception handling, so it'll fail where it fails and produce some more useful output:

# Main loop to read data, display, and send to Luftdaten
while True:
    time_since_update = time.time() - update_time
    values = read_values()
    print(values)
    if time_since_update > 145:
        resp = send_to_luftdaten(values, id)
        update_time = time.time()
        print("Response: {}\n".format("ok" if resp else "failed"))
    display_status()

I'm trying this locally to see if I can replicate!

Gadgetoid commented 4 years ago

I couldn't seem to replicate this at all- you'll have to try the above code (removing the exception trap) to see if you can narrow down where it's coming from.

mhawkshaw commented 4 years ago

Thanks for your time investigating, I'll include the above code to try and narrow it down (as soon as I get WiFi working on my Pi again...)