Bladeren bron

Add additional humidity methods (#149)

J. Nick Koston 1 jaar geleden
bovenliggende
commit
888c727f02

+ 2 - 2
switchbot/devices/bot.py

@@ -38,7 +38,7 @@ class Switchbot(SwitchbotDeviceOverrideStateDuringConnection):
         """Turn device on."""
         result = await self._send_command(ON_KEY)
         ret = self._check_command_result(result, 0, {1, 5})
-        self._override_adv_data = {"isOn": True}
+        self._override_state({"isOn": True})
         _LOGGER.debug(
             "%s: Turn on result: %s -> %s",
             self.name,
@@ -52,7 +52,7 @@ class Switchbot(SwitchbotDeviceOverrideStateDuringConnection):
         """Turn device off."""
         result = await self._send_command(OFF_KEY)
         ret = self._check_command_result(result, 0, {1, 5})
-        self._override_adv_data = {"isOn": False}
+        self._override_state({"isOn": False})
         _LOGGER.debug(
             "%s: Turn off result: %s -> %s",
             self.name,

+ 6 - 4
switchbot/devices/bulb.py

@@ -84,9 +84,11 @@ class SwitchbotBulb(SwitchbotSequenceBaseLight):
         self._state["g"] = result[4]
         self._state["b"] = result[5]
         self._state["cw"] = int(result[6:8].hex(), 16)
-        self._override_adv_data = {
-            "isOn": result[1] == 0x80,
-            "color_mode": result[10],
-        }
+        self._override_state(
+            {
+                "isOn": result[1] == 0x80,
+                "color_mode": result[10],
+            }
+        )
         _LOGGER.debug("%s: update state: %s = %s", self.name, result.hex(), self._state)
         self._fire_callbacks()

+ 4 - 4
switchbot/devices/ceiling_light.py

@@ -34,7 +34,7 @@ class SwitchbotCeilingLight(SwitchbotBaseLight):
         """Turn device on."""
         result = await self._send_command(CEILING_LIGHT_ON_KEY)
         ret = self._check_command_result(result, 0, {0x01})
-        self._override_adv_data = {"isOn": True}
+        self._override_state({"isOn": True})
         self._fire_callbacks()
         return ret
 
@@ -42,7 +42,7 @@ class SwitchbotCeilingLight(SwitchbotBaseLight):
         """Turn device off."""
         result = await self._send_command(CEILING_LIGHT_OFF_KEY)
         ret = self._check_command_result(result, 0, {0x01})
-        self._override_adv_data = {"isOn": False}
+        self._override_state({"isOn": False})
         self._fire_callbacks()
         return ret
 
@@ -51,7 +51,7 @@ class SwitchbotCeilingLight(SwitchbotBaseLight):
         assert 0 <= brightness <= 100, "Brightness must be between 0 and 100"
         result = await self._send_command(f"{BRIGHTNESS_KEY}{brightness:02X}0FA1")
         ret = self._check_command_result(result, 0, {0x01})
-        self._override_adv_data = {"brightness": brightness, "isOn": True}
+        self._override_state({"brightness": brightness, "isOn": True})
         self._fire_callbacks()
         return ret
 
@@ -64,7 +64,7 @@ class SwitchbotCeilingLight(SwitchbotBaseLight):
         )
         ret = self._check_command_result(result, 0, {0x01})
         self._state["cw"] = color_temp
-        self._override_adv_data = {"brightness": brightness, "isOn": True}
+        self._override_state({"brightness": brightness, "isOn": True})
         self._fire_callbacks()
         return ret
 

+ 6 - 0
switchbot/devices/device.py

@@ -379,6 +379,12 @@ class SwitchbotBaseDevice:
         """Return address of device."""
         return self._device.address
 
+    def _override_state(self, state: dict[str, Any]) -> None:
+        """Override device state."""
+        if self._override_adv_data is None:
+            self._override_adv_data = {}
+        self._override_adv_data.update(state)
+
     def _get_adv_value(self, key: str) -> Any:
         """Return value from advertisement data."""
         if self._override_adv_data and key in self._override_adv_data:

+ 43 - 8
switchbot/devices/humidifier.py

@@ -24,33 +24,68 @@ class SwitchbotHumidifier(SwitchbotDevice):
         """Update state of device."""
         await self.get_device_data(retry=self._retry_count, interface=interface)
 
+    def _generate_command(
+        self, on: bool | None = None, level: int | None = None
+    ) -> str:
+        """Generate command."""
+        if level is None:
+            level = self.get_level()
+        if on is None:
+            on = self.is_on()
+        on_hex = "01" if on else "00"
+        return f"{HUMIDIFIER_COMMAND}01{on_hex}{level:02X}FFFFFFFF"
+
     async def turn_on(self) -> bool:
         """Turn device on."""
-        result = await self._send_command(HUMIDIFIER_ON_KEY)
+        result = await self._send_command(self._generate_command(on=True))
         ret = self._check_command_result(result, 0, {0x01})
-        self._override_adv_data = {"isOn": True}
+        self._override_state({"isOn": True})
         self._fire_callbacks()
         return ret
 
     async def turn_off(self) -> bool:
         """Turn device off."""
-        result = await self._send_command(HUMIDIFIER_OFF_KEY)
+        result = await self._send_command(self._generate_command(on=False))
         ret = self._check_command_result(result, 0, {0x01})
-        self._override_adv_data = {"isOn": False}
+        self._override_state({"isOn": False})
         self._fire_callbacks()
         return ret
 
     async def set_level(self, level: int) -> bool:
         """Set level."""
         assert 1 <= level <= 100, "Level must be between 1 and 100"
-        result = await self._send_command(
-            f"{HUMIDIFIER_COMMAND}0101{level:02X}FFFFFFFF"
-        )
+        await self._set_level(level)
+
+    async def _set_level(self, level: int) -> bool:
+        """Set level."""
+        result = await self._send_command(self._generate_command(level=level))
         ret = self._check_command_result(result, 0, {0x01})
-        self._override_adv_data = {"isOn": False, "level": level}
+        self._override_state({"level": level})
         self._fire_callbacks()
         return ret
 
+    async def async_set_auto(self) -> bool:
+        """Set auto mode."""
+        await self._set_level(128)
+
+    async def async_set_manual(self) -> bool:
+        """Set manual mode."""
+        await self._set_level(50)
+
+    def is_auto(self) -> bool:
+        """Return auto state from cache."""
+        return self.get_level() == 128
+
+    def get_level(self) -> int | None:
+        """Return level state from cache."""
+        return self._get_adv_value("level")
+
     def is_on(self) -> bool | None:
         """Return switch state from cache."""
         return self._get_adv_value("isOn")
+
+    def get_target_humidity(self) -> int | None:
+        """Return target humidity from cache."""
+        level = self.get_level()
+        is_auto = level == 128
+        return None if is_auto else level

+ 6 - 4
switchbot/devices/light_strip.py

@@ -74,9 +74,11 @@ class SwitchbotLightStrip(SwitchbotSequenceBaseLight):
         self._state["r"] = result[3]
         self._state["g"] = result[4]
         self._state["b"] = result[5]
-        self._override_adv_data = {
-            "isOn": result[1] == 0x80,
-            "color_mode": result[10],
-        }
+        self._override_state(
+            {
+                "isOn": result[1] == 0x80,
+                "color_mode": result[10],
+            }
+        )
         _LOGGER.debug("%s: update state: %s = %s", self.name, result.hex(), self._state)
         self._fire_callbacks()

+ 2 - 2
switchbot/devices/plug.py

@@ -19,7 +19,7 @@ class SwitchbotPlugMini(SwitchbotDeviceOverrideStateDuringConnection):
         """Turn device on."""
         result = await self._send_command(PLUG_ON_KEY)
         ret = self._check_command_result(result, 1, {0x80})
-        self._override_adv_data = {"isOn": True}
+        self._override_state({"isOn": True})
         self._fire_callbacks()
         return ret
 
@@ -27,7 +27,7 @@ class SwitchbotPlugMini(SwitchbotDeviceOverrideStateDuringConnection):
         """Turn device off."""
         result = await self._send_command(PLUG_OFF_KEY)
         ret = self._check_command_result(result, 1, {0x80})
-        self._override_adv_data = {"isOn": False}
+        self._override_state({"isOn": False})
         self._fire_callbacks()
         return ret