Initial Home Assistant Configuration
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
""" Implement the Switch entities of this implementation """
|
||||
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from home_connect_async import Appliance, HomeConnect, HomeConnectError, Events
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .common import InteractiveEntityBase, EntityManager, is_boolean_enum, Configuration
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
async def async_setup_entry(hass:HomeAssistant , config_entry:ConfigType, async_add_entities:AddEntitiesCallback) -> None:
|
||||
"""Add sensors for passed config_entry in HA."""
|
||||
#homeconnect:HomeConnect = hass.data[DOMAIN]['homeconnect']
|
||||
entry_conf:Configuration = hass.data[DOMAIN][config_entry.entry_id]
|
||||
homeconnect:HomeConnect = entry_conf["homeconnect"]
|
||||
entity_manager = EntityManager(async_add_entities, "Switch")
|
||||
|
||||
def add_appliance(appliance:Appliance) -> None:
|
||||
conf = entry_conf.get_config()
|
||||
if appliance.available_programs:
|
||||
for program in appliance.available_programs.values():
|
||||
if program.options:
|
||||
for option in program.options.values():
|
||||
if ( not conf.has_entity_setting(option.key, "type") and (option.type == "Boolean" or isinstance(option.value, bool))) \
|
||||
or conf.get_entity_setting(option.key, "type") == "Boolean" :
|
||||
device = OptionSwitch(appliance, option.key, conf)
|
||||
entity_manager.add(device)
|
||||
|
||||
if appliance.settings:
|
||||
for setting in appliance.settings.values():
|
||||
if ( (not conf.has_entity_setting(setting.key, "type")
|
||||
and ( setting.type == "Boolean" or isinstance(setting.value, bool) or is_boolean_enum(setting.allowedvalues))) \
|
||||
or conf.get_entity_setting(setting.key, "type") == "Boolean") \
|
||||
and setting.access != "read" :
|
||||
device = SettingsSwitch(appliance, setting.key, conf)
|
||||
entity_manager.add(device)
|
||||
|
||||
entity_manager.register()
|
||||
|
||||
|
||||
def remove_appliance(appliance:Appliance) -> None:
|
||||
entity_manager.remove_appliance(appliance)
|
||||
|
||||
homeconnect.register_callback(add_appliance, [Events.PAIRED, Events.DATA_CHANGED, Events.PROGRAM_STARTED, Events.PROGRAM_SELECTED])
|
||||
homeconnect.register_callback(remove_appliance, Events.DEPAIRED)
|
||||
for appliance in homeconnect.appliances.values():
|
||||
add_appliance(appliance)
|
||||
|
||||
|
||||
class OptionSwitch(InteractiveEntityBase, SwitchEntity):
|
||||
""" Switch for binary options """
|
||||
@property
|
||||
def device_class(self) -> str:
|
||||
return f"{DOMAIN}__options"
|
||||
|
||||
@property
|
||||
def name_ext(self) -> str|None:
|
||||
if self._appliance.available_programs:
|
||||
for program in self._appliance.available_programs.values():
|
||||
if program.options and self._key in program.options and program.options[self._key].name:
|
||||
return program.options[self._key].name
|
||||
return None
|
||||
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
return self.get_entity_setting('icon', 'mdi:office-building-cog')
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
return self.program_option_available
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if entity is on."""
|
||||
option = self._appliance.get_applied_program_option(self._key)
|
||||
if option:
|
||||
return option.value
|
||||
return None
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity on."""
|
||||
try:
|
||||
await self._appliance.async_set_option(self._key, True)
|
||||
except HomeConnectError as ex:
|
||||
if ex.error_description:
|
||||
raise HomeAssistantError(f"Failed to set the option: {ex.error_description} ({ex.code})")
|
||||
raise HomeAssistantError(f"Failed to set the option: ({ex.code})")
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity off."""
|
||||
try:
|
||||
await self._appliance.async_set_option(self._key, False)
|
||||
except HomeConnectError as ex:
|
||||
if ex.error_description:
|
||||
raise HomeAssistantError(f"Failed to set the option: {ex.error_description} ({ex.code})")
|
||||
raise HomeAssistantError(f"Failed to set the option: ({ex.code})")
|
||||
|
||||
|
||||
async def async_on_update(self, appliance:Appliance, key:str, value) -> None:
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class SettingsSwitch(InteractiveEntityBase, SwitchEntity):
|
||||
""" Switch for binary settings """
|
||||
@property
|
||||
def device_class(self) -> str:
|
||||
return f"{DOMAIN}__settings"
|
||||
|
||||
@property
|
||||
def name_ext(self) -> str|None:
|
||||
if self._key in self._appliance.settings and self._appliance.settings[self._key].name:
|
||||
return self._appliance.settings[self._key].name
|
||||
return None
|
||||
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
return self.get_entity_setting('icon', 'mdi:tune')
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
return self._key in self._appliance.settings \
|
||||
and super().available \
|
||||
and (
|
||||
"BSH.Common.Status.RemoteControlActive" not in self._appliance.status or
|
||||
self._appliance.status["BSH.Common.Status.RemoteControlActive"].value
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if entity is on."""
|
||||
if self._key in self._appliance.settings:
|
||||
setting = self._appliance.settings[self._key]
|
||||
if setting.allowedvalues and setting.value.lower().endswith(".off"):
|
||||
return False
|
||||
if setting.allowedvalues and setting.value.lower().endswith(".on"):
|
||||
return True
|
||||
return setting.value
|
||||
return None
|
||||
|
||||
def bool_to_enum(self, allowedvalues, val:bool) -> str:
|
||||
""" Get the matching enum value for the provided boolean value """
|
||||
for av in allowedvalues:
|
||||
if (val and av.lower().endswith('.on')) or (not val and av.lower().endswith('.off')) :
|
||||
return av
|
||||
_LOGGER.error("Unexpected Error: couldn't find a boolean enum value in allowedvalues: %s", allowedvalues)
|
||||
return None
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
try:
|
||||
setting = self._appliance.settings[self._key]
|
||||
if setting.allowedvalues:
|
||||
await self._appliance.async_apply_setting(self._key, self.bool_to_enum(setting.allowedvalues, True))
|
||||
else:
|
||||
await self._appliance.async_apply_setting(self._key, True)
|
||||
except HomeConnectError as ex:
|
||||
if ex.error_description:
|
||||
raise HomeAssistantError(f"Failed to apply the setting: {ex.error_description} ({ex.code})")
|
||||
raise HomeAssistantError(f"Failed to apply the setting: ({ex.code})")
|
||||
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity off."""
|
||||
try:
|
||||
setting = self._appliance.settings[self._key]
|
||||
if setting.allowedvalues:
|
||||
await self._appliance.async_apply_setting(self._key, self.bool_to_enum(setting.allowedvalues, False))
|
||||
else:
|
||||
await self._appliance.async_apply_setting(self._key, False)
|
||||
except HomeConnectError as ex:
|
||||
if ex.error_description:
|
||||
raise HomeAssistantError(f"Failed to apply the setting: {ex.error_description} ({ex.code})")
|
||||
raise HomeAssistantError(f"Failed to apply the setting: ({ex.code})")
|
||||
|
||||
|
||||
async def async_on_update(self, appliance:Appliance, key:str, value) -> None:
|
||||
self.async_write_ha_state()
|
||||
Reference in New Issue
Block a user