diff --git a/custom_components/tapo_control/const.py b/custom_components/tapo_control/const.py index 086f53c..51d0b9e 100644 --- a/custom_components/tapo_control/const.py +++ b/custom_components/tapo_control/const.py @@ -5,7 +5,7 @@ from homeassistant.helpers import config_validation as cv -PYTAPO_REQUIRED_VERSION = "3.3.24" +PYTAPO_REQUIRED_VERSION = "3.3.27" DOMAIN = "tapo_control" BRAND = "TP-Link" ALARM_MODE = "alarm_mode" diff --git a/custom_components/tapo_control/manifest.json b/custom_components/tapo_control/manifest.json index 70fa4a7..6dbe336 100644 --- a/custom_components/tapo_control/manifest.json +++ b/custom_components/tapo_control/manifest.json @@ -8,7 +8,7 @@ ], "version": "5.4.31", "requirements": [ - "pytapo==3.3.24" + "pytapo==3.3.27" ], "dependencies": [ "ffmpeg", diff --git a/custom_components/tapo_control/number.py b/custom_components/tapo_control/number.py index c605eb3..877ebff 100644 --- a/custom_components/tapo_control/number.py +++ b/custom_components/tapo_control/number.py @@ -4,7 +4,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity import EntityCategory -from homeassistant.const import STATE_UNAVAILABLE,UnitOfTime +from homeassistant.const import STATE_UNAVAILABLE, UnitOfTime from .const import DOMAIN, LOGGER from .tapo.entities import TapoEntity, TapoNumberEntity @@ -73,20 +73,20 @@ async def setupEntities(entry): if tapoSpeakerVolume: LOGGER.debug("Adding tapoSpeakerVolume...") numbers.append(tapoSpeakerVolume) - if ( - "alarm_config" in entry["camData"] - and ("siren_volume" in entry["camData"]["alarm_config"] or "alarm_volume" in entry["camData"]["alarm_config"]) + if "alarm_config" in entry["camData"] and ( + "siren_volume" in entry["camData"]["alarm_config"] + or "alarm_volume" in entry["camData"]["alarm_config"] ): - tapoSirenVolume = TapoSirenVolume(entry,hass,config_entry) + tapoSirenVolume = TapoSirenVolume(entry, hass, config_entry) if tapoSirenVolume: LOGGER.debug("Adding TapoSirenVolume...") numbers.append(tapoSirenVolume) - if ( - "alarm_config" in entry["camData"] - and ("siren_duration" in entry["camData"]["alarm_config"] or "alarm_duration" in entry["camData"]["alarm_config"]) + if "alarm_config" in entry["camData"] and ( + "siren_duration" in entry["camData"]["alarm_config"] + or "alarm_duration" in entry["camData"]["alarm_config"] ): - tapoSirenDuration = TapoSirenDuration(entry,hass,config_entry) + tapoSirenDuration = TapoSirenDuration(entry, hass, config_entry) if tapoSirenDuration: LOGGER.debug("Adding TapoSirenDuration...") numbers.append(tapoSirenDuration) @@ -259,6 +259,7 @@ def updateTapo(self, camData): else: self._attr_state = camData["speakerVolume"] + class TapoSirenVolume(TapoNumberEntity): def __init__(self, entry: dict, hass: HomeAssistant, config_entry): LOGGER.debug("TapoSirenVolume - init - start") @@ -269,13 +270,14 @@ def __init__(self, entry: dict, hass: HomeAssistant, config_entry): self._attr_step = 1 self._hass = hass self.is_hub = entry["camData"]["alarm_is_hubSiren"] + self.typeOfAlarm = entry["camData"]["alarm_config"]["typeOfAlarm"] if "siren_volume" in entry["camData"]["alarm_config"]: self.value_key = "siren_volume" else: self.value_key = "alarm_volume" - + self._attr_native_value = entry["camData"]["alarm_config"][self.value_key] - + TapoNumberEntity.__init__( self, "Siren volume", @@ -300,13 +302,26 @@ async def async_set_native_value(self, value: float) -> None: ) else: strval = "low" - if value>3: + if value > 3: strval = "normal" - if value>7: + if value > 7: strval = "high" - result = await self._hass.async_add_executor_job( - self._controller.executeFunction, "setAlarmConfig", {"msg_alarm": {self.value_key: strval}} - ) + if self.typeOfAlarm == "getAlarm": + result = await self._hass.async_add_executor_job( + self._controller.setAlarm, + self.alarm_enabled == "on", + "sound" in self.alarm_mode, + "siren" in self.alarm_mode or "light" in self.alarm_mode, + strval, + ) + elif self.typeOfAlarm == "getAlarmConfig": + result = await self._hass.async_add_executor_job( + self._controller.executeFunction, + "setAlarmConfig", + {"msg_alarm": {self.value_key: strval}}, + ) + else: + LOGGER.error("Unexpected type of alarm: " + self.typeOfAlarm) if "error_code" not in result or result["error_code"] == 0: self._attr_state = value self.async_write_ha_state() @@ -316,7 +331,18 @@ def updateTapo(self, camData): if not camData: self._attr_state = STATE_UNAVAILABLE else: - self._attr_state = camData["alarm_config"][self.value_key] + alarmVolume = camData["alarm_config"][self.value_key] + if str(alarmVolume).isnumeric(): + self._attr_state = camData["alarm_config"][self.value_key] + elif str(alarmVolume) == "low": + self._attr_state = 1 + elif str(alarmVolume) == "normal": + self._attr_state = 5 + elif str(alarmVolume) == "high": + self._attr_state = 10 + self.alarm_enabled = camData["alarm_config"]["automatic"] == "on" + self.alarm_mode = camData["alarm_config"]["mode"] + class TapoSirenDuration(TapoNumberEntity): def __init__(self, entry: dict, hass: HomeAssistant, config_entry): @@ -326,11 +352,12 @@ def __init__(self, entry: dict, hass: HomeAssistant, config_entry): self._attr_max_value = 300 self._attr_native_max_value = 300 self.is_hub = entry["camData"]["alarm_is_hubSiren"] + self.typeOfAlarm = entry["camData"]["alarm_config"]["typeOfAlarm"] if self.is_hub: self._attr_max_value = 599 self._attr_native_max_value = 599 self._attr_step = 1 - self._attr_native_unit_of_measurement: UnitOfTime.SECONDS + self._attr_native_unit_of_measurement: UnitOfTime.SECONDS self._hass = hass if "siren_duration" in entry["camData"]["alarm_config"]: self.value_key = "siren_duration" @@ -362,7 +389,9 @@ async def async_set_native_value(self, value: float) -> None: ) else: result = await self._hass.async_add_executor_job( - self._controller.executeFunction, "setAlarmConfig", {"msg_alarm": {self.value_key: int(value)}} + self._controller.executeFunction, + "setAlarmConfig", + {"msg_alarm": {self.value_key: int(value)}}, ) if "error_code" not in result or result["error_code"] == 0: self._attr_state = value diff --git a/custom_components/tapo_control/utils.py b/custom_components/tapo_control/utils.py index 7d3eacd..7434e03 100644 --- a/custom_components/tapo_control/utils.py +++ b/custom_components/tapo_control/utils.py @@ -993,6 +993,7 @@ async def getCamData(hass, controller): hubSiren = True sirenData = data["getSirenConfig"][0] alarmConfig = { + "typeOfAlarm": "getSirenConfig", "siren_type": sirenData["siren_type"], "siren_volume": sirenData["volume"], "siren_duration": sirenData["duration"], @@ -1004,6 +1005,7 @@ async def getCamData(hass, controller): if not hubSiren and data["getAlarmConfig"][0] != False: alarmData = data["getAlarmConfig"][0] alarmConfig = { + "typeOfAlarm": "getAlarmConfig", "mode": alarmData["alarm_mode"], "automatic": alarmData["enabled"], } @@ -1032,6 +1034,7 @@ async def getCamData(hass, controller): ): alarmData = data["getLastAlarmInfo"][0]["msg_alarm"]["chn1_msg_alarm_info"] alarmConfig = { + "typeOfAlarm": "getAlarm", "mode": alarmData["alarm_mode"], "automatic": alarmData["enabled"], } @@ -1480,7 +1483,9 @@ def isCacheSupported(check_function, rawData): ) return True else: - raise Exception(f"Capability {check_function} (mapped to:{function}) cached but not supported.") + raise Exception( + f"Capability {check_function} (mapped to:{function}) cached but not supported." + ) return False