Migrate Switcher entity attributes to sensors (#51964)

* Migrate attributes to sensors

Migrate attributes to sensors

* Fix pylint

* Apply suggestions from code review

Co-authored-by: Franck Nijhof <git@frenck.dev>

* Add typing imports

Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
Shay Levy 2021-06-22 19:28:09 +03:00 committed by GitHub
parent d08129352f
commit 5795e76826
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 135 additions and 30 deletions

View file

@ -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

View file

@ -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:

View file

@ -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"

View file

@ -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()

View file

@ -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."""