core
core copied to clipboard
Dict key must be str when sending parameters
The problem
When attempting to send param data via an automation it consistently throws an error that Dict key must be str. Oddly enough if I send the same command via the services menu in the UI it works. I don't actually believe this is an issue with the iRobot integration but something else upstream with how it is the parsing data but is the only integration I've ran into this issue on thus far.
Services UI (Works):
service: vacuum.send_command
target:
entity_id: vacuum.basement_roomba
data:
command: start
params:
pmap_id: snnFyIYBTzmsjnbyPbW64R
regions:
- region_id: "2"
type: rid
Automation (Does Not Work):
- service: vacuum.send_command
data:
command: start
params:
ordered: '1'
pmap_id: snnFyIYBTzmsjnbyPbW64R
regions:
- region_id: '7'
type: rid
target:
entity_id: vacuum.basement_roomba
Automation - Reformatting the param payload (Does Not Work):
- service: vacuum.send_command
data:
command: start
params: {"pmap_id": "snnFyIYBTzmsjnbyPbW64R", "regions": [{"region_id": "7", "type": "rid"}]}
target:
entity_id: vacuum.basement_roomba
I've attempted various methods of putting quotes or apostrophe around the pmap_id with no luck.
When I put {"pmap_id": "snnFyIYBTzmsjnbyPbW64R", "regions": [{"region_id": "7", "type": "rid"}]} into the template tool in the UI it reports it back as a string.
I've read through the various release notes and changes and couldn't find a documented reason this would no longer function as it did previously.
What version of Home Assistant Core has the issue?
core-2023.12.0
What was the last working version of Home Assistant Core?
core-2023.11.3
What type of installation are you running?
Home Assistant Container
Integration causing the issue
Robot Roomba and Braava
Link to integration documentation on our website
https://www.home-assistant.io/integrations/roomba/
Diagnostics information
No response
Example YAML snippet
- service: vacuum.send_command
data:
command: start
params:
ordered: '1'
pmap_id: snnFyIYBTzmsjnbyPbW64R
regions:
- region_id: '7'
type: rid
target:
entity_id: vacuum.basement_roomba
- service: vacuum.send_command
data:
command: start
params: {"pmap_id": "snnFyIYBTzmsjnbyPbW64R", "regions": [{"region_id": "7", "type": "rid"}]}
target:
entity_id: vacuum.basement_roomba
Anything in the logs that might be useful for us?
2023-12-08 11:59:55.529 ERROR (MainThread) [homeassistant.components.automation.roomba_run_upstairs_roomba_in__office] While executing automation automation.roomba_run_upstairs_roomba_in_office
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/automation/__init__.py", line 655, in async_trigger
await self.action_script.async_run(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
return await asyncio.shield(run.async_run())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
await self._async_step(log_exceptions=False)
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
self._handle_exception(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
raise exception
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
response_data = await self._async_run_long_action(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
return long_task.result()
^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2067, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2104, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 272, in handle_service
return await service.entity_service_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 878, in entity_service_call
single_response = await _handle_entity_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
result = await task
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/roomba/irobot_base.py", line 266, in async_send_command
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/roombapy/roomba.py", line 224, in send_command
str_command = orjson.dumps(roomba_command).decode("utf-8")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Dict key must be str
Additional information
I have a feeling that the following issues might be related, I tried the changes in https://github.com/home-assistant/core/pull/105314 but that did not fix it.
https://github.com/home-assistant/core/issues/105309 https://github.com/home-assistant/core/issues/105315 https://github.com/home-assistant/core/pull/105314 https://github.com/home-assistant/core/issues/105318
Hey there @pschmitt, @cyr-ius, @shenxn, @xitee1, mind taking a look at this issue as it has been labeled with an integration (roomba) you are listed as a code owner for? Thanks!
Code owner commands
Code owners of roomba can trigger bot actions by commenting:
@home-assistant closeCloses the issue.@home-assistant rename Awesome new titleRenames the issue.@home-assistant reopenReopen the issue.@home-assistant unassign roombaRemoves the current integration label and assignees on the issue, add the integration domain after the command.@home-assistant add-label needs-more-informationAdd a label (needs-more-information, problem in dependency, problem in custom component) to the issue.@home-assistant remove-label needs-more-informationRemove a label (needs-more-information, problem in dependency, problem in custom component) on the issue.
(message by CodeOwnersMention)
roomba documentation roomba source (message by IssueLinks)
Facing the same issue with my automation.
I worked around it in a much more complicated way. I used some python scripts that ties into input booleans per room, when toggled on and the script is executed it cleans those rooms in that order. The automations just toggle on those input booleans and execute the script. It gave me a way to setup room cleaning in the UI and worked around this problem for now.
Just make sure the input booleans are created and update the python scripts to utilize your RID or ZIDs, input boolean entity names, Roomba entity name, and the pmap_id.
I think this is a larger change with how strings are being interpreted in automations, I just worked around it for now until I can find more time to look into it further. I'm not even sure I know where the change happened at this point.
I am having the exact same issue - kindly let me know how I can help troubleshoot
Have the same problem here, roomba cleaner is no more able to work
Same problem!
I think this may have been resolved with the 2023.12.3 patch. I just updated and I’m able to send commands now.
(Mentioning @geekofweek @ugomark @khorchanov @nk3750 @jeeftor for posterity, since this was pretty frustrating to try to troubleshoot for me, and this latest update fixed it)
Agreed, seems to be working on 2023.12.3, thanks folks!
Fun fact, nothing really changed in 2023.12.3
Appears that 2023.12.3 resolves it. Will open a new case if the problem persists in the future.
@geekofweek fyi I have 2023.12.3 and the problem is still there :(
Ah no, my bad, I ran the vaccum: send command service on the "run" option and that actually works fine when you test it:
But if it's called from an automation, I keep getting the same error:
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 878, in entity_service_call
single_response = await _handle_entity_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
result = await task
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/roomba/irobot_base.py", line 266, in async_send_command
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/roombapy/roomba.py", line 224, in send_command
str_command = orjson.dumps(roomba_command).decode("utf-8")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Dict key must be str
2023.12.3 and the problem is still there with an automation
I'll reopen since I don't see any code change that would've fixed this and people are reporting it's not working
For me this error appears when i run the command to start roomba with params in a script. When executing the same command directly in a Dashboard-Button it works just fine. Strange Also same as above when running the sequence alone from the ui.
Script (Not Working):
alias: asdf
sequence:
- service: vacuum.send_command
target:
entity_id: vacuum.roomba
data:
command: start
params:
pmap_id: asdf
regions:
- region_id: "asdf"
type: rid
user_pmapv_id: asdf
mode: single
icon: mdi:robot-vacuum-variant
Dashboard-Button (Working):
show_name: true
show_icon: true
type: button
tap_action:
action: call-service
service: vacuum.send_command
target:
entity_id: vacuum.roomba
data:
command: start
params:
pmap_id: asdf
regions:
- region_id: "asdf"
type: rid
user_pmapv_id: asdf
I have the same as oliverhildner. Everything works when executing command via a button, but when calling a script to run the same commands, it throws an error.
Running on 2023.12.3 (edit: correct script tag used)
Script:
vacuum_clean_area:
description: "Set the correct area and start cleaning"
sequence:
- service: input_select.select_option
data:
option: "{{ area }}"
target:
entity_id: input_select.vacuum_areas
- service: vacuum.send_command
data:
entity_id: vacuum.assepoets
command: start
params:
pmap_id: "{{ pmap_id }}"
regions: "{{ regions }}"
user_pmapv_id: "{{ user_pmapv_id }}"
mode: single
icon: mdi:vacuum-outline
Lovelace:
service: script.vacuum_clean_area
data:
area: "Boven"
pmap_id: "----"
regions:
- region_id: '1' # Gang
type: rid
- region_id: '10' # Slaapkamer
type: rid
- region_id: '8' # Babykamer
type: rid
- region_id: '9' # Logeerkamer
type: rid
user_pmapv_id: "----"
Maybe it's also notable to say that this error appears only when any parameter is added to the command. So executing the script without any params works. But unfortunately they are neccessary for the script to make sense in this case.
Just adding another voice to this conversation. I, too, have this issue and I've only now noticed it because I've been away from home for several weeks.
Same here..
sequence:
- service: vacuum.send_command
target:
device_id: xyz
data:
command: start
params:
pmap_id: xyz
regions:
- region_id: "10"
type: rid
mode: single
icon: mdi:robot-vacuum
2023-12-23 14:31:58.739 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [544259798720] Dict key must be str
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 238, in handle_call_service
response = await hass.services.async_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2067, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2104, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 605, in _service_handler
response = await self._async_start_run(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 563, in _async_start_run
script_result = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 594, in _async_run
return await self.script.async_run(script_vars, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
return await asyncio.shield(run.async_run())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
await self._async_step(log_exceptions=False)
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
self._handle_exception(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
raise exception
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
response_data = await self._async_run_long_action(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
return long_task.result()
^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2067, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2104, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 272, in handle_service
return await service.entity_service_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 878, in entity_service_call
single_response = await _handle_entity_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
result = await task
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/roomba/irobot_base.py", line 266, in async_send_command
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/roombapy/roomba.py", line 224, in send_command
str_command = orjson.dumps(roomba_command).decode("utf-8")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Dict key must be str
I am very much confused by this issue. The issue itself sounds like something is wrong with HA. When we look at the logs, it looks like we are sending something invalid to the library.
There is debug logging that logs the command being sent to the roomba. I tried both ways with logging and to my surprise:
2023-12-26 16:57:52.300 DEBUG (MainThread) [homeassistant.components.roomba.irobot_base] async_send_command start ({'pmap_id': 'snnFyIYBTzmsjnbyPbW64R', 'regions': [{'region_id': '2', 'type': 'rid'}]}), {}
2023-12-26 16:57:52.301 DEBUG (SyncWorker_12) [roombapy.roomba] Send command: start
2023-12-26 16:58:33.034 DEBUG (MainThread) [homeassistant.components.roomba.irobot_base] async_send_command start ({'pmap_id': 'snnFyIYBTzmsjnbyPbW64R', 'regions': [{'region_id': '2', 'type': 'rid'}]}), {}
2023-12-26 16:58:33.037 DEBUG (SyncWorker_1) [roombapy.roomba] Send command: start
They both send exactly the same data. So I am a bit weirded out on why this happens. I can't dig deeper as I am not on my main dev pc. But I will try to look into this somewhere soon
The reason behind this error is that orjson doesn't support subclasses of str. See https://github.com/ijl/orjson/issues/446 for more info. The key of the dict is of type NodeStrClass instead of str, I'll ask around
I’ll take a look in the morning as it’s too late now for me
https://github.com/pschmitt/roombapy/pull/214 should fix the issue once its merged, released, and bumped in HA
You guys are the best, thank you! Can't wait for it to be in the next update :P
Heads up! This fix has been merged in the 2024.1 update that is rolling out now.
Ha... it's release day I didn't even realize! :)
Seems to be working now! Thanks for the quick (and not easy) fix!
thank you guys, working like a charm again!