humbertogontijo / python-roborock Goto Github PK
View Code? Open in Web Editor NEWPython library & console tool for controlling Roborock vacuum
License: GNU General Public License v3.0
Python library & console tool for controlling Roborock vacuum
License: GNU General Public License v3.0
I tried to use the roborock intergration with home-assistant, but I find that I can't do the app_segment_clean. I can (through HA at least) start, stop, make the robot go back home .... but when I try to send a app_segment_clean command it fails
The logs say something along:
Jul 30 13:43:27 <host> hass[11089]: raise RoborockTimeout(f"Timeout after {QUEUE_TIMEOUT} seconds waiting for response") from None
Jul 30 13:43:27 <host> hass[11089]: roborock.exceptions.RoborockTimeout: Timeout after 4 seconds waiting for response
(my robot is a Roborock S6 Pure)
When I was originally testing and the prefix was wrong for setting the fan, it would give me a timeout error every 4 seconds. I'm not sure if that was just because the command was wrong or if there was something else going on. If you have any ideas/ want to test as well, that would probably be good.
I thought about adding a timeout limit in the socket controller. If it times out three times in a row, then it will disconnect and reconnect. Not sure if that actually would fix the problem though. Wanted to hear your opinion.
Hi,
Python 3.12 is dropping the 'imp' module.
There is a way to avoid using it ?
Thx
Hicham
I plan to handle this but I just wanted to write this so I remember as I removed it from the Core integration
Comment from core maintainer
Does this timeout countdown logic do anything? It appears to reset the count every time update is called, then decrement in the exception below. But then on the next call its going to reset again.
I'd rather not have this if possible. If there is special handling needed because roborock connections are flaky then perhaps they should be handled in the underlying library. Is this just here because there is an extremely short polling interval?
If timeout is a reminant of an old bug, I wont add it back to the api at all.
Obviously something has changed in the protocol and map retrieval does not work with this model.
How can I help getting this updated? I already set up packet capture and looked into it but I have no idea what could be of interest (but I assume it's the MQTT comms)
Hi !
I recently acquired a Roborock Q REVO and I'm looking for assistance regarding some missing information or commands in the Home Assistant component.
When I attempt to query my vacuum, I don't receive any response:
5820T:~/HomeAssistant$ roborock command --device_id *************** --cmd get_status
INFO:roborock.cloud_api:[Withee] Connecting to mqtt
INFO:roborock.cloud_api:[Withee] Starting mqtt loop
INFO:roborock.cloud_api:[Withee] Connected to mqtt mqtt-eu-5.roborock.com:8883
INFO:roborock.cloud_api:[Withee] Subscribed to topic rr/m/o/*****************/*********/******************
INFO:roborock.cloud_api:[Withee] Disconnecting from mqtt
What might I be doing wrong? Is there something that's missing?
I am trying to update this in hopes it will fix the issue of the HACS roborock failing to initialize. It was working before but seems like the update messed it up. When I run
pip install python-roborock
I get
pip: command not found
Any help appreciated
hi, have sing your pip install python-roborock with terminal..
where i found the gui or card for start?
using roborock Q7max
your other intecration is also nor working since ca. 2 months
error: Deinem Account ist kein Gerät zugeordnet
Please add support for Roborock S8 MaxV Ultra which identifies in Home Assistant as 'roborock.vacuum.a97'.
There seems to be some new codes that are currently not defined and set to some defaults:
2024-05-02 12:14:49.564 WARNING (MainThread) [roborock.code_mappings] Missing RoborockFanSpeedS7MaxV code: 110 - defaulting to 105
2024-05-02 12:14:49.564 WARNING (MainThread) [roborock.code_mappings] Missing RoborockMopIntensityS7 code: 209 - defaulting to 200
2024-05-02 12:14:49.565 WARNING (MainThread) [roborock.code_mappings] Missing RoborockDockTypeCode code: 10 - defaulting to 'unknown'
2024-05-02 12:14:49.565 WARNING (MainThread) [roborock.code_mappings] Missing RoborockMopModeS7 code: 306 - defaulting to 300
Not a defect, but since there's no section to discuss, I'm asking this here.
I've looked over the API commands, and I didn't see anything that would instruct the vacuum to switch the map. I have 2 maps saved (one for each floor), and I'l like the vacuum to use 1 map or the other when cleaning, but not sure how to do that. Thanks!
I have some problem to understand how work the documentation...
Should be compiled?
Anyway reading the files in source directory as plain text i was able to connect to my Roborock S7 And start the cleaning or clean a single room.
My goal is send the roborock to a position that should be possible with:
app_goto_target but how can I understand wich is che x coord and y coord of the place?
and clean a small zone. Is this possible?
Regards.
Enrico.
Recently switched from the Xiaomi Mii integration in HA to Roborock. So far everything is working great. However I am currently lacking the total amount of cleans done by my Roborock vacuum cleaner. I had an automation running which would move the vacuum cleaner to a specific spot, each time the total amount of cleans could be divided by 3. Roughly after 3 cleans, I want to empty it's bin, that's why.
As far as I can get from the documentation, this number is not yet returned? Or am I unable to find it? Else I could give it a go implementing it within Home Assistant.
Other integrations cause issues with dacite sometimes, the easiest solution is likely just to remove it and replace it with another module such as pydantic.
Working with a Roborock S7 MaxV Ultra here.
containers.py calculates strainer_time_left
as STRAINER_REPLACE_TIME - self.strainer_work_times
, where STRAINER_REPLACE_TIME == 540000
. I'm not sure where the value for STRAINER_REPLACE_TIME
came from, but code comments indicate that it's a value measured in seconds.
On my machine, the consumable strainer_work_times
seems to count up the number of times the water filter has been used. The last time I needed to reset the Water Filter in the Roborock app, 'strainer_work_times' was 184, which is much less than 540000.
Is STRAINER_REPLACE_TIME
just a placeholder value, or does it work differently on the Roborock S8 Pro Ultra?
It appears 0.17.2 is not available on pypi so when attempting to run the latest version of homeassistant-roborock from main, it fails since it can't find 0.17.2. I see 0.17.1 is available which was pushed around the same time so not sure if something is stuck on pipits side with 0.17.2?
Can someone help me with this error?
i am connected, can list devices and also send commands.
e.g. with test_sound_volume, the command runs (robot beeps) but it shows following error:
openhabian@pi4openhabian:~ $ /home/openhabian/rr/bin/roborock command --device_id 50XLKow9WZEjW4ssq6yexf --cmd test_sound_volume
INFO:roborock.cloud_api:Connecting to mqtt
INFO:roborock.cloud_api:Starting mqtt loop
INFO:roborock.cloud_api:Connected to mqtt mqtt-eu.roborock.com:8883
INFO:roborock.cloud_api:Subscribed to topic rr/m/o/onj7tEVB5eG3Uel6HHXVf/9369796a/50XLKow9WZEjW4ssq6yexf
Traceback (most recent call last):
File "/home/openhabian/rr/bin/roborock", line 8, in <module>
sys.exit(main())
File "/home/openhabian/rr/lib/python3.9/site-packages/roborock/cli.py", line 200, in main
return cli()
File "/home/openhabian/rr/lib/python3.9/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
File "/home/openhabian/rr/lib/python3.9/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
File "/home/openhabian/rr/lib/python3.9/site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/openhabian/rr/lib/python3.9/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/openhabian/rr/lib/python3.9/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
File "/home/openhabian/rr/lib/python3.9/site-packages/click/decorators.py", line 33, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/openhabian/rr/lib/python3.9/site-packages/roborock/util.py", line 65, in wrapped
return loop.run_until_complete(func(*args, **kwargs))
File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/openhabian/rr/lib/python3.9/site-packages/roborock/cli.py", line 139, in command
await mqtt_client.send_command(cmd, json.loads(params) if params is not None else None)
File "/home/openhabian/rr/lib/python3.9/site-packages/roborock/cloud_api.py", line 168, in send_command
self._diagnostic_data[method.name] = {"params": params, "response": response, "error": err}
AttributeError: 'str' object has no attribute 'name'
Seemingly Roborock has rolled out a new api version for the /user/homes/{home_id} request. It is now /v2/user/homes/{home_id}
It uses the same hawk authentication method, butI have been getting invalid token error when I have been trying. I will continue to figure out why, but if you wanted to take a look as well @humbertogontijo, more eyes would be nice.
Basically we want this for 2 reasons:
In case they depreciate v1 of the api
Some of the newer non-robot vacuum devices are received from this api.
Let me know if you figure anything out
I don't know the exact steps to reproduce this, but noticed this while changing a device settings in HomeAssistant. It seems like this is an internal consistency issue and not something that that the caller should be able to introduce, but i'm not positive.
2024-08-20 03:49:28.365 ERROR (MainThread) [homeassistant] Error doing job: Exception in callback RoborockFuture._resolve((None, None)) (None): File "/usr/local/lib/python3.12/asyncio/base_events.py", line 639, in run_forever
self._run_once()
File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1977, in _run_once
handle._run()
File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 970, in _read_ready
self._read_ready_cb()
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1027, in _read_ready__data_received
self._protocol.data_received(data)
File "/home/vscode/.local/lib/python3.12/site-packages/roborock/local_api.py", line 39, in data_received
self.on_message_received(parser_msg)
File "/home/vscode/.local/lib/python3.12/site-packages/roborock/version_1_apis/roborock_client_v1.py", line 444, in on_message_received
queue.resolve((data.payload, None))
File "/home/vscode/.local/lib/python3.12/site-packages/roborock/roborock_future.py", line 22, in resolve
self.loop.call_soon_threadsafe(self._resolve, item)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/home/vscode/.local/lib/python3.12/site-packages/roborock/roborock_future.py", line 19, in _resolve
self.fut.set_result(item)
asyncio.exceptions.InvalidStateError: invalid state
I believe this happened when i adjusted the same property two times in a row in a short succession (with a short pause between)
@humbertogontijo Not sure about this one as I've never really used new functionality before, so not sure the best approach to fix.
But compilers don't realize that RoborockCode has subscriptable functionality or values() or items()
Unless if I'm doing something wrong, VS code yells at me for attempting to do any of that (but it still works)
Until yesterday, I had string based vacuum statuses in Home Assistant, now I have int statuses. I believe this is because the model string for my S8 Pro Ultra is incorrect in the library.
this line https://github.com/humbertogontijo/python-roborock/blob/main/roborock/const.py#L33 should be roborock.vacuum.a70
for the new S8 Pro Ultra
The readme says it's possible to send commands locally. How do I do that?
The app can also send audio messages to the robot.
Has anybody managed to do this via an api yet?
Would be cool to send prerecorded messages or TTS generated messages to the robot
Could you please tag the source again? This allows distributions to get the complete source from GitHub if they want.
This was done till 0.23.6. the latest release on PyPI is 0.24.1.
Thanks
Hey there! I'm wondering whether supporting the Roborock Zeo One washer / drier is at all planned or even considered in-scope for this package. It'd be amazing if this would eventually be supported, maybe at least with a limited feature set (e.g. remote start).
The Zeo One uses the same Roborock app as the vacuums supported by this package already. The interface appears relatively simple compared to the vacuums — within the app, you can only view the current status, select a program, start / stop / pause if remote control has been enabled on the appliance, and set a few settings that aren't all that important (detergent auto dosing etc).
I own a Zeo One and would be more than happy to support with reverse-engineering and, assuming you consider it in-scope, maybe even give it a shot myself, though I have very limited python experience.
I am going to continue to progress the documentation over the next few weeks. Do you guys have any preference on the order of APIs to focus on ? My preference in the absence of any is the remote control and maps with picking up low hanging fruit as I see them
Additionally if you feel it is appropriate I will flesh out a page on using the parser command and what it takes to get it configured. (for IOS anyway)
roborock parser
With your ok, I will also look at extending parser to capture output to file which can then be post processed to help analyse
Could you please provide an example of using app_segment_clean?
I get an error every time. No matter which syntax I use.
For Example
roborock -d command --device_id xyxyxyxyxyxyxyxyxyx --cmd app_segment_clean --params "[23]"
DEBUG:roborock.cloud_api:id=79354 Requesting method app_segment_clean with [23]
roborock.exceptions.VacuumError: (-10005, 'Param is not an array')
roborock -d command --device_id xyxyxyxyxyxyxyxyxyx --cmd app_segment_clean --params '[{"segments":[23],"repeat":2}]'
DEBUG:roborock.cloud_api:id=40826 Requesting method app_segment_clean with [{"segments":[23],"repeat":2}]
roborock.exceptions.VacuumError: (-10005, 'Param is not an array')
My room mapping looks like this:
DEBUG:roborock.cloud_api:id=75853 Response from get_room_mapping: [[16, '12105189'], [18, '12105192'], [19, '12105181'], [20, '12105179'], [21, '12105183'], [22, '12105185'], [23, '12105177'], [24, '12105187']]
And how could I do local commands without the cloud_api?
Thanks in advance for your time
@Lash-L @humbertogontijo
Is there a command that would allow me to engage the auto-empty? Since I schedule the vacuum during DND period, I need to run an empty bin cycle, but the app doesn't allow me to schedule that, so I'm looking to use HA instead.
I used the instructions to setup an automation to clean a single room. I've looked through all of the documentation, but I am unsure how to make it only vacuum and not mop. Here's the yaml so far:
service: vacuum.send_command
target:
entity_id: vacuum.roborock_s8_pro_ultra
data:
command: app_segment_clean
params:
- segments:
- 16
repeat: 1
Response error after 0.23.0 -> (Add diagnostic data and extra containers (#67) (59ef6f4))
The command is executed without any problems, but there is an error with the response.
This happens with commands with as well as without params
or -d
# roborock -d command --device_id [redacted] --cmd set_water_box_custom_mode --params '[200]'
INFO:roborock.cloud_api:Connecting to mqtt
INFO:roborock.cloud_api:Starting mqtt loop
INFO:roborock.cloud_api:Connected to mqtt mqtt-eu-5.roborock.com:8883
INFO:roborock.cloud_api:Subscribed to topic [redacted]
DEBUG:roborock.cloud_api:id=21855 Requesting method set_water_box_custom_mode with [200]
Traceback (most recent call last):
File "/usr/local/bin/roborock", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.10/dist-packages/roborock/cli.py", line 200, in main
return cli()
File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1130, in __call__
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1055, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/click/decorators.py", line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/roborock/util.py", line 65, in wrapped
return loop.run_until_complete(func(*args, **kwargs))
File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/usr/local/lib/python3.10/dist-packages/roborock/cli.py", line 139, in command
await mqtt_client.send_command(cmd, json.loads(params) if params is not None else None)
File "/usr/local/lib/python3.10/dist-packages/roborock/api.py", line 267, in send_command
response = await self._send_command(method, params)
File "/usr/local/lib/python3.10/dist-packages/roborock/cloud_api.py", line 167, in _send_command
self._diagnostic_data[method.name] = {"params": params, "response": response, "error": err}
AttributeError: 'str' object has no attribute 'name'
For the S7 MaxV Ultra, cleaning the mop can cause two errors not currently handled. For both errors, the code may mean the tank is missing, empty, or has some other issue.
38 - Clean water tank error.
39 - Dirty water tank error.
My phone roborock app displays the battery percentage is there any chance at getting this data?
Hey! so in working on the core integration, I realized that releasing the api fails with a timeout error.
on_disconnect does not get called until after async disconnect calls async response which then calls queue.async_get. No matter what time I give the queue, it ends up timing out and once it is finished, then on_disconnect is called and the object is added to the queue.
I assume it is something with the run_in_executor decorator? But I really don't know, so I figured I would bring it up and maybe you would have an idea.
I noticed the following error in my Home Assistant log.
Unexpected error fetching roborock data
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 312, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/roborock/coordinator.py", line 102, in _async_update_data
await asyncio.gather(*(self._update_device_prop(), self.get_rooms()))
File "/usr/src/homeassistant/homeassistant/components/roborock/coordinator.py", line 92, in _update_device_prop
device_prop = await self.api.get_prop()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/roborock/version_1_apis/roborock_client_v1.py", line 266, in get_prop
status, clean_summary, consumable = await asyncio.gather(
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/roborock/version_1_apis/roborock_client_v1.py", line 186, in get_clean_summary
return CleanSummary(
^^^^^^^^^^^^^
File "<string>", line 10, in __init__
File "/usr/local/lib/python3.12/site-packages/roborock/containers.py", line 602, in __post_init__
self.square_meter_clean_area = round(self.clean_area / 1000000, 1) if self.clean_area is not None else None
~~~~~~~~~~~~~~~~^~~~~~~~~
TypeError: unsupported operand type(s) for /: 'list' and 'int'
Hi,
I have S8 model and two maps (below get_room_mapping response):
For first floor map: [[16, '13298627', 6], [17, '13300060', 14], [18, '13304622', 12], [19, '13300068', 12], [20, '13300064', 8]]
For second floor map: [[16, '13306813', 1], [17, '13306835', 12], [18, '13306828', 8], [19, '13306836', 9], [20, '13306839', 12], [21, '13306837', 15]]
The numbers are slightly different than in the docs because they have three digits. I think first is connected with the segment. So there are rooms like 16,17,18,19...
As you can see the number represents particular segments repeats in first and second floor. So How can I tell that I would like to clean e.g. segment 17 on the second floor (in second map)? I do not see the option in app_segment_clean command to pass something like map id...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.