openrgb_ha icon indicating copy to clipboard operation
openrgb_ha copied to clipboard

'NodeStrClass' object has no attribute 'pack'

Open matthewgrima opened this issue 1 year ago • 13 comments

When trying to apply colors via scenes i get this error. i can change colors directly from the device or entities but scenes have been failing for about a week or so


Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:238
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 09:16:01 (4 occurrences)
Last logged: 09:40:51

[140096035767488] 'NodeStrClass' object has no attribute 'pack'
[140096036210240] 'NodeStrClass' object has no attribute 'pack'
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 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, 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 882, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 952, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/scene/__init__.py", line 114, in _async_activate
    await self.async_activate(**kwargs)
  File "/usr/src/homeassistant/homeassistant/components/homeassistant/scene.py", line 371, in async_activate
    await async_reproduce_state(
  File "/usr/src/homeassistant/homeassistant/helpers/state.py", line 67, in async_reproduce_state
    await asyncio.gather(
  File "/usr/src/homeassistant/homeassistant/helpers/state.py", line 61, in worker
    await platform.async_reproduce_states(
  File "/usr/src/homeassistant/homeassistant/components/light/reproduce_state.py", line 158, in async_reproduce_states
    await asyncio.gather(
  File "/usr/src/homeassistant/homeassistant/components/light/reproduce_state.py", line 145, in _async_reproduce_state
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, 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 882, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 952, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/light/__init__.py", line 624, in async_handle_light_on_service
    await light.async_turn_on(**filter_turn_on_params(light, params))
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1568, in async_turn_on
    await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/openrgb/light.py", line 171, in turn_on
    self._device_turned_on(**kwargs)
  File "/config/custom_components/openrgb/light.py", line 300, in _device_turned_on
    self._set_effect()
  File "/config/custom_components/openrgb/light.py", line 324, in _set_effect
    self._light.set_mode(self._effect)
  File "/usr/local/lib/python3.11/site-packages/openrgb/orgb.py", line 231, in set_mode
    data = mode.pack(self.comms._protocol_version)
           ^^^^^^^^^
AttributeError: 'NodeStrClass' object has no attribute 'pack'

matthewgrima avatar Jan 07 '24 08:01 matthewgrima

Since HA 2024.1.0 scenes are failing for me to. Downgrading to whatever the last of HA 2023.12.X fixes it. So I'm stuck on HA 2023.12.X. Tried HA 2024.1.2 and its the same.

BeardElk avatar Jan 11 '24 21:01 BeardElk

@BeardElk i didn't rollback, switched to using scripts as a workaround

matthewgrima avatar Jan 11 '24 21:01 matthewgrima

@BeardElk i didn't rollback, switched to using scripts as a workaround

I'm to lazy to change anything haha. Was just easier to roll back.

BeardElk avatar Jan 11 '24 21:01 BeardElk

I can confirm I am also getting this since updating to HA 2024.1.0. I am currently on 2024.1.3 and still can't use scenes.

mattboy9921 avatar Jan 18 '24 20:01 mattboy9921

I updated HA yesterday and the same thing started happening. There is a related bug on the Home Assistant side, which is apparently getting fixed in an upcoming release: home-assistant/core#108386

krzys-h avatar Jan 28 '24 20:01 krzys-h

This issue is still present in 2024.2.0, apparently nothing has changed so far

taita2104 avatar Feb 08 '24 00:02 taita2104

I can confirm the issue is still present in 2024.2.1 as well.

mattboy9921 avatar Feb 14 '24 15:02 mattboy9921

@BeardElk i didn't rollback, switched to using scripts as a workaround

Hello, how can the scripts be used? The scripts don't work for me.

Otherwise does it work for anyone else?

Arnavisca avatar Mar 22 '24 16:03 Arnavisca

@Arnavisca

Hello, how can the scripts be used? The scripts don't work for me.

Otherwise does it work for anyone else?

Scripts works for me. Create a script in single mode, set service to "light: turn on", select openrgb instance and select the color you want. Then, in the automation that controls the scene, add "call service", select service "Script: Turn on" and select the script you want to turn on.

BeardElk avatar Mar 22 '24 16:03 BeardElk

@Arnavisca

Hello, how can the scripts be used? The scripts don't work for me. Otherwise does it work for anyone else?

Scripts works for me. Create a script in single mode, set service to "light: turn on", select openrgb instance and select the color you want. Then, in the automation that controls the scene, add "call service", select service "Script: Turn on" and select the script you want to turn on.

I had another problem with openrgb, but now it works for me now. Thanks a lot

Arnavisca avatar Mar 23 '24 11:03 Arnavisca

scripts not working for me

emerysteele avatar Mar 31 '24 17:03 emerysteele

@emerysteele scripts not working for me

How are they not working? What is not working? Aint much to go on with "not working for me".

BeardElk avatar Mar 31 '24 17:03 BeardElk

I finally got tired of this being broken for 2 months and decided to debug it myself.

The main bug comes from this section of openrgb-python code:

https://github.com/jath03/openrgb-python/blob/8b6aed80bccfffc5722b6f5687598d23b33d7575/openrgb/orgb.py#L222-L230

This method can take an int, str or a utils.ModeData class, but it doesn't handle the case where the argument is neither of these things, and takes the utils.ModeData path in that case. Additionally, it checks for an exact match of the type, instead of using isinstance, which means the check doesn't support inheritance.

After some changes in HA 2024.1.0 (which I didn't manage to track down), the scene apply code passes a NodeStrClass object instead of raw str to the integration. NodeStrClass is a subclass of str with additional metadata about where in the yaml config the value came from. This explains why it works from the UI, but doesn't work with scenes - the effect name from the UI does not have a config file location. Scripts likely work only as long as you are not trying to set an effect in the light.turn_on call (but I didn't verify that).

The HA team is likely aware of the possible issues related to this change (judging by random fix str subclass handling commits I've seen), and they attempted to address it more generally in home-assistant/core#107139, but for whatever reason that fix doesn't seem to change anything here.

As a temporary fix, you can patch custom_components/openrgb/light.py as follows:

--- ./custom_components/openrgb/light.py~
+++ ./custom_components/openrgb/light.py
@@ -321,7 +321,7 @@
     def _set_effect(self):
         """Set the devices effect."""
         try:
-            self._light.set_mode(self._effect)
+            self._light.set_mode(str(self._effect))
         except ConnectionError:
             self.hass.data[DOMAIN][self._entry_id]["connection_failed"]()
 

However, the more proper fix would be to either fix the type checks in openrgb-python, or make HA send a plain str to the integration like it used to (or ideally both).

krzys-h avatar Mar 31 '24 21:03 krzys-h