GeezerVison is showing github.com — dumping HTTP POST Body for Tapo Vacuum (RV30 Plus) · Issue #937 · python-kasa/python-kasa
dumping HTTP POST Body for Tapo Vacuum (RV30 Plus) #937DescriptionMITM captured these from the tapo app to a RV30 Plus. just wanted to dump them for the public.
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "getVacStatus"
},
{
"method": "getBatteryInfo"
},
{
"method": "getComponentList"
},
{
"method": "getDeviceInfo"
}
]
}
}
START CLEANING A SPECIFIC ROOM:
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setSwitchClean",
"params": {
"clean_mode": 3,
"clean_on": true,
"clean_order": true,
"force_clean": false,
"map_id": 1687964172,
"room_list": [
1
]
}
}
]
}
}
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "getAutoChangeMap"
}
]
}
}
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "getMapInfo"
},
{
"method": "startUpdateMapData",
"params": {
"map_upload_start": true
}
},
{
"method": "getAreaUnit"
}
]
}
}
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "getMapData",
"params": {
"map_id": -1
}
},
{
"method": "getPathData",
"params": {
"start_pos": 0
}
}
]
}
}
GET REPORTS
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "getCleanRecords"
}
]
}
}
HEAD TO DOCK
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setSwitchCharge",
"params": {
"switch_charge": true
}
}
]
}
}
STOP HEADING TO DOCK
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setSwitchCharge",
"params": {
"switch_charge": false
}
}
]
}
}
CLEAN WHOLE MAP
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setSwitchClean",
"params": {
"clean_mode": 0,
"clean_on": true,
"clean_order": true,
"force_clean": false
}
}
]
}
}
PAUSE
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setRobotPause",
"params": {
"pause": true
}
}
]
}
}
RESUME
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setRobotPause",
"params": {
"pause": false
}
}
]
}
}
CHANGE THE NUMBER OF PASSES
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setCleanAttr",
"params": {
"cistern": 2,
"clean_number": 2,
"suction": 2,
"type": "global"
}
}
]
}
}
START COLLECTING DUST
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setSwitchDustCollection",
"params": {
"switch_dust_collection": true
}
}
]
}
}
START ZONE CLEANING
{
"method": "multipleRequest",
"params": {
"requests": [
{
"method": "setSwitchClean",
"params": {
"area_list": [
{
"cistern": 2,
"clean_number": 1,
"id": 0,
"name": "",
"suction": 2,
"tag": "",
"type": "area",
"vertexs": [
[
-1861,
2262
],
[
653,
2262
],
[
653,
-1701
],
[
-1861,
-1701
]
]
}
],
"clean_mode": 4,
"clean_on": true,
"clean_order": true,
"force_clean": false,
"map_id": 1687964172
}
}
]
}
}
Activityrytilahti commented on May 25, 2024 steveredden commented on May 25, 2024 ContributorAuthor More actions == Unsupported device ==
== Discovery Result ==
Device Type: SMART.TAPOROBOVAC
Device Model: RV30 Plus(US)
IP: 192.168.1.202
MAC: AC-15-A2-72-B9-84
Device Id (hash): a1e6009e771ecc9876a7b7ad7b282d39
Owner (hash): 48D105C5593D5366DFCE115DCE5C3A06
HW Ver: None
Supports IOT Cloud: True
OBD Src: tplink
Factory Default: False
Encrypt Type: AES
Supports HTTPS: True
HTTP Port: 4433
LV (Login Level): None
dump bombs out pretty early.
Host given, performing discovery on 192.168.1.202.
Traceback (most recent call last):
File "C:\Users\Steve\Documents\Development\python\python-kasa\kasa\deviceconfig.py", line 99, in from_values
DeviceFamilyType(device_family),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\enum.py", line 711, in __call__
return cls.__new__(cls, value)
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\enum.py", line 1128, in __new__
raise ve_exc
ValueError: 'SMART.TAPOROBOVAC' is not a valid DeviceFamilyType
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Steve\Documents\Development\python\python-kasa\kasa\discover.py", line 466, in _get_device_instance
config.connection_type = ConnectionType.from_values(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\python-kasa\kasa\deviceconfig.py", line 104, in from_values
raise KasaException(
kasa.exceptions.KasaException: Invalid connection parameters for SMART.TAPOROBOVAC.AES.None
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\Steve\Documents\Development\python\python-kasa\devtools\dump_devinfo.py", line 696, in <module>
cli()
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\asyncclick\core.py", line 1205, in __call__
return anyio.run(self._main, main, args, kwargs, **opts)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\anyio\_core\_eventloop.py", line 73, in run
return async_backend.run(func, args, {}, backend_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\anyio\_backends\_asyncio.py", line 2001, in run
return runner.run(wrapper())
^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\anyio\_backends\_asyncio.py", line 1989, in wrapper
return await func(*args)
^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\asyncclick\core.py", line 1208, in _main
return await main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\asyncclick\core.py", line 1120, in main
rv = await self.invoke(ctx)
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\asyncclick\core.py", line 1485, in invoke
return await ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\kasaenv\Lib\site-packages\asyncclick\core.py", line 824, in invoke
rv = await rv
^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\python-kasa\devtools\dump_devinfo.py", line 253, in cli
device = await Discover.discover_single(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\python-kasa\kasa\discover.py", line 396, in discover_single
raise protocol.unsupported_device_exceptions[ip]
File "C:\Users\Steve\Documents\Development\python\python-kasa\kasa\discover.py", line 160, in datagram_received
device = Discover._get_device_instance(data, config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Steve\Documents\Development\python\python-kasa\kasa\discover.py", line 472, in _get_device_instance
raise UnsupportedDeviceError(
kasa.exceptions.UnsupportedDeviceError: Unsupported device 192.168.1.202 of type SMART.TAPOROBOVAC with encrypt_type AES
Are you looking to support vacuums in this project? How about Tapo Doorbells? steveredden commented on May 25, 2024 ContributorAuthor More actions vacuum starts with a login POST with MD5 of password and username

response is a token:
{
"error_code": 0,
"result": {
"token": "9A07686B66FB6A4E325DE4250D509B51"
}
}
which is then used in all calls:

rytilahti commented on May 26, 2024 Thanks for the discover output and clarifications!
Looks like the transport protocol is already implemented in this library (aes transport), but this is the first device known to use HTTPS, so some changes might be necessary to support it properly.
Are you looking to support vacuums in this project?
For sure! As adding (at least basic) support should be rather straightforward, I don't personally see any reason not to. If you modify
|
class DeviceFamilyType(Enum): |
to include SMART.TAPOROBOVAC, it shouldn't crash anymore and you could execute commands like kasa command getVacStatus to fetch the state.
If that works, it would be helpful if you could you try kasa command component_nego and kasa command get_device_info commands (or just re-try again with the dump_devinfo, which executes these, too).
How about Tapo Doorbells?
The current master branch has some preliminary support for hubs and some "passive" devices (like temp, door & contact sensors), but there is no support to control device-to-device triggers which is probably required to add proper support for doorbells.
What is already possible with #900 is to poll the event logs, but it'd be great if you could dump traffic what happens when you set up a "doorbell -> do some action". steveredden commented on May 26, 2024 ContributorAuthor More actions your initial hesitations seem to be warranted.
without --port
Host given, performing discovery on 192.168.1.202.
Unknown SMART device with SMART.TAPOROBOVAC, using SmartDevice
Testing component_nego call ..Unable to query component_nego call at once: ('Device connection error: 192.168.1.202: Cannot connect to host 192.168.1.202:80 ssl:default [The remote computer refused the network connection]', ClientConnectorError(ConnectionKey(host='192.168.1.202', port=80, is_ssl=False, ssl=True, proxy=None, proxy_auth=None, proxy_headers_hash=None), ConnectionRefusedError(22, 'The remote computer refused the network connection', None, 1225, None)))
with --port 4433
Host given, performing discovery on 192.168.1.202.
Fatal write error on datagram transport
protocol: <kasa.discover._DiscoverProtocol object at 0x0000021A0F6526D0>
transport: <_ProactorDatagramTransport fd=744 read=<_OverlappedFuture pending cb=[_ProactorDatagramTransport._loop_reading()]>>
Traceback (most recent call last):
File "C:\Python311\Lib\asyncio\proactor_events.py", line 536, in _loop_writing
self._write_fut = self._loop._proactor.sendto(self._sock,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\asyncio\windows_events.py", line 548, in sendto
ov.WSASendTo(conn.fileno(), buf, flags, addr)
TypeError: 'str' object cannot be interpreted as an integer
.
.
.
steveredden commented on May 26, 2024 ContributorAuthor More actions And pardon my misspeaking - I actually meant Tapo Door Locks - they're beta testing them now. rytilahti commented on May 26, 2024 Oops, sorry about that. The linked PR fixes the incorrect type for port number, so the script might work if you apply that patch in your local copy.
However, looking at the first requests in the description, it might be that none of the commands used by the script will yield any results (other devices uses snake_case and the vacuum camelCase for the names like get_device_info and get_components, two commands whose output would interesting), but it's worth trying.
Did you try using kasa command <one of those commands> already or did it have?
On those locks, assuming that they use the same protocol which they likely do, I see why we couldn't add support for those in the future, too. The upcoming 0.7 release makes the library more modularized which open an easy way to support new devices. steveredden commented on May 26, 2024 ContributorAuthor More actions Sent you a discord message: any way to not verify ssl certs? Do we need a new parameter to expose that? steveredden commented on May 26, 2024 ContributorAuthor More actions rytilahti commented on May 26, 2024 We discussed about this on discord, but here's basically what we know:
- Supporting this device requires implementing a new transport class. username + hashed password are send inside https tunnel to the device, which responds with a token that needs to be used for future requests.
- The discovery response says
AES even when the payloads themselves are not encrypted, furthermore, there is no clean indicator for this different transport protocol (besides port number & that it uses https, maybe?).
The method names are camelCased like getDeviceInfo instead of get_device_info. the snake_cased names work also just as well.
The getComponentList responds with a similar payload as component_nego does. component_nego works also, so we just need to implement the new transport protocol & add new modules to support the vacuuming features.
github-actions commented on Sep 28, 2024 There hasn't been any activity on this issue recently. This issue has been automatically marked as stale because of that. It will be closed if no further activity occurs.
Please make sure to update to the latest python-kasa version and check if that solves the issue.
Thank you for your contributions. steveredden commented on Dec 1, 2024 ContributorAuthor More actions Reacted by Teemu R. Reacted by GSzabados rytilahti commented on Jan 15, 2025 Thanks a lot for your input, testing & example commands, @steveredden! I think we now have some sort of implementation for most of the known, interesting commands (be it already merged in, or in open PRs) to fulfill the basic, initial implementation :-)
Notably missing are:
- Child lock
- Spot/zone cleaning
- Do not disturb mode
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|