BnMcG / PyRobovac

Python library for controlling the Eufy RoboVac 11c
Apache License 2.0
27 stars 2 forks source link

Broken Pipe #4

Open JXGA opened 5 years ago

JXGA commented 5 years ago

Hi again...

New issue on HA, but it's coming from this.

HA behaviour: The initial state loads (battery, status, on/off). No further updates are shown on HA, and unable to start any of the services. 'Bad file descriptor'.

Python test: Just a simple get_status(),

ERROR:root:[Errno 32] Broken pipe Traceback (most recent call last): File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 324, in _send_packet self.s.send(encrypted_packet_data) BrokenPipeError: [Errno 32] Broken pipe Traceback (most recent call last): File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 324, in _send_packet self.s.send(encrypted_packet_data) BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "robovac_test.py", line 5, in nemasis.get_status() File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 165, in get_status message = self._build_get_device_status_user_data_message() File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 292, in _build_get_device_status_user_data_message magic_number = self._get_magic_number() File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 308, in _get_magic_number pong = self._send_packet(ping, True) File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 328, in _send_packet self.connect() File "/home/omv/.local/lib/python3.6/site-packages/robovac/robovac.py", line 154, in connect self.s.connect((self.ip, self.port)) OSError: [Errno 9] Bad file descriptor

I got the older robovac from the repo and it works fine directly from Python- able to get a status, trigger the clean, etc.

Thank you again for your time !

BnMcG commented 5 years ago

Could you copy and paste your test script for me to take a quick look over? The bottom error makes it seem like it's trying to communicate with the RoboVac after the socket has closed.

JXGA commented 5 years ago

Certainly, it's pretty simple;

from robovac import Robovac

nemasis = Robovac('IP', 'key')

print(nemasis.get_status())

This issue is replicated from both HA and Python on a different machine Thanks

BnMcG commented 5 years ago

I've just pushed a newer version to a "socket-tests" branch, can you clone this locally? You should be able to put your test script at the end and run it without needing to do anything to install the module. I think you probably can't re-open a socket after closing it, because the underlying OS handle is now gone.

The version on the branch recreates the socket when a re-connection is made - I'm not 100% sure that won't lead to a different problem, but it's worth a quick try and I can't try and re-create the issue locally at the moment.

To add some extra info, you'll probably need to put something like this at the bottom of robovac.py:

if __name__ == '__main__':
  nemasis = Robovac(IP, key)
  print(nemasis.get_status())

You should then be able to run using python3 -m robovac.robovac from inside the top-level directory of the repository.

JXGA commented 5 years ago

Perfect, socket-tests works.

I still get two errors, but the vac does work with HA. In the HA log (and when I first try and use the standalone python script), I get the Broken Pipe.

[Errno 32] Broken pipe Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/robovac/robovac.py", line 325, in _send_packet self.s.send(encrypted_packet_data) BrokenPipeError: [Errno 32] Broken pipe

In addition, inside HA I get;

Failed to update RoboVac status: unpack requires a buffer of 2 bytes

For what it's worth, I have restarted everything several times, and the buffer thing has been appearing for a few days.

BnMcG commented 5 years ago

Does the buffer error appear intermittently or constantly?

Broken pipe sounds like it's trying to write to the closed socket... Does it still work even when the broken pipe error appears? I added some code in the 0.0.9 version of the library to log the exceptions it was hitting to try and work out why it was resetting the connection so often, it might just be logging the exception then ignoring it, but I'm not exactly sure of the format Python uses for this - but I'd expect it to log some sort of error and then continue working if that's the case (eg: log the error but then reconnect successfully and execute whatever action you requested initially).

JXGA commented 5 years ago

Broken pipe seems to appear once, then it re-establishes communication and works fine. Status updates and commands work... except for Spot Clean (info below, but I don't personally use that).

I'll report back on the buffer error (and other instances of the broken pipe, should it reoccur) - Buffer error definitely appears on HA start.

Following call of Spot Clean:

Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 121, in handle_call_service connection.context(msg)) File "/usr/src/homeassistant/homeassistant/core.py", line 1150, in async_call self._execute_service(handler, service_call)) File "/usr/src/homeassistant/homeassistant/core.py", line 1172, in _execute_service await handler.func(service_call) File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 194, in handle_service required_features File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 316, in entity_service_call future.result() # pop exception if have File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 337, in _handle_service_platform_call await getattr(entity, func)(data) File "/usr/src/homeassistant/homeassistant/components/vacuum/init.py", line 218, in async_clean_spot partial(self.clean_spot, kwargs)) File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/usr/src/homeassistant/homeassistant/components/vacuum/init.py", line 210, in clean_spot raise NotImplementedError() NotImplementedError

BnMcG commented 5 years ago

Spot clean is just where I've missed adding the function in the Home Assistant component, but it is implemented in the underlying Python library here. I'll push a quick fix tomorrow morning to the Home Assistant component that should get spot cleaning working in Home Assistant - my bad for missing it, sorry!

Does broken pipe also appear once on HA start-up? I'm wondering if it's related to the buffer error. Also, do you know if buffer error appears when you call any particular command? Or is it just when the status updates periodically?

JXGA commented 5 years ago

Here's a full list of Robo errors from HA (last restart yesterday evening).

Failed to update RoboVac status: unpack requires a buffer of 2 bytes Occurred at HA startup and hasn't reoccured since.

[Errno 32] Broken pipe The full error included above - occurred at HA startup and hasn't reoccured since.

NotImplementedError The full error included above - occurred at HA startup and reoccurred a few times (every time I clicked the button for spot cleaning).

Failed to update RoboVac status: 131 Random occurrence of this during the night, shows up 4 times.

Thank you!

BnMcG commented 5 years ago

OK, the final error is because the RoboVac uses numbers to represent statuses (eg: "charging", "stuck", etc). That error appears because I haven't mapped 131 to a specific state yet - do you know if the RoboVac was stuck or anything similar at the time - or did you get a notification through the app for something? If not, I'll have a look through the decompiled app to see if I can work out what 131 corresponds to.

I'm not too worried about the broken pipe and unpack buffer errors if they only occur once at start-up and then it continues to function fine afterwards, but I'll see if I can spot anything going on in the code - it doesn't happen for me locally when I start HA.

JXGA commented 5 years ago

I thought that alright - when it occurs the Vac isn't doing anything but charging... Maybe the 131 could mean 'fully charged'? I have received a couple of broken pipe messages, but it seems that HA was losing connection to more the vac during the night - the good thing is that it reconnects and works as expected when commanded from HA, so I'm more than happy to treat it as a spurious warning. Cheers

Lex-talionis commented 5 years ago

I've installed 0.0.9 and made the change to the file you made in the socket branch and I'm able to get the same status output. But for anything else I get the same original broken pipe error. I dont really know python but I going to see if I can get it to work using a similar technique with the other calls.