diff --git a/homeassistant/components/plugwise/const.py b/homeassistant/components/plugwise/const.py index a885a047f7a..4c221b2860a 100644 --- a/homeassistant/components/plugwise/const.py +++ b/homeassistant/components/plugwise/const.py @@ -9,9 +9,7 @@ DOMAIN = "plugwise" LOGGER = logging.getLogger(__package__) API = "api" -ATTR_ILLUMINANCE = "illuminance" COORDINATOR = "coordinator" -DEVICE_STATE = "device_state" FLOW_SMILE = "smile (Adam/Anna/P1)" FLOW_STRETCH = "stretch (Stretch)" FLOW_TYPE = "flow_type" @@ -38,11 +36,6 @@ ZEROCONF_MAP = { "stretch": "Stretch", } -# Sensor mapping -SENSOR_MAP_DEVICE_CLASS = 2 -SENSOR_MAP_MODEL = 0 -SENSOR_MAP_STATE_CLASS = 3 -SENSOR_MAP_UOM = 1 # Default directives DEFAULT_MAX_TEMP = 30 diff --git a/homeassistant/components/plugwise/sensor.py b/homeassistant/components/plugwise/sensor.py index 3cba9f59651..d55c2df4df9 100644 --- a/homeassistant/components/plugwise/sensor.py +++ b/homeassistant/components/plugwise/sensor.py @@ -6,6 +6,7 @@ from plugwise.smile import Smile from homeassistant.components.sensor import ( SensorDeviceClass, SensorEntity, + SensorEntityDescription, SensorStateClass, ) from homeassistant.config_entries import ConfigEntry @@ -24,207 +25,259 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import ( COOL_ICON, COORDINATOR, - DEVICE_STATE, DOMAIN, FLAME_ICON, IDLE_ICON, LOGGER, - SENSOR_MAP_DEVICE_CLASS, - SENSOR_MAP_MODEL, - SENSOR_MAP_STATE_CLASS, - SENSOR_MAP_UOM, UNIT_LUMEN, ) from .coordinator import PlugwiseDataUpdateCoordinator from .entity import PlugwiseEntity -ATTR_TEMPERATURE = [ - "Temperature", - TEMP_CELSIUS, - SensorDeviceClass.TEMPERATURE, - SensorStateClass.MEASUREMENT, -] -ATTR_BATTERY_LEVEL = [ - "Charge", - PERCENTAGE, - SensorDeviceClass.BATTERY, - SensorStateClass.MEASUREMENT, -] -ATTR_ILLUMINANCE = [ - "Illuminance", - UNIT_LUMEN, - SensorDeviceClass.ILLUMINANCE, - SensorStateClass.MEASUREMENT, -] -ATTR_PRESSURE = [ - "Pressure", - PRESSURE_BAR, - SensorDeviceClass.PRESSURE, - SensorStateClass.MEASUREMENT, -] +SENSORS: tuple[SensorEntityDescription, ...] = ( + SensorEntityDescription( + key="setpoint", + name="Setpoint", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="temperature", + name="Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="intended_boiler_temperature", + name="Intended Boiler Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="temperature_difference", + name="Temperature Difference", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="outdoor_temperature", + name="Outdoor Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="water_temperature", + name="Water Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="return_temperature", + name="Return Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="return_temperature", + name="Return Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_consumed", + name="Electricity Consumed", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_produced", + name="Electricity Produced", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_consumed_interval", + name="Electricity Consumed Interval", + native_unit_of_measurement=ENERGY_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="electricity_consumed_peak_interval", + name="Electricity Consumed Peak Interval", + native_unit_of_measurement=ENERGY_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="electricity_consumed_off_peak_interval", + name="Electricity Consumed Off Peak Interval", + native_unit_of_measurement=ENERGY_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="electricity_produced_interval", + name="Electricity Produced Interval", + native_unit_of_measurement=ENERGY_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="electricity_produced_peak_interval", + name="Electricity Produced Peak Interval", + native_unit_of_measurement=ENERGY_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="electricity_produced_off_peak_interval", + name="Electricity Produced Off Peak Interval", + native_unit_of_measurement=ENERGY_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="electricity_consumed_off_peak_point", + name="Electricity Consumed Off Peak Point", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_consumed_peak_point", + name="Electricity Consumed Peak Point", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_consumed_off_peak_cumulative", + name="Electricity Consumed Off Peak Cumulative", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + SensorEntityDescription( + key="electricity_consumed_peak_cumulative", + name="Electricity Consumed Peak Cumulative", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + SensorEntityDescription( + key="electricity_produced_off_peak_point", + name="Electricity Produced Off Peak Point", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_produced_peak_point", + name="Electricity Produced Peak Point", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="electricity_produced_off_peak_cumulative", + name="Electricity Produced Off Peak Cumulative", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + SensorEntityDescription( + key="electricity_produced_peak_cumulative", + name="Electricity Produced Peak Cumulative", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + ), + SensorEntityDescription( + key="gas_consumed_interval", + name="Gas Consumed Interval", + native_unit_of_measurement=VOLUME_CUBIC_METERS, + device_class=SensorDeviceClass.GAS, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="gas_consumed_cumulative", + name="Gas Consumed Cumulative", + native_unit_of_measurement=VOLUME_CUBIC_METERS, + device_class=SensorDeviceClass.GAS, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="net_electricity_point", + name="Net Electricity Point", + native_unit_of_measurement=POWER_WATT, + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="net_electricity_cumulative", + name="Net Electricity Cumulative", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL, + ), + SensorEntityDescription( + key="battery", + name="Battery", + native_unit_of_measurement=PERCENTAGE, + device_class=SensorDeviceClass.BATTERY, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="illuminance", + name="Illuminance", + native_unit_of_measurement=UNIT_LUMEN, + device_class=SensorDeviceClass.ILLUMINANCE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="modulation_level", + name="Modulation Level", + icon="mdi:percent", + native_unit_of_measurement=PERCENTAGE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="valve_position", + name="Valve Position", + icon="mdi:valve", + native_unit_of_measurement=PERCENTAGE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="water_pressure", + name="Water Pressure", + native_unit_of_measurement=PRESSURE_BAR, + device_class=SensorDeviceClass.PRESSURE, + state_class=SensorStateClass.MEASUREMENT, + ), +) -TEMP_SENSOR_MAP: dict[str, list] = { - "setpoint": ATTR_TEMPERATURE, - "temperature": ATTR_TEMPERATURE, - "intended_boiler_temperature": ATTR_TEMPERATURE, - "temperature_difference": ATTR_TEMPERATURE, - "outdoor_temperature": ATTR_TEMPERATURE, - "water_temperature": ATTR_TEMPERATURE, - "return_temperature": ATTR_TEMPERATURE, -} - -ENERGY_SENSOR_MAP: dict[str, list] = { - "electricity_consumed": [ - "Current Consumed Power", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "electricity_produced": [ - "Current Produced Power", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "electricity_consumed_interval": [ - "Consumed Power Interval", - ENERGY_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], - "electricity_consumed_peak_interval": [ - "Consumed Power Interval", - ENERGY_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], - "electricity_consumed_off_peak_interval": [ - "Consumed Power Interval (off peak)", - ENERGY_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], - "electricity_produced_interval": [ - "Produced Power Interval", - ENERGY_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], - "electricity_produced_peak_interval": [ - "Produced Power Interval", - ENERGY_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], - "electricity_produced_off_peak_interval": [ - "Produced Power Interval (off peak)", - ENERGY_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], - "electricity_consumed_off_peak_point": [ - "Current Consumed Power (off peak)", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "electricity_consumed_peak_point": [ - "Current Consumed Power", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "electricity_consumed_off_peak_cumulative": [ - "Cumulative Consumed Power (off peak)", - ENERGY_KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL_INCREASING, - ], - "electricity_consumed_peak_cumulative": [ - "Cumulative Consumed Power", - ENERGY_KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL_INCREASING, - ], - "electricity_produced_off_peak_point": [ - "Current Produced Power (off peak)", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "electricity_produced_peak_point": [ - "Current Produced Power", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "electricity_produced_off_peak_cumulative": [ - "Cumulative Produced Power (off peak)", - ENERGY_KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL_INCREASING, - ], - "electricity_produced_peak_cumulative": [ - "Cumulative Produced Power", - ENERGY_KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL_INCREASING, - ], - "gas_consumed_interval": [ - "Current Consumed Gas Interval", - VOLUME_CUBIC_METERS, - SensorDeviceClass.GAS, - SensorStateClass.TOTAL, - ], - "gas_consumed_cumulative": [ - "Consumed Gas", - VOLUME_CUBIC_METERS, - SensorDeviceClass.GAS, - SensorStateClass.TOTAL_INCREASING, - ], - "net_electricity_point": [ - "Current net Power", - POWER_WATT, - SensorDeviceClass.POWER, - SensorStateClass.MEASUREMENT, - ], - "net_electricity_cumulative": [ - "Cumulative net Power", - ENERGY_KILO_WATT_HOUR, - SensorDeviceClass.ENERGY, - SensorStateClass.TOTAL, - ], -} - -MISC_SENSOR_MAP: dict[str, list] = { - "battery": ATTR_BATTERY_LEVEL, - "illuminance": ATTR_ILLUMINANCE, - "modulation_level": [ - "Heater Modulation Level", - PERCENTAGE, - None, - SensorStateClass.MEASUREMENT, - ], - "valve_position": [ - "Valve Position", - PERCENTAGE, - None, - SensorStateClass.MEASUREMENT, - ], - "water_pressure": ATTR_PRESSURE, -} - -INDICATE_ACTIVE_LOCAL_DEVICE = [ - "cooling_state", - "flame_state", -] - -CUSTOM_ICONS = { - "gas_consumed_interval": "mdi:fire", - "gas_consumed_cumulative": "mdi:fire", - "modulation_level": "mdi:percent", - "valve_position": "mdi:valve", -} +INDICATE_ACTIVE_LOCAL_DEVICE_SENSORS: tuple[SensorEntityDescription, ...] = ( + SensorEntityDescription( + key="cooling_state", + name="Cooling State", + ), + SensorEntityDescription( + key="flame_state", + name="Flame State", + ), +) async def async_setup_entry( @@ -241,12 +294,8 @@ async def async_setup_entry( single_thermostat = api.single_master_thermostat() for dev_id, device_properties in all_devices.items(): data = api.get_device_data(dev_id) - for sensor, sensor_type in { - **TEMP_SENSOR_MAP, - **ENERGY_SENSOR_MAP, - **MISC_SENSOR_MAP, - }.items(): - if data.get(sensor) is None: + for description in SENSORS: + if data.get(description.key) is None: continue if "power" in device_properties["types"]: @@ -261,9 +310,8 @@ async def async_setup_entry( coordinator, device_properties["name"], dev_id, - sensor, - sensor_type, model, + description, ) ) else: @@ -273,14 +321,13 @@ async def async_setup_entry( coordinator, device_properties["name"], dev_id, - sensor, - sensor_type, + description, ) ) if single_thermostat is False: - for state in INDICATE_ACTIVE_LOCAL_DEVICE: - if state not in data: + for description in INDICATE_ACTIVE_LOCAL_DEVICE_SENSORS: + if description.key not in data: continue entities.append( @@ -289,7 +336,7 @@ async def async_setup_entry( coordinator, device_properties["name"], dev_id, - DEVICE_STATE, + description, ) ) break @@ -306,18 +353,17 @@ class SmileSensor(PlugwiseEntity, SensorEntity): coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, - sensor: str, + description: SensorEntityDescription, ) -> None: """Initialise the sensor.""" super().__init__(api, coordinator, name, dev_id) - self._attr_unique_id = f"{dev_id}-{sensor}" - self._sensor = sensor + self.entity_description = description + self._attr_unique_id = f"{dev_id}-{description.key}" if dev_id == self._api.heater_id: self._entity_name = "Auxiliary" - sensorname = sensor.replace("_", " ").title() - self._name = f"{self._entity_name} {sensorname}" + self._name = f"{self._entity_name} {description.name}" if dev_id == self._api.gateway_id: self._entity_name = f"Smile {self._entity_name}" @@ -326,23 +372,6 @@ class SmileSensor(PlugwiseEntity, SensorEntity): class PwThermostatSensor(SmileSensor): """Thermostat (or generic) sensor devices.""" - def __init__( - self, - api: Smile, - coordinator: PlugwiseDataUpdateCoordinator, - name: str, - dev_id: str, - sensor: str, - sensor_type: list[str], - ) -> None: - """Set up the Plugwise API.""" - super().__init__(api, coordinator, name, dev_id, sensor) - - self._model = sensor_type[SENSOR_MAP_MODEL] - self._attr_native_unit_of_measurement = sensor_type[SENSOR_MAP_UOM] - self._attr_device_class = sensor_type[SENSOR_MAP_DEVICE_CLASS] - self._attr_state_class = sensor_type[SENSOR_MAP_STATE_CLASS] - @callback def _async_process_data(self) -> None: """Update the entity.""" @@ -351,29 +380,15 @@ class PwThermostatSensor(SmileSensor): self.async_write_ha_state() return - if data.get(self._sensor) is not None: - self._attr_native_value = data[self._sensor] - self._attr_icon = CUSTOM_ICONS.get(self._sensor, self.icon) - + self._attr_native_value = data.get(self.entity_description.key) self.async_write_ha_state() class PwAuxDeviceSensor(SmileSensor): """Auxiliary Device Sensors.""" - def __init__( - self, - api: Smile, - coordinator: PlugwiseDataUpdateCoordinator, - name: str, - dev_id: str, - sensor: str, - ) -> None: - """Set up the Plugwise API.""" - super().__init__(api, coordinator, name, dev_id, sensor) - - self._cooling_state = False - self._heating_state = False + _cooling_state = False + _heating_state = False @callback def _async_process_data(self) -> None: @@ -409,21 +424,12 @@ class PwPowerSensor(SmileSensor): coordinator: PlugwiseDataUpdateCoordinator, name: str, dev_id: str, - sensor: str, - sensor_type: list[str], model: str | None, + description: SensorEntityDescription, ) -> None: """Set up the Plugwise API.""" - super().__init__(api, coordinator, name, dev_id, sensor) - + super().__init__(api, coordinator, name, dev_id, description) self._model = model - if model is None: - self._model = sensor_type[SENSOR_MAP_MODEL] - - self._attr_native_unit_of_measurement = sensor_type[SENSOR_MAP_UOM] - self._attr_device_class = sensor_type[SENSOR_MAP_DEVICE_CLASS] - self._attr_state_class = sensor_type[SENSOR_MAP_STATE_CLASS] - if dev_id == self._api.gateway_id: self._model = "P1 DSMR" @@ -435,8 +441,5 @@ class PwPowerSensor(SmileSensor): self.async_write_ha_state() return - if data.get(self._sensor) is not None: - self._attr_native_value = data[self._sensor] - self._attr_icon = CUSTOM_ICONS.get(self._sensor, self.icon) - + self._attr_native_value = data.get(self.entity_description.key) self.async_write_ha_state()