From 71518d3056f7a2305ff8006b1c0b098f30462fe5 Mon Sep 17 00:00:00 2001 From: Ben Korinth Date: Sun, 5 Mar 2023 21:52:53 +0100 Subject: [PATCH] fix: sensor entity --- custom_components/estimenergy/config_flow.py | 12 +-- custom_components/estimenergy/coordinator.py | 4 +- custom_components/estimenergy/manifest.json | 2 +- custom_components/estimenergy/sensor.py | 85 ++++++++++---------- 4 files changed, 48 insertions(+), 55 deletions(-) diff --git a/custom_components/estimenergy/config_flow.py b/custom_components/estimenergy/config_flow.py index a552b09..e646509 100644 --- a/custom_components/estimenergy/config_flow.py +++ b/custom_components/estimenergy/config_flow.py @@ -7,7 +7,6 @@ from .const import ( DOMAIN, - CONF_NAME, CONF_HOST, CONF_PORT, ) @@ -20,22 +19,15 @@ class EstimEnergyConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def async_step_user(self, user_input=None) -> FlowResult: if user_input is not None: - collector_name = user_input["collector_name"] - - unique_id = f"estimenergy_{collector_name}" + unique_id = f"estimenergy_{user_input[CONF_HOST]}:{user_input[CONF_PORT]}" await self.async_set_unique_id(unique_id) self._abort_if_unique_id_configured() - return self.async_create_entry( - title=collector_name.title(), data=user_input - ) + return self.async_create_entry(title=unique_id, data=user_input) data_schema = vol.Schema( { - vol.Required( - CONF_NAME, - ): str, vol.Required( CONF_HOST, default=DEFAULT_HOST, diff --git a/custom_components/estimenergy/coordinator.py b/custom_components/estimenergy/coordinator.py index ac9652a..8fd87ff 100644 --- a/custom_components/estimenergy/coordinator.py +++ b/custom_components/estimenergy/coordinator.py @@ -14,16 +14,14 @@ class EstimEnergyCoordinator(DataUpdateCoordinator): """Data coordinator for EstimEnergy.""" - def __init__(self, hass: HomeAssistant, name: str, host: str, port: int) -> None: + def __init__(self, hass: HomeAssistant, host: str, port: int) -> None: super().__init__( hass, _LOGGER, - name=name, update_interval=timedelta(seconds=5), ) self.hass = hass - self.name = name self.host = host self.port = port self.client = EstimEnergyClient(host, port) diff --git a/custom_components/estimenergy/manifest.json b/custom_components/estimenergy/manifest.json index 0339d51..5bbb310 100644 --- a/custom_components/estimenergy/manifest.json +++ b/custom_components/estimenergy/manifest.json @@ -7,6 +7,6 @@ "documentation": "https://github.com/EuleMitKeule/EstimEnergy", "iot_class": "local_polling", "issue_tracker": "https://github.com/EuleMitKeule/EstimEnergy/issues", - "requirements": ["estimenergy"], + "requirements": ["estimenergy==1.7.0"], "version": "0.0.1" } diff --git a/custom_components/estimenergy/sensor.py b/custom_components/estimenergy/sensor.py index 345ab9f..2581da9 100644 --- a/custom_components/estimenergy/sensor.py +++ b/custom_components/estimenergy/sensor.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.components.sensor import SensorEntity -from homeassistant.const import CURRENCY_EURO +from homeassistant.const import CURRENCY_EURO, PERCENTAGE from homeassistant.const import UnitOfEnergy from estimenergy.const import ( JSON_BILLING_MONTH, @@ -17,7 +17,7 @@ JSON_DAY_KWH, JSON_DAY_COST, JSON_DAY_COST_DIFFERENCE, - JSON_PREDICTED_MONTH_KWH_RAW, + JSON_MONTH_KWH_RAW, JSON_YEAR_KWH_RAW, JSON_MONTH_KWH, JSON_MONTH_COST, @@ -26,11 +26,6 @@ SENSOR_TYPE_FRIENDLY_NAME, SENSOR_TYPE_JSON, SENSOR_TYPE_UNIQUE_ID, - SENSOR_TYPES, -) - -from .coordinator import EstimEnergyCoordinator -from .const import ( CONF_NAME, CONF_HOST, CONF_PORT, @@ -45,52 +40,57 @@ async def async_setup_entry( ) -> None: """Set up the EstimEnergy sensor platform.""" + client = EstimEnergyClient() + collectors = await hass.async_add_executor_job(client.get_collectors) + coordinator = EstimEnergyCoordinator( hass, - name=entry.data[CONF_NAME], host=entry.data[CONF_HOST], port=entry.data[CONF_PORT], ) await coordinator.initialize() - sensors = [ - EstimEnergySensor(coordinator, sensor_type=sensor_type) - for sensor_type in SENSOR_TYPES - ] + for collector in collectors: + sensors = [ + EstimEnergySensor(coordinator, metric=metric, collector=collector) + for metric in METRICS + ] - async_add_entities( - sensors, - update_before_add=True, - ) + async_add_entities( + sensors, + update_before_add=True, + ) class EstimEnergySensor(CoordinatorEntity, SensorEntity): """EstimEnergy Sensor class.""" - def __init__(self, coordinator: EstimEnergyCoordinator, sensor_type: dict) -> None: + def __init__( + self, coordinator: EstimEnergyCoordinator, metric: Metric, collector: dict + ) -> None: super().__init__(coordinator) - self.json_key = sensor_type[SENSOR_TYPE_JSON] - self._attr_name = ( - f"EstimEnergy {coordinator.name} {sensor_type[SENSOR_TYPE_FRIENDLY_NAME]}" - ) - self._attr_unique_id = ( - f"estimenergy-{coordinator.name}-{sensor_type[SENSOR_TYPE_UNIQUE_ID]}" - ) + self.metric = metric + self.collector = collector + self._attr_name = f"EstimEnergy {coordinator.name} {metric.friendly_name}" + self._attr_unique_id = f"estimenergy-{coordinator.name}-{metric.json_key}" @property def device_class(self) -> SensorDeviceClass | None: """Return the class of this entity.""" if self.json_key in [ JSON_DAY_KWH, - JSON_PREDICTED_MONTH_KWH_RAW, - JSON_PREDICTED_YEAR_KWH_RAW, + JSON_MONTH_KWH_RAW, + JSON_YEAR_KWH_RAW, JSON_MONTH_KWH, JSON_YEAR_KWH, ]: return SensorDeviceClass.ENERGY - return SensorDeviceClass.MONETARY + if self.metric.metric_type in [MetricType.COST, MetricType.COST_DIFFERENCE]: + return SensorDeviceClass.MONETARY + + return None @property def options(self) -> list[str] | None: @@ -105,17 +105,17 @@ def state_class(self) -> SensorStateClass | str | None: @property def last_reset(self) -> datetime | None: """Return the time when the sensor was last reset, if any.""" - if self.json_key in [JSON_DAY_COST, JSON_DAY_KWH, JSON_DAY_COST_DIFFERENCE]: + if self.metric.metric_period == MetricPeriod.DAY: return datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) - elif self.json_key in [ - JSON_MONTH_COST, - JSON_MONTH_KWH, - JSON_MONTH_COST_DIFFERENCE, - ]: + + if self.metric.metric_period == MetricPeriod.MONTH: return datetime.now().replace( day=1, hour=0, minute=0, second=0, microsecond=0 ) + if self.metric.metric_period == MetricPeriod.TOTAL: + return None + billing_month = self.coordinator.data[JSON_BILLING_MONTH] now = datetime.now() @@ -134,12 +134,12 @@ def native_value(self) -> int | None: """Return the state of the sensor.""" if ( self.coordinator.data is None - or JSON_DATA not in self.coordinator.data - or self.json_key not in self.coordinator.data[JSON_DATA] + or JSON_METRICS not in self.coordinator.data + or self.metric.json_key not in self.coordinator.data[JSON_METRICS] ): return None - return self.coordinator.data[JSON_DATA][self.json_key] + return self.coordinator.data[JSON_METRICS][self.metric.json_key] @property def suggested_display_precision(self) -> int | None: @@ -151,15 +151,18 @@ def native_unit_of_measurement(self) -> str | None: """Return the unit of measurement of the sensor.""" if self.json_key in [ JSON_DAY_KWH, - JSON_PREDICTED_MONTH_KWH_RAW, + JSON_MONTH_KWH_RAW, JSON_YEAR_KWH_RAW, JSON_MONTH_KWH, JSON_YEAR_KWH, ]: return UnitOfEnergy.KILO_WATT_HOUR - currency = self.hass.config.currency - if currency is None: - currency = CURRENCY_EURO + if self.device_class == SensorDeviceClass.MONETARY: + currency = self.hass.config.currency + if currency is None: + currency = CURRENCY_EURO + + return currency - return currency + return PERCENTAGE