Olen / homeassistant-plant

Alternative Plant component of home assistant
365 stars 25 forks source link

Log Error: Error adding entity sensor.centella_asiatica_illuminance for domain sensor with platform plant #162

Closed gurglingtonic closed 6 months ago

gurglingtonic commented 6 months ago

Error appear after updating to Home Assistant 2024.5.1

Error disappear when revert to Home Assistant 2024.4.4

Logger: homeassistant.components.sensor
Source: helpers/entity_platform.py:580
integration: Sensor ([documentation](https://www.home-assistant.io/integrations/sensor), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+sensor%22))
First occurred: 11:49:19 pm (4 occurrences)
Last logged: 11:49:19 pm

Error adding entity sensor.centella_asiatica_illuminance for domain sensor with platform plant
Error adding entity sensor.centella_asiatica_conductivity for domain sensor with platform plant
Error adding entity sensor.centella_asiatica_soil_moisture for domain sensor with platform plant
Error adding entity sensor.centella_asiatica_temperature for domain sensor with platform plant
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 658, in state
    numerical_value = int(value)
                      ^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'unknown'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 661, in state
    numerical_value = float(value)
                      ^^^^^^^^^^^^
ValueError: could not convert string to float: 'unknown'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 580, in _async_add_entities
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 892, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1359, in add_to_platform_finish
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1009, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1132, in _async_write_ha_state
    state, attr, capabilities, shadowed_attr = self.__async_calculate_state()
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1067, in __async_calculate_state
    state = self._stringify_state(available)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1015, in _stringify_state
    if (state := self.state) is None:
                 ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 665, in state
    raise ValueError(
ValueError: Sensor sensor.centella_asiatica_illuminance has device class 'illuminance', state class 'measurement' unit 'lx' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: 'unknown' (<class 'str'>)
chemelli74 commented 6 months ago

Same here, error appeared after updating from 2024.4.4 to 2024.5.1.

2024-05-06 08:23:09.783 INFO (MainThread) [custom_components.plant.sensor] Setting sensor.pianta_05f0_temperature external sensor to sensor.plant_sensor_05f0_temperature
2024-05-06 08:23:09.784 ERROR (MainThread) [homeassistant.components.sensor] Error adding entity sensor.pianta_05f0_temperature for domain sensor with platform plant
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 658, in state
    numerical_value = int(value)
                      ^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'unknown'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 661, in state
    numerical_value = float(value)
                      ^^^^^^^^^^^^
ValueError: could not convert string to float: 'unknown'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 580, in _async_add_entities
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 892, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1359, in add_to_platform_finish
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1009, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1132, in _async_write_ha_state
    state, attr, capabilities, shadowed_attr = self.__async_calculate_state()
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1067, in __async_calculate_state
    state = self._stringify_state(available)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1015, in _stringify_state
    if (state := self.state) is None:
                 ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 665, in state
    raise ValueError(
ValueError: Sensor sensor.pianta_05f0_temperature has device class 'temperature', state class 'measurement' unit '°C' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: 'unknown' (<class 'str'>)

Seems restoring the value is not working as expected.

Olen commented 6 months ago

I really don't understand where this "unknown" can sneak inn. In __init__() I check the state of the source and changes it to None:

    def __init__(
...
        self._default_state = None
...
        if (
            not self._attr_native_value
            or self._attr_native_value == STATE_UNKNOWN
            or self._attr_native_value == STATE_UNAVAILABLE
        ):
            _LOGGER.debug(
                "Unknown native value for %s, setting to default: %s",
                self.entity_id,
                self._default_state,
            )
            self._attr_native_value = self._default_state

On updates from the source sensor I check the value and set it to None:

        if (
            self.external_sensor
            and new_state
            and new_state is not STATE_UNKNOWN
            and new_state is not STATE_UNAVAILABLE
        ):
            self._attr_native_value = new_state.state
            if ATTR_UNIT_OF_MEASUREMENT in new_state.attributes:
                self._attr_native_unit_of_measurement = new_state.attributes[
                    ATTR_UNIT_OF_MEASUREMENT
                ]
        else:
            self._attr_native_value = self._default_state

So there is "no way" the state should be set to the string "unknown" anywhere as far as I can see.

gurglingtonic commented 6 months ago

Not sure if this is ugly fix but I tried this in sensor.py and the 'unknown' error disappeared:-

        if (
            self.external_sensor
            and new_state
            and new_state is not STATE_UNKNOWN
            and new_state is not STATE_UNAVAILABLE
        ):
            if new_state.state != 'unknown':
                self._attr_native_value = new_state.state
                if ATTR_UNIT_OF_MEASUREMENT in new_state.attributes:
                    self._attr_native_unit_of_measurement = new_state.attributes[
                        ATTR_UNIT_OF_MEASUREMENT
                    ]
        else:
            self._attr_native_value = self._default_state
Olen commented 6 months ago

Hm, maybe that's the point. new_state is maybe an object, not a string...