Address late review of fritzbox (#82369)

This commit is contained in:
Michael 2022-11-19 15:12:24 +01:00 committed by GitHub
parent 93897016f0
commit 217d8eb9c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 78 deletions

View File

@ -111,16 +111,16 @@ class FritzBoxEntity(CoordinatorEntity[FritzboxDataUpdateCoordinator], ABC):
self.ain = ain self.ain = ain
if entity_description is not None: if entity_description is not None:
self.entity_description = entity_description self.entity_description = entity_description
self._attr_name = f"{self.entity.name} {entity_description.name}" self._attr_name = f"{self.data.name} {entity_description.name}"
self._attr_unique_id = f"{ain}_{entity_description.key}" self._attr_unique_id = f"{ain}_{entity_description.key}"
else: else:
self._attr_name = self.entity.name self._attr_name = self.data.name
self._attr_unique_id = ain self._attr_unique_id = ain
@property @property
@abstractmethod @abstractmethod
def entity(self) -> FritzhomeEntityBase: def data(self) -> FritzhomeEntityBase:
"""Return entity object from coordinator.""" """Return data object from coordinator."""
class FritzBoxDeviceEntity(FritzBoxEntity): class FritzBoxDeviceEntity(FritzBoxEntity):
@ -129,21 +129,21 @@ class FritzBoxDeviceEntity(FritzBoxEntity):
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return if entity is available.""" """Return if entity is available."""
return super().available and self.entity.present return super().available and self.data.present
@property @property
def entity(self) -> FritzhomeDevice: def data(self) -> FritzhomeDevice:
"""Return device object from coordinator.""" """Return device data object from coordinator."""
return self.coordinator.data.devices[self.ain] return self.coordinator.data.devices[self.ain]
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return device specific attributes.""" """Return device specific attributes."""
return DeviceInfo( return DeviceInfo(
name=self.entity.name, name=self.data.name,
identifiers={(DOMAIN, self.ain)}, identifiers={(DOMAIN, self.ain)},
manufacturer=self.entity.manufacturer, manufacturer=self.data.manufacturer,
model=self.entity.productname, model=self.data.productname,
sw_version=self.entity.fw_version, sw_version=self.data.fw_version,
configuration_url=self.coordinator.configuration_url, configuration_url=self.coordinator.configuration_url,
) )

View File

@ -68,7 +68,9 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the FRITZ!SmartHome binary sensor from ConfigEntry.""" """Set up the FRITZ!SmartHome binary sensor from ConfigEntry."""
coordinator = hass.data[FRITZBOX_DOMAIN][entry.entry_id][CONF_COORDINATOR] coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
async_add_entities( async_add_entities(
[ [
@ -93,10 +95,10 @@ class FritzboxBinarySensor(FritzBoxDeviceEntity, BinarySensorEntity):
) -> None: ) -> None:
"""Initialize the FritzBox entity.""" """Initialize the FritzBox entity."""
super().__init__(coordinator, ain, entity_description) super().__init__(coordinator, ain, entity_description)
self._attr_name = f"{self.entity.name} {entity_description.name}" self._attr_name = f"{self.data.name} {entity_description.name}"
self._attr_unique_id = f"{ain}_{entity_description.key}" self._attr_unique_id = f"{ain}_{entity_description.key}"
@property @property
def is_on(self) -> bool | None: def is_on(self) -> bool | None:
"""Return true if sensor is on.""" """Return true if sensor is on."""
return self.entity_description.is_on(self.entity) return self.entity_description.is_on(self.data)

View File

@ -31,15 +31,15 @@ class FritzBoxTemplate(FritzBoxEntity, ButtonEntity):
"""Interface between FritzhomeTemplate and hass.""" """Interface between FritzhomeTemplate and hass."""
@property @property
def entity(self) -> FritzhomeTemplate: def data(self) -> FritzhomeTemplate:
"""Return the template entity.""" """Return the template data entity."""
return self.coordinator.data.templates[self.ain] return self.coordinator.data.templates[self.ain]
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return device specific attributes.""" """Return device specific attributes."""
return DeviceInfo( return DeviceInfo(
name=self.entity.name, name=self.data.name,
identifiers={(FRITZBOX_DOMAIN, self.ain)}, identifiers={(FRITZBOX_DOMAIN, self.ain)},
configuration_url=self.coordinator.configuration_url, configuration_url=self.coordinator.configuration_url,
manufacturer="AVM", manufacturer="AVM",

View File

@ -21,7 +21,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import FritzBoxDeviceEntity from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import ( from .const import (
ATTR_STATE_BATTERY_LOW, ATTR_STATE_BATTERY_LOW,
ATTR_STATE_HOLIDAY_MODE, ATTR_STATE_HOLIDAY_MODE,
@ -50,7 +50,9 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the FRITZ!SmartHome thermostat from ConfigEntry.""" """Set up the FRITZ!SmartHome thermostat from ConfigEntry."""
coordinator = hass.data[FRITZBOX_DOMAIN][entry.entry_id][CONF_COORDINATOR] coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
async_add_entities( async_add_entities(
[ [
@ -73,18 +75,18 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
@property @property
def current_temperature(self) -> float: def current_temperature(self) -> float:
"""Return the current temperature.""" """Return the current temperature."""
if self.entity.has_temperature_sensor and self.entity.temperature is not None: if self.data.has_temperature_sensor and self.data.temperature is not None:
return self.entity.temperature # type: ignore [no-any-return] return self.data.temperature # type: ignore [no-any-return]
return self.entity.actual_temperature # type: ignore [no-any-return] return self.data.actual_temperature # type: ignore [no-any-return]
@property @property
def target_temperature(self) -> float: def target_temperature(self) -> float:
"""Return the temperature we try to reach.""" """Return the temperature we try to reach."""
if self.entity.target_temperature == ON_API_TEMPERATURE: if self.data.target_temperature == ON_API_TEMPERATURE:
return ON_REPORT_SET_TEMPERATURE return ON_REPORT_SET_TEMPERATURE
if self.entity.target_temperature == OFF_API_TEMPERATURE: if self.data.target_temperature == OFF_API_TEMPERATURE:
return OFF_REPORT_SET_TEMPERATURE return OFF_REPORT_SET_TEMPERATURE
return self.entity.target_temperature # type: ignore [no-any-return] return self.data.target_temperature # type: ignore [no-any-return]
async def async_set_temperature(self, **kwargs: Any) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature.""" """Set new target temperature."""
@ -94,14 +96,14 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
elif kwargs.get(ATTR_TEMPERATURE) is not None: elif kwargs.get(ATTR_TEMPERATURE) is not None:
temperature = kwargs[ATTR_TEMPERATURE] temperature = kwargs[ATTR_TEMPERATURE]
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self.entity.set_target_temperature, temperature self.data.set_target_temperature, temperature
) )
await self.coordinator.async_refresh() await self.coordinator.async_refresh()
@property @property
def hvac_mode(self) -> str: def hvac_mode(self) -> str:
"""Return the current operation mode.""" """Return the current operation mode."""
if self.entity.target_temperature in ( if self.data.target_temperature in (
OFF_REPORT_SET_TEMPERATURE, OFF_REPORT_SET_TEMPERATURE,
OFF_API_TEMPERATURE, OFF_API_TEMPERATURE,
): ):
@ -119,16 +121,14 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
if hvac_mode == HVACMode.OFF: if hvac_mode == HVACMode.OFF:
await self.async_set_temperature(temperature=OFF_REPORT_SET_TEMPERATURE) await self.async_set_temperature(temperature=OFF_REPORT_SET_TEMPERATURE)
else: else:
await self.async_set_temperature( await self.async_set_temperature(temperature=self.data.comfort_temperature)
temperature=self.entity.comfort_temperature
)
@property @property
def preset_mode(self) -> str | None: def preset_mode(self) -> str | None:
"""Return current preset mode.""" """Return current preset mode."""
if self.entity.target_temperature == self.entity.comfort_temperature: if self.data.target_temperature == self.data.comfort_temperature:
return PRESET_COMFORT return PRESET_COMFORT
if self.entity.target_temperature == self.entity.eco_temperature: if self.data.target_temperature == self.data.eco_temperature:
return PRESET_ECO return PRESET_ECO
return None return None
@ -140,11 +140,9 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
async def async_set_preset_mode(self, preset_mode: str) -> None: async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set preset mode.""" """Set preset mode."""
if preset_mode == PRESET_COMFORT: if preset_mode == PRESET_COMFORT:
await self.async_set_temperature( await self.async_set_temperature(temperature=self.data.comfort_temperature)
temperature=self.entity.comfort_temperature
)
elif preset_mode == PRESET_ECO: elif preset_mode == PRESET_ECO:
await self.async_set_temperature(temperature=self.entity.eco_temperature) await self.async_set_temperature(temperature=self.data.eco_temperature)
@property @property
def min_temp(self) -> int: def min_temp(self) -> int:
@ -160,17 +158,17 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
def extra_state_attributes(self) -> ClimateExtraAttributes: def extra_state_attributes(self) -> ClimateExtraAttributes:
"""Return the device specific state attributes.""" """Return the device specific state attributes."""
attrs: ClimateExtraAttributes = { attrs: ClimateExtraAttributes = {
ATTR_STATE_BATTERY_LOW: self.entity.battery_low, ATTR_STATE_BATTERY_LOW: self.data.battery_low,
} }
# the following attributes are available since fritzos 7 # the following attributes are available since fritzos 7
if self.entity.battery_level is not None: if self.data.battery_level is not None:
attrs[ATTR_BATTERY_LEVEL] = self.entity.battery_level attrs[ATTR_BATTERY_LEVEL] = self.data.battery_level
if self.entity.holiday_active is not None: if self.data.holiday_active is not None:
attrs[ATTR_STATE_HOLIDAY_MODE] = self.entity.holiday_active attrs[ATTR_STATE_HOLIDAY_MODE] = self.data.holiday_active
if self.entity.summer_active is not None: if self.data.summer_active is not None:
attrs[ATTR_STATE_SUMMER_MODE] = self.entity.summer_active attrs[ATTR_STATE_SUMMER_MODE] = self.data.summer_active
if self.entity.window_open is not None: if self.data.window_open is not None:
attrs[ATTR_STATE_WINDOW_OPEN] = self.entity.window_open attrs[ATTR_STATE_WINDOW_OPEN] = self.data.window_open
return attrs return attrs

View File

@ -13,7 +13,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import FritzBoxDeviceEntity from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
@ -21,7 +21,9 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the FRITZ!SmartHome cover from ConfigEntry.""" """Set up the FRITZ!SmartHome cover from ConfigEntry."""
coordinator = hass.data[FRITZBOX_DOMAIN][entry.entry_id][CONF_COORDINATOR] coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
async_add_entities( async_add_entities(
FritzboxCover(coordinator, ain) FritzboxCover(coordinator, ain)
@ -45,34 +47,34 @@ class FritzboxCover(FritzBoxDeviceEntity, CoverEntity):
def current_cover_position(self) -> int | None: def current_cover_position(self) -> int | None:
"""Return the current position.""" """Return the current position."""
position = None position = None
if self.entity.levelpercentage is not None: if self.data.levelpercentage is not None:
position = 100 - self.entity.levelpercentage position = 100 - self.data.levelpercentage
return position return position
@property @property
def is_closed(self) -> bool | None: def is_closed(self) -> bool | None:
"""Return if the cover is closed.""" """Return if the cover is closed."""
if self.entity.levelpercentage is None: if self.data.levelpercentage is None:
return None return None
return self.entity.levelpercentage == 100 # type: ignore [no-any-return] return self.data.levelpercentage == 100 # type: ignore [no-any-return]
async def async_open_cover(self, **kwargs: Any) -> None: async def async_open_cover(self, **kwargs: Any) -> None:
"""Open the cover.""" """Open the cover."""
await self.hass.async_add_executor_job(self.entity.set_blind_open) await self.hass.async_add_executor_job(self.data.set_blind_open)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()
async def async_close_cover(self, **kwargs: Any) -> None: async def async_close_cover(self, **kwargs: Any) -> None:
"""Close the cover.""" """Close the cover."""
await self.hass.async_add_executor_job(self.entity.set_blind_close) await self.hass.async_add_executor_job(self.data.set_blind_close)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()
async def async_set_cover_position(self, **kwargs: Any) -> None: async def async_set_cover_position(self, **kwargs: Any) -> None:
"""Move the cover to a specific position.""" """Move the cover to a specific position."""
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self.entity.set_level_percentage, 100 - kwargs[ATTR_POSITION] self.data.set_level_percentage, 100 - kwargs[ATTR_POSITION]
) )
async def async_stop_cover(self, **kwargs: Any) -> None: async def async_stop_cover(self, **kwargs: Any) -> None:
"""Stop the cover.""" """Stop the cover."""
await self.hass.async_add_executor_job(self.entity.set_blind_stop) await self.hass.async_add_executor_job(self.data.set_blind_stop)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()

View File

@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import FritzBoxDeviceEntity from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import ( from .const import (
COLOR_MODE, COLOR_MODE,
COLOR_TEMP_MODE, COLOR_TEMP_MODE,
@ -24,7 +24,6 @@ from .const import (
DOMAIN as FRITZBOX_DOMAIN, DOMAIN as FRITZBOX_DOMAIN,
LOGGER, LOGGER,
) )
from .coordinator import FritzboxDataUpdateCoordinator
SUPPORTED_COLOR_MODES = {ColorMode.COLOR_TEMP, ColorMode.HS} SUPPORTED_COLOR_MODES = {ColorMode.COLOR_TEMP, ColorMode.HS}
@ -34,7 +33,9 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the FRITZ!SmartHome light from ConfigEntry.""" """Set up the FRITZ!SmartHome light from ConfigEntry."""
entities: list[FritzboxLight] = [] entities: list[FritzboxLight] = []
coordinator = hass.data[FRITZBOX_DOMAIN][entry.entry_id][CONF_COORDINATOR] coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
for ain, device in coordinator.data.devices.items(): for ain, device in coordinator.data.devices.items():
if not device.has_lightbulb: if not device.has_lightbulb:
@ -88,36 +89,36 @@ class FritzboxLight(FritzBoxDeviceEntity, LightEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""If the light is currently on or off.""" """If the light is currently on or off."""
return self.entity.state # type: ignore [no-any-return] return self.data.state # type: ignore [no-any-return]
@property @property
def brightness(self) -> int: def brightness(self) -> int:
"""Return the current Brightness.""" """Return the current Brightness."""
return self.entity.level # type: ignore [no-any-return] return self.data.level # type: ignore [no-any-return]
@property @property
def hs_color(self) -> tuple[float, float] | None: def hs_color(self) -> tuple[float, float] | None:
"""Return the hs color value.""" """Return the hs color value."""
if self.entity.color_mode != COLOR_MODE: if self.data.color_mode != COLOR_MODE:
return None return None
hue = self.entity.hue hue = self.data.hue
saturation = self.entity.saturation saturation = self.data.saturation
return (hue, float(saturation) * 100.0 / 255.0) return (hue, float(saturation) * 100.0 / 255.0)
@property @property
def color_temp_kelvin(self) -> int | None: def color_temp_kelvin(self) -> int | None:
"""Return the CT color value.""" """Return the CT color value."""
if self.entity.color_mode != COLOR_TEMP_MODE: if self.data.color_mode != COLOR_TEMP_MODE:
return None return None
return self.entity.color_temp # type: ignore [no-any-return] return self.data.color_temp # type: ignore [no-any-return]
@property @property
def color_mode(self) -> ColorMode: def color_mode(self) -> ColorMode:
"""Return the color mode of the light.""" """Return the color mode of the light."""
if self.entity.color_mode == COLOR_MODE: if self.data.color_mode == COLOR_MODE:
return ColorMode.HS return ColorMode.HS
return ColorMode.COLOR_TEMP return ColorMode.COLOR_TEMP
@ -130,7 +131,7 @@ class FritzboxLight(FritzBoxDeviceEntity, LightEntity):
"""Turn the light on.""" """Turn the light on."""
if kwargs.get(ATTR_BRIGHTNESS) is not None: if kwargs.get(ATTR_BRIGHTNESS) is not None:
level = kwargs[ATTR_BRIGHTNESS] level = kwargs[ATTR_BRIGHTNESS]
await self.hass.async_add_executor_job(self.entity.set_level, level) await self.hass.async_add_executor_job(self.data.set_level, level)
if kwargs.get(ATTR_HS_COLOR) is not None: if kwargs.get(ATTR_HS_COLOR) is not None:
# Try setunmappedcolor first. This allows free color selection, # Try setunmappedcolor first. This allows free color selection,
# but we don't know if its supported by all devices. # but we don't know if its supported by all devices.
@ -139,7 +140,7 @@ class FritzboxLight(FritzBoxDeviceEntity, LightEntity):
unmapped_hue = int(kwargs[ATTR_HS_COLOR][0] % 360) unmapped_hue = int(kwargs[ATTR_HS_COLOR][0] % 360)
unmapped_saturation = round(kwargs[ATTR_HS_COLOR][1] * 255.0 / 100.0) unmapped_saturation = round(kwargs[ATTR_HS_COLOR][1] * 255.0 / 100.0)
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self.entity.set_unmapped_color, (unmapped_hue, unmapped_saturation) self.data.set_unmapped_color, (unmapped_hue, unmapped_saturation)
) )
# This will raise 400 BAD REQUEST if the setunmappedcolor is not available # This will raise 400 BAD REQUEST if the setunmappedcolor is not available
except HTTPError as err: except HTTPError as err:
@ -157,18 +158,18 @@ class FritzboxLight(FritzBoxDeviceEntity, LightEntity):
key=lambda x: abs(x - unmapped_saturation), key=lambda x: abs(x - unmapped_saturation),
) )
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self.entity.set_color, (hue, saturation) self.data.set_color, (hue, saturation)
) )
if kwargs.get(ATTR_COLOR_TEMP_KELVIN) is not None: if kwargs.get(ATTR_COLOR_TEMP_KELVIN) is not None:
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self.entity.set_color_temp, kwargs[ATTR_COLOR_TEMP_KELVIN] self.data.set_color_temp, kwargs[ATTR_COLOR_TEMP_KELVIN]
) )
await self.hass.async_add_executor_job(self.entity.set_state_on) await self.hass.async_add_executor_job(self.data.set_state_on)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the light off.""" """Turn the light off."""
await self.hass.async_add_executor_job(self.entity.set_state_off) await self.hass.async_add_executor_job(self.data.set_state_off)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()

View File

@ -235,4 +235,4 @@ class FritzBoxSensor(FritzBoxDeviceEntity, SensorEntity):
@property @property
def native_value(self) -> StateType | datetime: def native_value(self) -> StateType | datetime:
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self.entity_description.native_value(self.entity) return self.entity_description.native_value(self.data)

View File

@ -8,7 +8,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import FritzBoxDeviceEntity from . import FritzboxDataUpdateCoordinator, FritzBoxDeviceEntity
from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN
@ -16,7 +16,9 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the FRITZ!SmartHome switch from ConfigEntry.""" """Set up the FRITZ!SmartHome switch from ConfigEntry."""
coordinator = hass.data[FRITZBOX_DOMAIN][entry.entry_id][CONF_COORDINATOR] coordinator: FritzboxDataUpdateCoordinator = hass.data[FRITZBOX_DOMAIN][
entry.entry_id
][CONF_COORDINATOR]
async_add_entities( async_add_entities(
[ [
@ -33,14 +35,14 @@ class FritzboxSwitch(FritzBoxDeviceEntity, SwitchEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return true if the switch is on.""" """Return true if the switch is on."""
return self.entity.switch_state # type: ignore [no-any-return] return self.data.switch_state # type: ignore [no-any-return]
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on.""" """Turn the switch on."""
await self.hass.async_add_executor_job(self.entity.set_switch_state_on) await self.hass.async_add_executor_job(self.data.set_switch_state_on)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off.""" """Turn the switch off."""
await self.hass.async_add_executor_job(self.entity.set_switch_state_off) await self.hass.async_add_executor_job(self.data.set_switch_state_off)
await self.coordinator.async_refresh() await self.coordinator.async_refresh()