python-eufy-security icon indicating copy to clipboard operation
python-eufy-security copied to clipboard

Implement P2P protocol for device control

Open keshavdv opened this issue 5 years ago • 11 comments

Describe what the PR does: This is an initial attempt at implementing the peer to peer protocol in Python that is heavily based on https://github.com/fbertone/lib32100 combined with Eufy-specific elements. I only have a single "standalone" device (floodlight) so I can't test certain features that I know won't work just yet. Apart from that, it does seem to at least work (see added example for usage) but I imagine there needs to be a discussion on the best API to expose from within this library to make it more friendly for other applications so there still aren't any unit tests.

Does this fix a specific issue? Nope, new feature.

Checklist:

  • [ ] Confirm that one or more new tests are written for the new functionality.
  • [ ] Update README.md with any new documentation.
  • [ ] Add yourself to AUTHORS.md.

keshavdv avatar May 31 '20 04:05 keshavdv

Looks promising. Wasn't able to connect to the my doorbell with that yet though. Will dig deeper.

nonsleepr avatar May 31 '20 16:05 nonsleepr

I think I figured out why it's not working with the doorbell:

When you do discovery, STUN servers actually send your (client's) host/port to the doorbell. Since you open a new connection (with a new port) to connect to every new host, the doorbell gets the port different from the one you're using to connect to it. You should open only one connection and use it to communicate with everything.

nonsleepr avatar Jun 01 '20 06:06 nonsleepr

Ah, that does makes sense, but it seems like @joepadmiraal's attempt wasn't even getting that far -- it didn't seem like there was even a valid response from the discovery servers.

keshavdv avatar Jun 01 '20 06:06 keshavdv

Could be API_BASE switching. In my case it switches to -eu and can't find anything. I think that's also the reason why my doorbell is no longer displayed in the web-app.

nonsleepr avatar Jun 01 '20 06:06 nonsleepr

I'm replying here instead of in the issue to concentrate our findings. I tested with the EU addresses and it now seems to get a bit further for me. Sometimes I get this output:

DEBUG:asyncio:Using selector: EpollSelector
INFO:eufy_security.api:Switching to another API_BASE: https://security-app-eu.eufylife.com/v1
------------------
Station Name: eufy base
Serial Number: T8010P2320020A43
DEBUG:eufy_security.station:Unable to process parameter "1266", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1176", value "192.168.0.248"
DEBUG:eufy_security.station:Unable to process parameter "1236", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1155", value "2"
DEBUG:eufy_security.station:Unable to process parameter "1135", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1670", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1265", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1362", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1253", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1200", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1043", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1280", value "30"
DEBUG:eufy_security.station:Unable to process parameter "1140", value "1"
Station params: {1266: '0', 1176: '192.168.0.248', 1236: '1', <ParamType.GUARD_MODE: 1224>: 1, <ParamType.CAMERA_SPEAKER_VOLUME: 1230>: 26, 1155: '2', 1135: '0', 1670: '0', 1265: '1', <ParamType.CAMERA_UPGRADE_NOW: 1133>: 0, 1362: '1', 1253: '0', 1200: '0', 1043: '0', <ParamType.SCHEDULE_MODE: 1257>: 63, 1280: '30', 1140: '1'}
Camera params: DeviceType.STATION
INFO:eufy_security.p2p.session:Trying discovery seed 34.235.4.153
INFO:eufy_security.p2p.session:Trying discovery seed 54.153.101.7
INFO:eufy_security.p2p.session:Trying discovery seed 18.223.127.200
INFO:eufy_security.p2p.session:Trying discovery seed 54.223.148.206
INFO:eufy_security.p2p.session:Trying discovery seed 18.197.212.165
INFO:eufy_security.p2p.session:Trying discovery seed 13.251.222.7
INFO:eufy_security.p2p.session:Trying addresses: ('192.168.0.248', 29798)
ERROR:eufy_security.p2p.session:Error received
Traceback (most recent call last):
  File "/usr/lib64/python3.8/asyncio/selector_events.py", line 1009, in _read_ready
    data, addr = self._sock.recvfrom(self.max_size)
ConnectionRefusedError: [Errno 111] Connection refused
ERROR:eufy_security.p2p.session:Error received
Traceback (most recent call last):
  File "/usr/lib64/python3.8/asyncio/selector_events.py", line 1009, in _read_ready
    data, addr = self._sock.recvfrom(self.max_size)
ConnectionRefusedError: [Errno 111] Connection refused
INFO:eufy_security.p2p.session:Connection closed
INFO:eufy_security.p2p.session:Trying addresses: ('94.208.195.16', 29798)
ERROR:eufy_security.p2p.session:Error received
Traceback (most recent call last):
  File "/usr/lib64/python3.8/asyncio/selector_events.py", line 1009, in _read_ready
    data, addr = self._sock.recvfrom(self.max_size)
ConnectionRefusedError: [Errno 111] Connection refused
ERROR:eufy_security.p2p.session:Error received
Traceback (most recent call last):
  File "/usr/lib64/python3.8/asyncio/selector_events.py", line 1009, in _read_ready
    data, addr = self._sock.recvfrom(self.max_size)
ConnectionRefusedError: [Errno 111] Connection refused
INFO:eufy_security.p2p.session:Connection closed
Traceback (most recent call last):
  File "test_p2p.py", line 42, in <module>
    asyncio.get_event_loop().run_until_complete(main())
  File "/usr/lib64/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "test_p2p.py", line 30, in main
    async with station.connect() as session:
  File "/usr/lib64/python3.8/contextlib.py", line 171, in __aenter__
    return await self.gen.__anext__()
  File "/home/joep/Documents/joep/domotica/eufy/python-keshavdv/eufy_security/station.py", line 45, in connect
    raise EufySecurityP2PError(f"Could not connect to {self.name}")
eufy_security.errors.EufySecurityP2PError: Could not connect to eufy base

And sometimes I get this output. In this case it will hang (waited for 2 minutes) instead of stop the program.

DEBUG:asyncio:Using selector: EpollSelector
INFO:eufy_security.api:Switching to another API_BASE: https://security-app-eu.eufylife.com/v1
------------------
Station Name: eufy base
Serial Number: T8010P2320020A43
DEBUG:eufy_security.station:Unable to process parameter "1266", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1176", value "192.168.0.248"
DEBUG:eufy_security.station:Unable to process parameter "1236", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1155", value "2"
DEBUG:eufy_security.station:Unable to process parameter "1135", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1670", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1265", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1362", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1253", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1200", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1043", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1280", value "30"
DEBUG:eufy_security.station:Unable to process parameter "1140", value "1"
Station params: {1266: '0', 1176: '192.168.0.248', 1236: '1', <ParamType.GUARD_MODE: 1224>: 1, <ParamType.CAMERA_SPEAKER_VOLUME: 1230>: 26, 1155: '2', 1135: '0', 1670: '0', 1265: '1', <ParamType.CAMERA_UPGRADE_NOW: 1133>: 0, 1362: '1', 1253: '0', 1200: '0', 1043: '0', <ParamType.SCHEDULE_MODE: 1257>: 63, 1280: '30', 1140: '1'}
Camera params: DeviceType.STATION
INFO:eufy_security.p2p.session:Trying discovery seed 34.235.4.153
INFO:eufy_security.p2p.session:Trying discovery seed 54.153.101.7
INFO:eufy_security.p2p.session:Trying discovery seed 18.223.127.200
INFO:eufy_security.p2p.session:Trying discovery seed 54.223.148.206
INFO:eufy_security.p2p.session:Trying discovery seed 18.197.212.165
INFO:eufy_security.p2p.session:Trying discovery seed 13.251.222.7
INFO:eufy_security.p2p.session:Trying addresses: ('192.168.0.248', 23219)
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_PING (20): bytearray(b'\xd1\x00\x00\x00XZYHs\x04\x00\x00\x00\x00\x01\x00\xff\x00\x00\x00')
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_PING (20): bytearray(b'\xd1\x00\x00\x01XZYHs\x04\x00\x00\x00\x00\x01\x00\xff\x00\x00\x00')
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_PING (20): bytearray(b'\xd1\x00\x00\x02XZYHs\x04\x00\x00\x00\x00\x01\x00\xff\x00\x00\x00')
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_PING (20): bytearray(b'\xd1\x00\x00\x03XZYHs\x04\x00\x00\x00\x00\x01\x00\xff\x00\x00\x00')
DEBUG:eufy_security.p2p.session:Processing P2PClientProtocolResponseMessageType.DATA:EufyP2PDataType.CONTROL with seq 0
DEBUG:eufy_security.p2p.session:Received command type CommandType.CMD_PING
DEBUG:eufy_security.p2p.session:Processing P2PClientProtocolResponseMessageType.DATA:EufyP2PDataType.CONTROL with seq 1
DEBUG:eufy_security.p2p.session:Received command type CommandType.CMD_PING

joepadmiraal avatar Jun 01 '20 07:06 joepadmiraal

Sweet! So I think you're getting around the NAT issues that @nonsleepr might be hitting since you’re accessing your device over LAN, but it's at least looking more promising. It seems like it was able to communicate with the doorbell and is stuck because it didn't receive a packet that I expected it should based on my own testing. Can you try the latest commit and share another tcpdump if it still hangs?

keshavdv avatar Jun 01 '20 07:06 keshavdv

Seems better now:

DEBUG:asyncio:Using selector: EpollSelector
INFO:eufy_security.api:Switching to another API_BASE: https://security-app-eu.eufylife.com/v1
------------------
Station Name: eufy base
Serial Number: T8010P2320020A43
DEBUG:eufy_security.station:Unable to process parameter "1266", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1176", value "192.168.0.248"
DEBUG:eufy_security.station:Unable to process parameter "1236", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1155", value "2"
DEBUG:eufy_security.station:Unable to process parameter "1135", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1670", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1265", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1362", value "1"
DEBUG:eufy_security.station:Unable to process parameter "1253", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1200", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1043", value "0"
DEBUG:eufy_security.station:Unable to process parameter "1280", value "30"
DEBUG:eufy_security.station:Unable to process parameter "1140", value "1"
Station params: {1266: '0', 1176: '192.168.0.248', 1236: '1', <ParamType.GUARD_MODE: 1224>: 1, <ParamType.CAMERA_SPEAKER_VOLUME: 1230>: 26, 1155: '2', 1135: '0', 1670: '0', 1265: '1', <ParamType.CAMERA_UPGRADE_NOW: 1133>: 0, 1362: '1', 1253: '0', 1200: '0', 1043: '0', <ParamType.SCHEDULE_MODE: 1257>: 63, 1280: '30', 1140: '1'}
Camera params: DeviceType.STATION
INFO:eufy_security.p2p.session:Trying discovery seed 34.235.4.153
INFO:eufy_security.p2p.session:Trying discovery seed 54.153.101.7
INFO:eufy_security.p2p.session:Trying discovery seed 18.223.127.200
INFO:eufy_security.p2p.session:Trying discovery seed 54.223.148.206
INFO:eufy_security.p2p.session:Trying discovery seed 18.197.212.165
INFO:eufy_security.p2p.session:Trying discovery seed 13.251.222.7
INFO:eufy_security.p2p.session:Trying addresses: ('192.168.0.248', 23192)
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_PING (20): bytearray(b'\xd1\x00\x00\x00XZYHs\x04\x00\x00\x00\x00\x01\x00\xff\x00\x00\x00')
INFO:eufy_security.p2p.session:Connected to ('192.168.0.248', 23192)
Turning the on-screen watermark on
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_SET_DEVS_OSD (156): bytearray(b'\xd1\x00\x00\x01XZYH\xbe\x04\x88\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00c37274750c94e96532bfeaad0bd4bfd815bef36a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
DEBUG:eufy_security.p2p.session:Processing P2PClientProtocolResponseMessageType.DATA:EufyP2PDataType.CONTROL with seq 0
DEBUG:eufy_security.p2p.session:Received command type CommandType.CMD_PING
DEBUG:eufy_security.p2p.session:Processing P2PClientProtocolResponseMessageType.DATA:EufyP2PDataType.DATA with seq 0
DEBUG:eufy_security.p2p.session:Received command type CommandType.CMD_SET_DEVS_OSD
Turning watermark off
DEBUG:eufy_security.p2p.session:Sending packet CommandType.CMD_SET_DEVS_OSD (156): bytearray(b'\xd1\x00\x00\x02XZYH\xbe\x04\x88\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00c37274750c94e96532bfeaad0bd4bfd815bef36a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
INFO:eufy_security.p2p.session:Connection closed

Do you still want the a new tcpdump?

joepadmiraal avatar Jun 01 '20 08:06 joepadmiraal

Nope, from the output it looks like it ran successfully. It should have momentarily turned on the on screen watermark (the Eufy logo in the top left) of the live video feed for a couple seconds and then turned it off. Can you confirm that actually happens? Also, to clarify, do you have a wired or wireless doorbell?

keshavdv avatar Jun 01 '20 08:06 keshavdv

The watermark is successfully added and removed in the video. Also when I look at the app I see the watermark toggle is on, and later is off. I have the Battery video doorbell set which is wired for power and the base station is also wired to ethernet. The doorbell itself communicates wireless to the base station. So it's both wireless and wired ;)

https://www.coolblue.nl/product/857838/eufy-by-anker-video-doorbell-battery-set.html#product-specifications

joepadmiraal avatar Jun 01 '20 09:06 joepadmiraal

So I think you're getting around the NAT issues that @nonsleepr might be hitting since you’re accessing your device over LAN

I'm trying to connect over internet and not getting the response from the doorbell (I explained the reason above). (my own implementation using single connection works, BTW, I'll see if I can release that). As for the LAN connection, the discovery piece is not needed at all. You could simply broadcast \xf1\x30\x00\x00 to port 32108 to locate the doorbell (not sure about other cameras).

nonsleepr avatar Jun 01 '20 17:06 nonsleepr

@keshavdv and @nonsleepr u guys gave up on this ? Or can I still check out this branch and give it a shot ?

praveen12bnitt avatar Jul 18 '20 13:07 praveen12bnitt