cryptk / haomnilogic-local

A Home Assistant integration for Hayward OmniLogic/OmniHub pool controllers using the local UDP api
Apache License 2.0
19 stars 4 forks source link

Error with ColorLogic Lights #118

Open hoagea opened 3 months ago

hoagea commented 3 months ago

When trying to turn on the lights I get an error in HA that says _Failed to call service light/turnon. 'int' object has no attribute 'value' I get a similar error when trying to turn off the lights... in addition despite lights being in an on status the switch in HA is showing them as off.

home-assistant_omnilogic_local_2024-07-24T22-20-53.870Z.log

hoagea commented 3 months ago

I found this error in the log

Logger: homeassistant.components.light Source: helpers/entity_platform.py:598 integration: Light (documentation, issues) First occurred: July 24, 2024 at 8:03:09 PM (1 occurrences) Last logged: July 24, 2024 at 8:03:09 PM

Error adding entity light.omnilogic_pool_color_lights for domain light with platform omnilogic_local Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 598, in _async_add_entities await coro File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 912, in _async_add_entity await entity.add_to_platform_finish() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1362, in add_to_platform_finish self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1007, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1133, in _async_write_ha_state state, attr, capabilities, shadowed_attr = self.async_calculate_state() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1070, in async_calculate_state if state_attributes := self.state_attributes: ^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/components/light/init.py", line 1201, in state_attributes data[ATTR_BRIGHTNESS] = self.brightness ^^^^^^^^^^^^^^^ File "/config/custom_components/omnilogic_local/light.py", line 98, in brightness return to_hass_level(self.data.telemetry.brightness) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/omnilogic_local/light.py", line 44, in to_hass_level return int(int(level.value * 255) // 4) ^^^^^^^^^^^ AttributeError: 'int' object has no attribute 'value'

hoagea commented 3 months ago

I also was able to copy this error from the log after again trying to turn the light on... I will note that when I turned it on today despite the error the light turned on:

This error originated from a custom integration.

Logger: homeassistant Source: custom_components/omnilogic_local/light.py:44 integration: OmniLogic Local (documentation, issues) First occurred: July 24, 2024 at 8:03:19 PM (941 occurrences) Last logged: 6:53:02 PM

Error doing job: Task exception was never retrieved (None) Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 255, in _handle_refresh_interval await self._async_refresh(log_failures=True, scheduled=True) File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 411, in _async_refresh self.async_update_listeners() File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 165, in async_update_listeners update_callback() File "/config/custom_components/omnilogic_local/entity.py", line 47, in _handle_coordinator_update self.async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1007, in async_write_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1133, in _async_write_ha_state state, attr, capabilities, shadowed_attr = self.async_calculate_state() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1070, in async_calculate_state if state_attributes := self.state_attributes: ^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/components/light/init.py", line 1201, in state_attributes data[ATTR_BRIGHTNESS] = self.brightness ^^^^^^^^^^^^^^^ File "/config/custom_components/omnilogic_local/light.py", line 98, in brightness return to_hass_level(self.data.telemetry.brightness) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/omnilogic_local/light.py", line 44, in to_hass_level return int(int(level.value * 255) // 4) ^^^^^^^^^^^ AttributeError: 'int' object has no attribute 'value'

hoagea commented 3 months ago

TLDR: if you have this same issue skip to the end of this comment and you will find the code that seems to have fixed this issue for me.

Ok so I figured I would give ChatGPT a chance to help me fix this while waiting on feed back here. I initial provided a prompt that asked "what is this error and how do I fix it" and pasted in the last four lines from the log above. ChatGPT gave me some feedback and a possible solution with the following code tor replace the code at line 44:

If level is supposed to be an integer: Ensure that level is an integer before this line of code. You can add a print statement to debug what level is before this line:

return int(level * 255 // 4)

I tried this and when I turned on the light it came on at 1250% according to the slider in HA, and when I tried to use the slider to change the level I got a different error message. So I went back to ChatGPT and told it "Here is the code from line 1 through line 44" and pasted in that code from the lights.py file. In response I received a long explanation followed by

If you suspect that level might sometimes be passed as an integer directly, you can handle this by checking the type and adjusting the logic accordingly:

def to_hass_level(level: Any) -> int:
    """Convert the given OmniLogic (0-4) light level to Home Assistant (0-255)."""
    if isinstance(level, ColorLogicBrightness):
        return int(int(level.value * 255) // 4)
    elif isinstance(level, int):
        return int(int(level * 255) // 4)
    else:
        raise TypeError("Expected level to be an instance of ColorLogicBrightness or int")

This will cover both cases where level is either a ColorLogicBrightness object or an integer. Ensure that you update any calling code to pass the correct type to this function.

I used this code to replace the original "def to_hass_level" code and saved the file, now when I turn on the light no error and everything seems to be working.

cryptk commented 2 months ago

This has been an issue for a while that I haven't had time to fix yet. I know the cause, it has to do with how the data is translated back and forth between the number values and the "pretty" values for display. This should only happen if you try and adjust the lights twice within a single polling interval. I've been slammed with life lately, but hopefully soon I'll have time time to resolve some of these lingering issues.