FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

dumping HTTP POST Body for Tapo Vacuum (RV30 Plus) · Issue #937 · python-kasa/python-kasa · GitHub

Repository navigation

dumping HTTP POST Body for Tapo Vacuum (RV30 Plus) #937

Closed

Description

MITM 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
                }
            }
        ]
    }
}

Activity

  1. rytilahti commented on May 25, 2024

    Member

    Nice! Would you mind trying kasa --debug discover and post the discovery payload, or even trying to obtain a fixture dump (https://python-kasa.readthedocs.io/en/latest/contribute.html#contributing-fixture-files)?

  2. steveredden commented on May 25, 2024

    ContributorAuthor
    == 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?

  3. steveredden commented on May 25, 2024

    ContributorAuthor

    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:

  4. rytilahti commented on May 26, 2024

    Member

    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".

  5. steveredden commented on May 26, 2024

    ContributorAuthor

    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
    .
    .
    .
    
  6. steveredden commented on May 26, 2024

    ContributorAuthor

    And pardon my misspeaking - I actually meant Tapo Door Locks - they're beta testing them now.

  7. rytilahti commented on May 26, 2024

    Member

    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.

  8. steveredden commented on May 26, 2024

    ContributorAuthor

    Sent you a discord message: any way to not verify ssl certs? Do we need a new parameter to expose that?

  9. steveredden commented on May 26, 2024

    ContributorAuthor

    attaching common request + responses

    responses.zip

  10. rytilahti commented on May 26, 2024

    Member

    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.
  11. 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.

  12. 3 remaining items

  13. steveredden commented on Dec 1, 2024

    ContributorAuthor

    some more reverse engineered methods
    more methods.txt

  14. linked a pull request that will close this issueInitial support for vacuums (clean module) #944on Jan 14, 2025
  15. rytilahti commented on Jan 15, 2025

    Member

    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
  16. added a commit that references this issue on Jan 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL