Skip to content

Commit

Permalink
fix: refresh multiple contracts, statistic id invalid (#19)
Browse files Browse the repository at this point in the history
* fix: trigger refresh multiple coordinators

* change to TimestampDataUpdateCoordinator

* fix: invalid statistic id, refactor internal id

* optimize code, remove unused previous data declaration

* internal: call function for error raise

* use id instead of name (same value)

* bump version
  • Loading branch information
duhow authored Mar 16, 2024
1 parent 697c216 commit 0105b22
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 25 deletions.
2 changes: 1 addition & 1 deletion custom_components/aigues_barcelona/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/duhow/hass-aigues-barcelona/issues",
"requirements": [],
"version": "0.4.0"
"version": "0.4.1"
}
54 changes: 30 additions & 24 deletions custom_components/aigues_barcelona/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.helpers.update_coordinator import TimestampDataUpdateCoordinator

from .api import AiguesApiClient
from .const import API_ERROR_TOKEN_REVOKED
Expand Down Expand Up @@ -60,31 +60,29 @@ async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entitie
contadores = list()

for contract in contracts:
coordinator = ContratoAgua(
hass, username, password, contract, token=token, prev_data=None
)
coordinator = ContratoAgua(hass, username, password, contract, token=token)
contadores.append(ContadorAgua(coordinator))

# postpone first refresh to speed up startup
@callback
async def async_first_refresh(*args):
"""Force the component to assess the first refresh."""
await coordinator.async_refresh()
# postpone first refresh to speed up startup
@callback
async def async_first_refresh(*args):
for sensor in contadores:
await sensor.coordinator.async_refresh()

if hass.state == CoreState.running:
await async_first_refresh()
else:
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, async_first_refresh)
# ------

contadores.append(ContadorAgua(coordinator))
if hass.state == CoreState.running:
await async_first_refresh()
else:
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, async_first_refresh)

_LOGGER.info("about to add entities")
# add sensor entities
async_add_entities(contadores)

return True


class ContratoAgua(DataUpdateCoordinator):
class ContratoAgua(TimestampDataUpdateCoordinator):
def __init__(
self,
hass: HomeAssistant,
Expand All @@ -99,6 +97,7 @@ def __init__(

self.contract = contract.upper()
self.id = contract.lower()
self.internal_sensor_id = f"sensor.contador_{self.id}"

if not hass.data[DOMAIN].get(self.contract):
# init data shared store
Expand All @@ -119,6 +118,9 @@ def __init__(
update_interval=timedelta(seconds=DEFAULT_SCAN_PERIOD),
)

def __repr__(self):
return f"<{self.__class__.__name__} {self.contract}>"

async def _async_update_data(self):
_LOGGER.info(f"Updating coordinator data for {self.contract}")
TODAY = datetime.now()
Expand Down Expand Up @@ -149,7 +151,7 @@ async def _async_update_data(self):
_LOGGER.error("Token has expired, cannot check consumptions.")
raise ConfigEntryAuthFailed from exp
except Exception as exp:
_LOGGER.error("error while getting data: %s", exp)
self.async_set_update_error(exp)
if API_ERROR_TOKEN_REVOKED in str(exp):
raise ConfigEntryAuthFailed from exp

Expand All @@ -165,7 +167,10 @@ async def _async_update_data(self):
self._data[CONF_STATE] = metric["datetime"]

# await self._clear_statistics()
await self._async_import_statistics(consumptions)
try:
await self._async_import_statistics(consumptions)
except:
pass

return True

Expand All @@ -176,7 +181,7 @@ async def _clear_statistics(self) -> None:
to_clear = [
x["statistic_id"]
for x in all_ids
if x["statistic_id"].startswith(f"sensor.contador_{self.contract}")
if x["statistic_id"].startswith(self.internal_sensor_id)
]

if to_clear:
Expand Down Expand Up @@ -218,7 +223,7 @@ async def _async_import_statistics(self, consumptions) -> None:
"has_sum": True,
"name": None,
"source": "recorder", # required
"statistic_id": f"sensor.contador_{self.contract}",
"statistic_id": self.internal_sensor_id,
"unit_of_measurement": UnitOfVolume.CUBIC_METERS,
}
# _LOGGER.debug(f"Adding metric: {metadata} {stats}")
Expand All @@ -231,8 +236,7 @@ class ContadorAgua(CoordinatorEntity, SensorEntity):
def __init__(self, coordinator) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self._data = coordinator.hass.data[DOMAIN][coordinator.id.upper()]
self._attr_name = f"Contador {coordinator.name}"
self._attr_name = f"Contador {coordinator.id}"
self._attr_unique_id = coordinator.id
self._attr_icon = "mdi:water-pump"
self._attr_has_entity_name = True
Expand All @@ -243,12 +247,14 @@ def __init__(self, coordinator) -> None:

@property
def native_value(self):
return self._data.get(CONF_VALUE, None)
return self.coordinator._data.get(CONF_VALUE, None)

@property
def last_measurement(self):
try:
last_measure = datetime.fromisoformat(self._data.get(CONF_STATE, ""))
last_measure = datetime.fromisoformat(
self.coordinator._data.get(CONF_STATE, "")
)
except ValueError:
last_measure = None
return last_measure
Expand Down

0 comments on commit 0105b22

Please sign in to comment.