GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

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) #937

New issue
Copy link
New issue
Copy link
Closed
#944
Closed
dumping HTTP POST Body for Tapo Vacuum (RV30 Plus)#937
#944
Copy link
Labels
enhancementNew feature or requestNew feature or requestno-stale

Description

@steveredden
steveredden
opened on May 25, 2024
Issue body actions

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

Next
  1. rytilahti commented on May 25, 2024

    @rytilahti
    rytilahti
    on May 25, 2024
    Member
    More actions

    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

    @steveredden
    steveredden
    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?

  3. steveredden commented on May 25, 2024

    @steveredden
    steveredden
    on May 25, 2024
    ContributorAuthor
    More actions

    vacuum starts with a login POST with MD5 of password and username

    image

    response is a token:

    {
        "error_code": 0,
        "result": {
            "token": "9A07686B66FB6A4E325DE4250D509B51"
        }
    }
    

    which is then used in all calls:

    image

  4. rytilahti commented on May 26, 2024

    @rytilahti
    rytilahti
    on May 26, 2024
    Member
    More actions

    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

    python-kasa/kasa/deviceconfig.py

    Line 31 in 7671564

    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

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

    @steveredden
    steveredden
    on May 26, 2024
    ContributorAuthor
    More actions

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

  7. rytilahti commented on May 26, 2024

    @rytilahti
    rytilahti
    on May 26, 2024
    Member
    More actions

    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

    @steveredden
    steveredden
    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?

  9. steveredden commented on May 26, 2024

    @steveredden
    steveredden
    on May 26, 2024
    ContributorAuthor
    More actions

    attaching common request + responses

    responses.zip

  10. rytilahti commented on May 26, 2024

    @rytilahti
    rytilahti
    on May 26, 2024
    Member
    More actions

    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. rytilahti
    added
    enhancementNew feature or requestNew feature or request
    on May 26, 2024
  12. github-actions commented on Sep 28, 2024

    @github-actions
    github-actionsBot
    on Sep 28, 2024 – with GitHub Actions
    More actions

    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.

  13. github-actions
    added
    stale
    on Sep 28, 2024
  14. github-actions
    closed this as not plannedon Oct 6, 2024
  15. rytilahti
    reopened this on Oct 6, 2024
  16. 3 remaining items

  17. steveredden commented on Dec 1, 2024

    @steveredden
    steveredden
    on Dec 1, 2024
    ContributorAuthor
    More actions

    some more reverse engineered methods
    more methods.txt

    Reacted by Teemu R.
    Reacted by GSzabados
  18. rytilahti
    linked a pull request that will close this issueInitial support for vacuums (clean module) #944on Jan 14, 2025
  19. rytilahti
    closed this as completedin #944on Jan 14, 2025
  20. rytilahti commented on Jan 15, 2025

    @rytilahti
    rytilahti
    on Jan 15, 2025
    Member
    More actions

    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
    Reacted by GSzabados
  21. sdb9696
    added a commit that references this issue on Jan 26, 2025

    Prepare 0.10.0 (#1473)

    09e73fa
  22. rytilahti
    added 2 commits that reference this issue on Aug 31, 2025

    Add ssltransport for robovacs (python-kasa#943)

    8bc4ebd

    Prepare 0.10.0 (python-kasa#1473)

    a11b953
  23. rytilahti
    added 2 commits that reference this issue on Oct 26, 2025

    Add ssltransport for robovacs (python-kasa#943)

    3e655e0

    Prepare 0.10.0 (python-kasa#1473)

    4577b2c
  24. rytilahti
    added 2 commits that reference this issue on Nov 10, 2025

    Add ssltransport for robovacs (python-kasa#943)

    e3192c3

    Prepare 0.10.0 (python-kasa#1473)

    2382821
  25. rytilahti
    added 2 commits that reference this issue on Jul 5, 2026

    Add ssltransport for robovacs (python-kasa#943)

    8a5144d

    Prepare 0.10.0 (python-kasa#1473)

    309dc46
  26. pillarsdotnet
    added 2 commits that reference this issue on Oct 22, 2026

    Add ssltransport for robovacs (python-kasa#943)

    0dc5244

    Prepare 0.10.0 (python-kasa#1473)

    e37cf64
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

    enhancementNew feature or requestNew feature or requestno-stale

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.