Sensor/BinarySensor value does not update

Hello, my custom integration is able to trigger an update (call to MyDataUpdateCoordinator._async_update_data) every 1 minute. I do see variations of sensor value in the history chart. However the UI (in example in the main page) doesn’t update and the value shown is always the one of the last reboot. Could you please advise?

Thanks.

If you want help with code, it is always best to provide a link to it. Without it, people are not usually willing or able to help.

I can guess what the issue is (that you are not calling update_ha_state in your sensor), but post your code and i will tell you definitely.

Indeed I’m not calling that. Where should that be called? I’ll post the code as soon as I’m back to my laptop. Thanks for any help you can provide in the meantime.

I extracted relevant details of my code and simplified things a bit for you to avoid useless details. Also example is more generic and can better help other people.

This is my sensor:

class MySensorEntity(CoordinatorEntity[MyDataUpdateCoordinator], SensorEntity):
   
    _attr_has_entity_name = True

    def __init__(
        self,
        coordinator: MyDataUpdateCoordinator,
        resource: dict[str, Any],
    ) -> None:
        super().__init__(coordinator)
        self.entity_description = MySensorEntityDescription(resource)
        self._attr_unique_id = self.entity_description.key
        self._attr_name = resource.name
        self._attr_device_info = MyDeviceInfo(resource)
        self.resource = resource

    @property
    def native_value(self) -> str | None:
        return self.resource.get_value()


async def async_setup_entry(
    hass: HomeAssistant,
    entry: MyConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    coordinator = entry.runtime_data
    async_add_entities(
        MySensorEntity(
            coordinator=coordinator,
            resource=resource,
        )
        for resource in coordinator.get_resources(Platform.SENSOR)
    )

Here is how I update values:

type MyConfigEntry = ConfigEntry[MyDataUpdateCoordinator]


class MyDataUpdateCoordinator(DataUpdateCoordinator):

    resources: dict[str, MyResource]

    def __init__(
        self, hass: HomeAssistant, config_entry: MyConfigEntry, api: MyApi
    ) -> None:
        super().__init__(
            hass,
            LOGGER,
            config_entry=config_entry,
            name=DOMAIN,
            update_interval=timedelta(minutes=1),
            always_update=False,
        )
        self.api = api
        self.resources = {}

    def setup_data(self) -> None:
        self.resources = self.api.get_resources()

    def _fetch_data(self) -> dict[str, MyResource]:
        values = self.api.get_resource_values()
        for k, v in values.items():
            if k in self.resources:
                self.resources[k].set_value(v)
        return self.resources

    def fetch_data(self) -> dict[str, MyResource]:
        try:
            return self._fetch_data()
        except AuthenticationError as e:
            self.api.authenticate()
            return self._fetch_data()

    def get_resources(self, platform: Platform) -> MyResource:
        return [r for r in self.resource if to_platform(r.type) == platform]

    async def _async_setup(self):
        try:
            await self.hass.async_add_executor_job(self.setup_data)
        except AuthenticationError as e:
            raise ConfigEntryAuthFailed from e

    async def _async_update_data(self) -> dict[str, MyResource]:
        try:
            return await self.hass.async_add_executor_job(self.fetch_data)
        except AuthenticationError as e:
            raise ConfigEntryAuthFailed from e

Thanks for the help.

Ok, so your issue is that you are not refreshing your data from the coordinator. When you set self.resources in your init, this is then static as a local variable. You will need to update self.resources from your coordinator to get the latest value on each update.

In my coordinator I do update the value of resource like this self.resources[k].set_value(v) into _fetch_data. Do I need to notify the GUI that the value has changed? If so how? Thanks.