diff --git a/.coveragerc b/.coveragerc index 0c2da893245..a58af4a7836 100644 --- a/.coveragerc +++ b/.coveragerc @@ -122,7 +122,7 @@ omit = homeassistant/components/braviatv/__init__.py homeassistant/components/braviatv/const.py homeassistant/components/braviatv/media_player.py - homeassistant/components/braviatv/remote.py + homeassistant/components/braviatv/remote.py homeassistant/components/broadlink/__init__.py homeassistant/components/broadlink/const.py homeassistant/components/broadlink/remote.py @@ -992,6 +992,7 @@ omit = homeassistant/components/swiss_public_transport/sensor.py homeassistant/components/swisscom/device_tracker.py homeassistant/components/switchbot/switch.py + homeassistant/components/switcher_kis/sensor.py homeassistant/components/switcher_kis/switch.py homeassistant/components/switchmate/switch.py homeassistant/components/syncthing/__init__.py diff --git a/homeassistant/components/switcher_kis/__init__.py b/homeassistant/components/switcher_kis/__init__.py index 6627e9d097c..ef196220656 100644 --- a/homeassistant/components/switcher_kis/__init__.py +++ b/homeassistant/components/switcher_kis/__init__.py @@ -8,7 +8,6 @@ import logging from aioswitcher.bridge import SwitcherV2Bridge import voluptuous as vol -from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.const import CONF_DEVICE_ID, EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv @@ -65,7 +64,8 @@ async def async_setup(hass: HomeAssistant, config: dict) -> bool: return False hass.data[DOMAIN] = {DATA_DEVICE: device_data} - hass.async_create_task(async_load_platform(hass, SWITCH_DOMAIN, DOMAIN, {}, config)) + hass.async_create_task(async_load_platform(hass, "switch", DOMAIN, {}, config)) + hass.async_create_task(async_load_platform(hass, "sensor", DOMAIN, {}, config)) @callback def device_updates(timestamp: datetime | None) -> None: diff --git a/homeassistant/components/switcher_kis/const.py b/homeassistant/components/switcher_kis/const.py index da51fae4d1a..acd6c070337 100644 --- a/homeassistant/components/switcher_kis/const.py +++ b/homeassistant/components/switcher_kis/const.py @@ -1,5 +1,4 @@ """Constants for the Switcher integration.""" -from homeassistant.components.switch import ATTR_CURRENT_POWER_W DOMAIN = "switcher_kis" @@ -17,12 +16,5 @@ ATTR_REMAINING_TIME = "remaining_time" CONF_AUTO_OFF = "auto_off" CONF_TIMER_MINUTES = "timer_minutes" -DEVICE_PROPERTIES_TO_HA_ATTRIBUTES = { - "power_consumption": ATTR_CURRENT_POWER_W, - "electric_current": ATTR_ELECTRIC_CURRENT, - "remaining_time": ATTR_REMAINING_TIME, - "auto_off_set": ATTR_AUTO_OFF_SET, -} - SERVICE_SET_AUTO_OFF_NAME = "set_auto_off" SERVICE_TURN_ON_WITH_TIMER_NAME = "turn_on_with_timer" diff --git a/homeassistant/components/switcher_kis/sensor.py b/homeassistant/components/switcher_kis/sensor.py new file mode 100644 index 00000000000..037e7297cee --- /dev/null +++ b/homeassistant/components/switcher_kis/sensor.py @@ -0,0 +1,131 @@ +"""Switcher integration Sensor platform.""" +from __future__ import annotations + +from dataclasses import dataclass + +from aioswitcher.consts import WAITING_TEXT +from aioswitcher.devices import SwitcherV2Device + +from homeassistant.components.sensor import ( + DEVICE_CLASS_CURRENT, + DEVICE_CLASS_POWER, + STATE_CLASS_MEASUREMENT, + SensorEntity, +) +from homeassistant.const import ELECTRICAL_CURRENT_AMPERE, POWER_WATT +from homeassistant.core import HomeAssistant +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.typing import DiscoveryInfoType, StateType + +from .const import DATA_DEVICE, DOMAIN, SIGNAL_SWITCHER_DEVICE_UPDATE + + +@dataclass +class AttributeDescription: + """Class to describe a sensor.""" + + name: str + icon: str | None = None + unit: str | None = None + device_class: str | None = None + state_class: str | None = None + default_enabled: bool = True + default_value: float | int | str | None = None + + +POWER_SENSORS = { + "power_consumption": AttributeDescription( + name="Power Consumption", + unit=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + default_value=0, + ), + "electric_current": AttributeDescription( + name="Electric Current", + unit=ELECTRICAL_CURRENT_AMPERE, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + default_value=0.0, + ), +} + +TIME_SENSORS = { + "remaining_time": AttributeDescription( + name="Remaining Time", + icon="mdi:av-timer", + default_value="00:00:00", + ), + "auto_off_set": AttributeDescription( + name="Auto Shutdown", + icon="mdi:progress-clock", + default_enabled=False, + default_value="00:00:00", + ), +} + +SENSORS = {**POWER_SENSORS, **TIME_SENSORS} + + +async def async_setup_platform( + hass: HomeAssistant, + config: dict, + async_add_entities: AddEntitiesCallback, + discovery_info: DiscoveryInfoType, +) -> None: + """Set up Switcher sensor from config entry.""" + device_data = hass.data[DOMAIN][DATA_DEVICE] + + async_add_entities( + SwitcherSensorEntity(device_data, attribute, SENSORS[attribute]) + for attribute in SENSORS + ) + + +class SwitcherSensorEntity(SensorEntity): + """Representation of a Switcher sensor entity.""" + + def __init__( + self, + device_data: SwitcherV2Device, + attribute: str, + description: AttributeDescription, + ) -> None: + """Initialize the entity.""" + self._device_data = device_data + self.attribute = attribute + self.description = description + + # Entity class attributes + self._attr_name = f"{self._device_data.name} {self.description.name}" + self._attr_icon = self.description.icon + self._attr_unit_of_measurement = self.description.unit + self._attr_device_class = self.description.device_class + self._attr_entity_registry_enabled_default = self.description.default_enabled + self._attr_should_poll = False + + self._attr_unique_id = f"{self._device_data.device_id}-{self._device_data.mac_addr}-{self.attribute}" + + @property + def state(self) -> StateType: + """Return value of sensor.""" + value = getattr(self._device_data, self.attribute) + if value and value is not WAITING_TEXT: + return value + + return self.description.default_value + + async def async_added_to_hass(self) -> None: + """Run when entity about to be added to hass.""" + self.async_on_remove( + async_dispatcher_connect( + self.hass, SIGNAL_SWITCHER_DEVICE_UPDATE, self.async_update_data + ) + ) + + async def async_update_data(self, device_data: SwitcherV2Device) -> None: + """Update the entity data.""" + if device_data: + self._device_data = device_data + self.async_write_ha_state() diff --git a/homeassistant/components/switcher_kis/switch.py b/homeassistant/components/switcher_kis/switch.py index 343d4dd8b13..27d9e16e1f8 100644 --- a/homeassistant/components/switcher_kis/switch.py +++ b/homeassistant/components/switcher_kis/switch.py @@ -8,7 +8,6 @@ from aioswitcher.consts import ( COMMAND_ON, STATE_OFF as SWITCHER_STATE_OFF, STATE_ON as SWITCHER_STATE_ON, - WAITING_TEXT, ) from aioswitcher.devices import SwitcherV2Device import voluptuous as vol @@ -23,7 +22,6 @@ from .const import ( CONF_AUTO_OFF, CONF_TIMER_MINUTES, DATA_DEVICE, - DEVICE_PROPERTIES_TO_HA_ATTRIBUTES, DOMAIN, SERVICE_SET_AUTO_OFF_NAME, SERVICE_TURN_ON_WITH_TIMER_NAME, @@ -124,23 +122,6 @@ class SwitcherControl(SwitchEntity): """Return True if entity is on.""" return self._state == SWITCHER_STATE_ON - @property - def current_power_w(self) -> int: - """Return the current power usage in W.""" - return self._device_data.power_consumption - - @property - def extra_state_attributes(self) -> dict: - """Return the optional state attributes.""" - attribs = {} - - for prop, attr in DEVICE_PROPERTIES_TO_HA_ATTRIBUTES.items(): - value = getattr(self._device_data, prop) - if value and value is not WAITING_TEXT: - attribs[attr] = value - - return attribs - @property def available(self) -> bool: """Return True if entity is available."""