From d404282cab311803d67bf076c917ab4aaccdbe19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Sun, 21 Jul 2024 11:06:24 +0200 Subject: [PATCH 1/7] Add: warning message to log data about doorbell --- custom_components/tapo_control/select.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/tapo_control/select.py b/custom_components/tapo_control/select.py index c5eab26..d7b0187 100644 --- a/custom_components/tapo_control/select.py +++ b/custom_components/tapo_control/select.py @@ -312,6 +312,7 @@ async def async_update(self) -> None: await self._coordinator.async_request_refresh() def updateTapo(self, camData): + LOGGER.warn(camData) if not camData: self._attr_state = "unavailable" else: From 0390aac3cb3284ce6c92a57de4d7c7d3a304e051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Mon, 22 Jul 2024 11:50:42 +0200 Subject: [PATCH 2/7] Revert: tapoNightVisionSelect to use getDayNightMode as dependency --- custom_components/tapo_control/select.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/custom_components/tapo_control/select.py b/custom_components/tapo_control/select.py index 77a1baa..0f1b255 100644 --- a/custom_components/tapo_control/select.py +++ b/custom_components/tapo_control/select.py @@ -23,11 +23,10 @@ async def async_setup_entry( async def setupEntities(entry): selects = [] - if ( - "day_night_mode" in entry["camData"] - and entry["camData"]["day_night_mode"] is not None - ): - tapoNightVisionSelect = TapoNightVisionSelect(entry, hass, config_entry) + tapoNightVisionSelect = await check_and_create( + entry, hass, TapoNightVisionSelect, "getDayNightMode", config_entry + ) + if tapoNightVisionSelect: LOGGER.debug("Adding tapoNightVisionSelect...") selects.append(tapoNightVisionSelect) From c239c5f4419d47fff1eb9d1dd1010a0a4863e2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Mon, 22 Jul 2024 11:52:39 +0200 Subject: [PATCH 3/7] Revert "Revert: tapoNightVisionSelect to use getDayNightMode as dependency" This reverts commit 0390aac3cb3284ce6c92a57de4d7c7d3a304e051. --- custom_components/tapo_control/select.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/custom_components/tapo_control/select.py b/custom_components/tapo_control/select.py index 0f1b255..77a1baa 100644 --- a/custom_components/tapo_control/select.py +++ b/custom_components/tapo_control/select.py @@ -23,10 +23,11 @@ async def async_setup_entry( async def setupEntities(entry): selects = [] - tapoNightVisionSelect = await check_and_create( - entry, hass, TapoNightVisionSelect, "getDayNightMode", config_entry - ) - if tapoNightVisionSelect: + if ( + "day_night_mode" in entry["camData"] + and entry["camData"]["day_night_mode"] is not None + ): + tapoNightVisionSelect = TapoNightVisionSelect(entry, hass, config_entry) LOGGER.debug("Adding tapoNightVisionSelect...") selects.append(tapoNightVisionSelect) From 8378834a5632b13f558fcff809c82f1d3e445672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Mon, 22 Jul 2024 11:57:31 +0200 Subject: [PATCH 4/7] Fix: D230 missing night vision select --- custom_components/tapo_control/utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/custom_components/tapo_control/utils.py b/custom_components/tapo_control/utils.py index 731c78f..7a06a85 100644 --- a/custom_components/tapo_control/utils.py +++ b/custom_components/tapo_control/utils.py @@ -930,6 +930,14 @@ async def getCamData(hass, controller): except Exception: day_night_mode = None + if day_night_mode is None: + try: + day_night_mode = data["getLightFrequencyInfo"][0]["image"]["common"][ + "inf_type" + ] + except Exception: + day_night_mode = None + if day_night_mode is None: try: if ( From 10cf678de4c219d1ffd7fe7f85cdb5faa5047878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Mon, 22 Jul 2024 21:33:14 +0200 Subject: [PATCH 5/7] Add: Night Vision switching and Night Vision select fields adjustments --- custom_components/tapo_control/const.py | 1 - custom_components/tapo_control/select.py | 61 ++++++++++++++---- custom_components/tapo_control/utils.py | 81 ++++++++++++++---------- 3 files changed, 98 insertions(+), 45 deletions(-) diff --git a/custom_components/tapo_control/const.py b/custom_components/tapo_control/const.py index 0ffa7f0..1242e7a 100644 --- a/custom_components/tapo_control/const.py +++ b/custom_components/tapo_control/const.py @@ -13,7 +13,6 @@ LIGHT = "light" SOUND = "sound" PRIVACY_MODE = "privacy_mode" -DAY_NIGHT_MODE = "day_night_mode" ALARM = "alarm" LED_MODE = "led_mode" NAME = "name" diff --git a/custom_components/tapo_control/select.py b/custom_components/tapo_control/select.py index 77a1baa..73ff4a9 100644 --- a/custom_components/tapo_control/select.py +++ b/custom_components/tapo_control/select.py @@ -5,7 +5,7 @@ from .const import DOMAIN, LOGGER from .tapo.entities import TapoSelectEntity -from .utils import check_and_create +from .utils import check_and_create, getNightModeName, getNightModeValue async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -24,11 +24,36 @@ async def setupEntities(entry): selects = [] if ( - "day_night_mode" in entry["camData"] - and entry["camData"]["day_night_mode"] is not None + "night_vision_mode_switching" in entry["camData"] + and entry["camData"]["night_vision_mode_switching"] is not None ): - tapoNightVisionSelect = TapoNightVisionSelect(entry, hass, config_entry) - LOGGER.debug("Adding tapoNightVisionSelect...") + tapoNightVisionSelect = TapoNightVisionSelect( + entry, + hass, + config_entry, + "Night Vision Switching", + ["auto", "on", "off"], + "night_vision_mode_switching", + entry["controller"].setDayNightMode, + ) + LOGGER.debug("Adding tapoNightVisionSelect (Night Vision Switching)...") + selects.append(tapoNightVisionSelect) + + if ( + "night_vision_mode" in entry["camData"] + and entry["camData"]["night_vision_mode"] is not None + and entry["camData"]["night_vision_capability"] is not None + ): + tapoNightVisionSelect = TapoNightVisionSelect( + entry, + hass, + config_entry, + "Night Vision", + entry["camData"]["night_vision_capability"], + "night_vision_mode", + entry["controller"].setNightVisionModeConfig, + ) + LOGGER.debug("Adding tapoNightVisionSelect (Night Vision)...") selects.append(tapoNightVisionSelect) tapoLightFrequencySelect = await check_and_create( @@ -316,12 +341,26 @@ def entity_category(self): class TapoNightVisionSelect(TapoSelectEntity): - def __init__(self, entry: dict, hass: HomeAssistant, config_entry): - self._attr_options = ["auto", "on", "off"] + def __init__( + self, + entry: dict, + hass: HomeAssistant, + config_entry, + entityName: str, + nightVisionOptions: list, + currentValueKey: str, + method, + ): + self._attr_options = [] + self.method = method + self.currentValueKey = currentValueKey + for nightVisionCapability in nightVisionOptions: + self._attr_options.append(getNightModeName(nightVisionCapability)) + self._attr_current_option = None TapoSelectEntity.__init__( self, - "Night Vision", + entityName, entry, hass, config_entry, @@ -333,16 +372,16 @@ async def async_update(self) -> None: await self._coordinator.async_request_refresh() def updateTapo(self, camData): - LOGGER.warn(camData) if not camData: self._attr_state = "unavailable" else: - self._attr_current_option = camData["day_night_mode"] + self._attr_current_option = getNightModeName(camData[self.currentValueKey]) self._attr_state = self._attr_current_option async def async_select_option(self, option: str) -> None: + LOGGER.debug("Calling " + self.method.__name__ + " with " + option + "...") result = await self._hass.async_add_executor_job( - self._controller.setDayNightMode, option + self.method, getNightModeValue(option) ) if "error_code" not in result or result["error_code"] == 0: self._attr_state = option diff --git a/custom_components/tapo_control/utils.py b/custom_components/tapo_control/utils.py index 7a06a85..20d32c5 100644 --- a/custom_components/tapo_control/utils.py +++ b/custom_components/tapo_control/utils.py @@ -660,6 +660,30 @@ def getDataForController(hass, entry, controller): return childDevice +def getNightModeMap(): + return { + "inf_night_vision": "Infrared Mode", + "wtl_night_vision": "Full Color Mode", + "md_night_vision": "Smart Mode", + "dbl_night_vision": "Doorbell Mode", + } + + +def getNightModeName(value: str): + nightModeMap = getNightModeMap() + if value in nightModeMap: + return nightModeMap[value] + return value + + +def getNightModeValue(value: str): + night_mode_map = getNightModeMap() + for key, val in night_mode_map.items(): + if val == value: + return key + return value + + async def getCamData(hass, controller): LOGGER.debug("getCamData") data = await hass.async_add_executor_job(controller.getMost) @@ -926,44 +950,35 @@ async def getCamData(hass, controller): camData["light_frequency_mode"] = light_frequency_mode try: - day_night_mode = data["getLdc"][0]["image"]["common"]["inf_type"] + night_vision_mode = data["getNightVisionModeConfig"][0]["image"]["switch"][ + "night_vision_mode" + ] except Exception: - day_night_mode = None + night_vision_mode = None + camData["night_vision_mode"] = night_vision_mode - if day_night_mode is None: - try: - day_night_mode = data["getLightFrequencyInfo"][0]["image"]["common"][ - "inf_type" - ] - except Exception: - day_night_mode = None + try: + night_vision_capability = data["getNightVisionCapability"][0][ + "image_capability" + ]["supplement_lamp"]["night_vision_mode_range"] + except Exception: + night_vision_capability = None + camData["night_vision_capability"] = night_vision_capability + + try: + night_vision_mode_switching = data["getLdc"][0]["image"]["common"]["inf_type"] + except Exception: + night_vision_mode_switching = None + camData["night_vision_mode_switching"] = night_vision_mode_switching - if day_night_mode is None: + if night_vision_mode_switching is None: try: - if ( - data["getNightVisionModeConfig"][0]["image"]["switch"][ - "night_vision_mode" - ] - == "inf_night_vision" - ): - day_night_mode = "on" - elif ( - data["getNightVisionModeConfig"][0]["image"]["switch"][ - "night_vision_mode" - ] - == "wtl_night_vision" - ): - day_night_mode = "off" - elif ( - data["getNightVisionModeConfig"][0]["image"]["switch"][ - "night_vision_mode" - ] - == "md_night_vision" - ): - day_night_mode = "auto" + night_vision_mode_switching = data["getLightFrequencyInfo"][0]["image"][ + "common" + ]["inf_type"] except Exception: - day_night_mode = None - camData["day_night_mode"] = day_night_mode + night_vision_mode_switching = None + camData["night_vision_mode_switching"] = night_vision_mode_switching try: force_white_lamp_state = data["getLdc"][0]["image"]["switch"]["force_wtl_state"] From 4741574a08679d3178741e08787b6dacf2a7ffe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Wed, 31 Jul 2024 17:48:44 +0200 Subject: [PATCH 6/7] Add: Map for Scheduled mode night vision --- custom_components/tapo_control/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/tapo_control/utils.py b/custom_components/tapo_control/utils.py index 20d32c5..77e0383 100644 --- a/custom_components/tapo_control/utils.py +++ b/custom_components/tapo_control/utils.py @@ -666,6 +666,7 @@ def getNightModeMap(): "wtl_night_vision": "Full Color Mode", "md_night_vision": "Smart Mode", "dbl_night_vision": "Doorbell Mode", + "shed_night_vision": "Scheduled mode", } From 4d09246201880bfd4fdf0e75f66f5e45feb99b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Wed, 31 Jul 2024 17:52:09 +0200 Subject: [PATCH 7/7] Update: Bump version --- custom_components/tapo_control/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/tapo_control/manifest.json b/custom_components/tapo_control/manifest.json index 2f7b972..65d59c2 100644 --- a/custom_components/tapo_control/manifest.json +++ b/custom_components/tapo_control/manifest.json @@ -6,7 +6,7 @@ "codeowners": [ "@JurajNyiri" ], - "version": "5.5.4", + "version": "5.6.0", "requirements": [ "pytapo==3.3.30" ],