bamthomas / domopyc

Python utilities to build home domotic applications for example with Raspberry Pi
MIT License
3 stars 1 forks source link

Sometimes cpu is going hight and there are serial.serialutil.SerialException on rfxcom module #1

Open bamthomas opened 9 years ago

bamthomas commented 9 years ago

The rfxcom module is broken with this kind of stacks :

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/asyncio/events.py", line 119, in _run
    self._callback(*self._args)
  File "/home/pi/venv/lib/python3.4/site-packages/rfxcom/transport/asyncio.py", line 76, in read
    data = self.dev.read()
  File "/home/pi/venv/lib/python3.4/site-packages/serial/serialposix.py", line 480, in read
    if e[0] != errno.EAGAIN:
TypeError: 'SerialException' object does not support indexing
2015-07-29 08:12:17,411 [asyncio] ERROR: Exception in callback AsyncioTransport.read()
handle: <Handle AsyncioTransport.read()>
Traceback (most recent call last):
  File "/home/pi/venv/lib/python3.4/site-packages/serial/serialposix.py", line 475, in read
    raise SerialException('device reports readiness to read but returned no data (device disconnected or multiple access on port?)')
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
RouquinBlanc commented 9 years ago

Hi Bruno,

Had the same issue. An easy way to get this error is to simply unplug the rfxcom module. This comes from pyserial not correctly handling the error in python 3. select.error is a subclass of OSError, which causes to enter in the first catch instead of second.

Not finding a fixed version on pyserial website, I justed hacked directly the file serialposix.py around line 480 from this:

            except select.error, e:
                # ignore EAGAIN errors. all other errors are shown
                # see also http://www.python.org/dev/peps/pep-3151/#select
                if e[0] != errno.EAGAIN:
                    raise SerialException('read failed: %s' % (e,))
            except OSError, e:
                # ignore EAGAIN errors. all other errors are shown
                if e.errno != errno.EAGAIN:
                    raise SerialException('read failed: %s' % (e,))

to this (found somewhere, I believe in ToT of dev branch):

            except OSError as e:
                # this is for Python 3.x where select.error is a subclass of OSError
                # ignore EAGAIN errors. all other errors are shown
                if e.errno != errno.EAGAIN:
                    raise SerialException('read failed: %s' % (e,))
            except select.error as e:
                # this is for Python 2.x
                # ignore EAGAIN errors. all other errors are shown
                # see also http://www.python.org/dev/peps/pep-3151/#select
                if e[0] != errno.EAGAIN:
                    raise SerialException('read failed: %s' % (e,))

It would be great to insist in getting a new release of pyserial with recent fixes at some point!

Cheers Jonathan

RouquinBlanc commented 9 years ago

Oh, and the CPU goes high because (in my case), the exception not being handled correctly, asyncio was repeatedly trying to read from a dead fd!

bamthomas commented 9 years ago

Thank you for the analysis. I wonder why there is a select.error thrown. I thought I had found the root cause with the raspberry pi, when I had not disabled the serial port as console port. After having disabled it, this error became much less frequent. But it still occurs.

Is the serial file descriptor dead ?

RouquinBlanc commented 9 years ago

In my case, yes: i unplug the rfxcom! It results in a infinite look on the same error.

bamthomas commented 9 years ago

So far so good, the system is in production for 10 days with a little raspberry pi 2. I have not had this bug. But it's too early to be sure.