diff --git a/custom_components/meteo_lt/manifest.json b/custom_components/meteo_lt/manifest.json index ec01348..b6055a9 100644 --- a/custom_components/meteo_lt/manifest.json +++ b/custom_components/meteo_lt/manifest.json @@ -10,5 +10,5 @@ "issue_tracker": "https://github.com/Brunas/meteo_lt/issues", "loggers": ["meteo_lt"], "requirements": ["meteo_lt-pkg==0.2.0"], - "version": "0.1.8" + "version": "0.2.0" } \ No newline at end of file diff --git a/custom_components/meteo_lt/sensor.py b/custom_components/meteo_lt/sensor.py index b61e1fd..ac1eb50 100644 --- a/custom_components/meteo_lt/sensor.py +++ b/custom_components/meteo_lt/sensor.py @@ -20,33 +20,72 @@ async def async_setup_entry(hass, entry, async_add_entities): hass.data[DOMAIN][entry.entry_id], entry, ) - async_add_entities( - [ - MeteoLtCurrentConditionsSensor( - hass.data[DOMAIN][entry.entry_id]["coordinator"], - hass.data[DOMAIN][entry.entry_id]["nearest_place"], - entry, - ) - ] - ) + coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"] + nearest_place = hass.data[DOMAIN][entry.entry_id]["nearest_place"] -class MeteoLtCurrentConditionsSensor(CoordinatorEntity, SensorEntity): - """Representation of a Meteo.Lt Current Conditions Sensor.""" + sensors = [ + MeteoLtCurrentConditionsSensor(coordinator, nearest_place, entry), + MeteoLtTemperatureSensor(coordinator, nearest_place, entry), + MeteoLtApparentTemperatureSensor(coordinator, nearest_place, entry), + MeteoLtWindSpeedSensor(coordinator, nearest_place, entry), + MeteoLtWindGustSpeedSensor(coordinator, nearest_place, entry), + MeteoLtWindBearingSensor(coordinator, nearest_place, entry), + MeteoLtCloudCoverageSensor(coordinator, nearest_place, entry), + MeteoLtPressureSensor(coordinator, nearest_place, entry), + MeteoLtHumiditySensor(coordinator, nearest_place, entry), + MeteoLtPrecipitationSensor(coordinator, nearest_place, entry), + MeteoLtConditionSensor(coordinator, nearest_place, entry), + ] - def __init__(self, coordinator, nearest_place, config_entry): + async_add_entities(sensors) + + +class MeteoLtBaseSensor(CoordinatorEntity, SensorEntity): + """Base class for all Meteo.Lt sensors.""" + + def __init__(self, coordinator, nearest_place, config_entry, attribute, unit=None): """Initialize the sensor.""" super().__init__(coordinator) - self._attr_name = ( - f"{config_entry.title} {nearest_place.name} - Current Conditions" - ) - self._attr_unique_id = f"{config_entry.entry_id}-sensor" - self._state = None + self._attr_name = f"{config_entry.title} {nearest_place.name} - {attribute}" + self._attr_unique_id = f"{config_entry.entry_id}-{attribute}".replace( + " ", "_" + ).lower() + self._attr_unit_of_measurement = unit + self._attribute = attribute @property def native_value(self): """Return the value of the sensor.""" - return self.coordinator.data.current_conditions().temperature + return getattr(self.coordinator.data.current_conditions(), self._attribute) + + @property + def extra_state_attributes(self) -> Dict[str, Any] | None: + """Return the state attributes.""" + return { + "last_updated": self.coordinator.last_updated, + } + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + LOGGER.debug( + "Handling Meteo.Lt sensor coordinator update for entity %s", self.entity_id + ) + self.async_write_ha_state() + + async def async_update(self): + """Fetch new state data for the sensor.""" + LOGGER.debug("Updating Meteo.Lt sensor entity %s", self.entity_id) + await self.coordinator.async_request_refresh() + + +class MeteoLtCurrentConditionsSensor(MeteoLtBaseSensor): + """Representation of a Meteo.Lt Current Conditions Sensor.""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__(coordinator, nearest_place, config_entry, "Current Conditions") + self._attribute = "temperature" @property def extra_state_attributes(self) -> Dict[str, Any] | None: @@ -54,7 +93,8 @@ def extra_state_attributes(self) -> Dict[str, Any] | None: current_conditions = self.coordinator.data.current_conditions() LOGGER.debug("Current conditions: %s", current_conditions) - return { + base_attributes = super().extra_state_attributes or {} + current_conditions_attributes = { "native_temperature": current_conditions.temperature, "native_apparent_temperature": current_conditions.apparent_temperature, "native_wind_speed": current_conditions.wind_speed, @@ -69,18 +109,107 @@ def extra_state_attributes(self) -> Dict[str, Any] | None: "native_wind_speed_unit": UnitOfSpeed.METERS_PER_SECOND, "native_pressure_unit": UnitOfPressure.HPA, "native_precipitation_unit": UnitOfPrecipitationDepth.MILLIMETERS, - "last_updated": self.coordinator.last_updated, } + return {**current_conditions_attributes, **base_attributes} - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - LOGGER.debug( - "Handling Meteo.Lt sensor coordinator update for entity %s", self.entity_id + +class MeteoLtTemperatureSensor(MeteoLtBaseSensor): + """MeteoLtBaseSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__( + coordinator, + nearest_place, + config_entry, + "temperature", + UnitOfTemperature.CELSIUS, ) - self.async_write_ha_state() - async def async_update(self): - """Fetch new state data for the sensor.""" - LOGGER.debug("Updating Meteo.Lt sensor entity %s", self.entity_id) - await self.coordinator.async_request_refresh() + +class MeteoLtApparentTemperatureSensor(MeteoLtBaseSensor): + """MeteoLtApparentTemperatureSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__( + coordinator, + nearest_place, + config_entry, + "apparent_temperature", + UnitOfTemperature.CELSIUS, + ) + + +class MeteoLtWindSpeedSensor(MeteoLtBaseSensor): + """MeteoLtWindSpeedSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__( + coordinator, + nearest_place, + config_entry, + "wind_speed", + UnitOfSpeed.METERS_PER_SECOND, + ) + + +class MeteoLtWindGustSpeedSensor(MeteoLtBaseSensor): + """MeteoLtWindGustSpeedSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__( + coordinator, + nearest_place, + config_entry, + "wind_gust_speed", + UnitOfSpeed.METERS_PER_SECOND, + ) + + +class MeteoLtWindBearingSensor(MeteoLtBaseSensor): + """MeteoLtWindBearingSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__(coordinator, nearest_place, config_entry, "wind_bearing") + + +class MeteoLtCloudCoverageSensor(MeteoLtBaseSensor): + """MeteoLtCloudCoverageSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__(coordinator, nearest_place, config_entry, "cloud_coverage") + + +class MeteoLtPressureSensor(MeteoLtBaseSensor): + """MeteoLtPressureSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__( + coordinator, nearest_place, config_entry, "pressure", UnitOfPressure.HPA + ) + + +class MeteoLtHumiditySensor(MeteoLtBaseSensor): + """MeteoLtHumiditySensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__(coordinator, nearest_place, config_entry, "humidity") + + +class MeteoLtPrecipitationSensor(MeteoLtBaseSensor): + """MeteoLtPrecipitationSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__( + coordinator, + nearest_place, + config_entry, + "precipitation", + UnitOfPrecipitationDepth.MILLIMETERS, + ) + + +class MeteoLtConditionSensor(MeteoLtBaseSensor): + """MeteoLtConditionSensor""" + + def __init__(self, coordinator, nearest_place, config_entry): + super().__init__(coordinator, nearest_place, config_entry, "condition")