Skip to content

Commit 888c727

Browse files
authored
Add additional humidity methods (#149)
1 parent 41d9beb commit 888c727

File tree

7 files changed

+69
-24
lines changed

7 files changed

+69
-24
lines changed

switchbot/devices/bot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ async def turn_on(self) -> bool:
3838
"""Turn device on."""
3939
result = await self._send_command(ON_KEY)
4040
ret = self._check_command_result(result, 0, {1, 5})
41-
self._override_adv_data = {"isOn": True}
41+
self._override_state({"isOn": True})
4242
_LOGGER.debug(
4343
"%s: Turn on result: %s -> %s",
4444
self.name,
@@ -52,7 +52,7 @@ async def turn_off(self) -> bool:
5252
"""Turn device off."""
5353
result = await self._send_command(OFF_KEY)
5454
ret = self._check_command_result(result, 0, {1, 5})
55-
self._override_adv_data = {"isOn": False}
55+
self._override_state({"isOn": False})
5656
_LOGGER.debug(
5757
"%s: Turn off result: %s -> %s",
5858
self.name,

switchbot/devices/bulb.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@ def _update_state(self, result: bytes | None) -> None:
8484
self._state["g"] = result[4]
8585
self._state["b"] = result[5]
8686
self._state["cw"] = int(result[6:8].hex(), 16)
87-
self._override_adv_data = {
88-
"isOn": result[1] == 0x80,
89-
"color_mode": result[10],
90-
}
87+
self._override_state(
88+
{
89+
"isOn": result[1] == 0x80,
90+
"color_mode": result[10],
91+
}
92+
)
9193
_LOGGER.debug("%s: update state: %s = %s", self.name, result.hex(), self._state)
9294
self._fire_callbacks()

switchbot/devices/ceiling_light.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ async def turn_on(self) -> bool:
3434
"""Turn device on."""
3535
result = await self._send_command(CEILING_LIGHT_ON_KEY)
3636
ret = self._check_command_result(result, 0, {0x01})
37-
self._override_adv_data = {"isOn": True}
37+
self._override_state({"isOn": True})
3838
self._fire_callbacks()
3939
return ret
4040

4141
async def turn_off(self) -> bool:
4242
"""Turn device off."""
4343
result = await self._send_command(CEILING_LIGHT_OFF_KEY)
4444
ret = self._check_command_result(result, 0, {0x01})
45-
self._override_adv_data = {"isOn": False}
45+
self._override_state({"isOn": False})
4646
self._fire_callbacks()
4747
return ret
4848

@@ -51,7 +51,7 @@ async def set_brightness(self, brightness: int) -> bool:
5151
assert 0 <= brightness <= 100, "Brightness must be between 0 and 100"
5252
result = await self._send_command(f"{BRIGHTNESS_KEY}{brightness:02X}0FA1")
5353
ret = self._check_command_result(result, 0, {0x01})
54-
self._override_adv_data = {"brightness": brightness, "isOn": True}
54+
self._override_state({"brightness": brightness, "isOn": True})
5555
self._fire_callbacks()
5656
return ret
5757

@@ -64,7 +64,7 @@ async def set_color_temp(self, brightness: int, color_temp: int) -> bool:
6464
)
6565
ret = self._check_command_result(result, 0, {0x01})
6666
self._state["cw"] = color_temp
67-
self._override_adv_data = {"brightness": brightness, "isOn": True}
67+
self._override_state({"brightness": brightness, "isOn": True})
6868
self._fire_callbacks()
6969
return ret
7070

switchbot/devices/device.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,12 @@ def get_address(self) -> str:
379379
"""Return address of device."""
380380
return self._device.address
381381

382+
def _override_state(self, state: dict[str, Any]) -> None:
383+
"""Override device state."""
384+
if self._override_adv_data is None:
385+
self._override_adv_data = {}
386+
self._override_adv_data.update(state)
387+
382388
def _get_adv_value(self, key: str) -> Any:
383389
"""Return value from advertisement data."""
384390
if self._override_adv_data and key in self._override_adv_data:

switchbot/devices/humidifier.py

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,68 @@ async def update(self, interface: int | None = None) -> None:
2424
"""Update state of device."""
2525
await self.get_device_data(retry=self._retry_count, interface=interface)
2626

27+
def _generate_command(
28+
self, on: bool | None = None, level: int | None = None
29+
) -> str:
30+
"""Generate command."""
31+
if level is None:
32+
level = self.get_level()
33+
if on is None:
34+
on = self.is_on()
35+
on_hex = "01" if on else "00"
36+
return f"{HUMIDIFIER_COMMAND}01{on_hex}{level:02X}FFFFFFFF"
37+
2738
async def turn_on(self) -> bool:
2839
"""Turn device on."""
29-
result = await self._send_command(HUMIDIFIER_ON_KEY)
40+
result = await self._send_command(self._generate_command(on=True))
3041
ret = self._check_command_result(result, 0, {0x01})
31-
self._override_adv_data = {"isOn": True}
42+
self._override_state({"isOn": True})
3243
self._fire_callbacks()
3344
return ret
3445

3546
async def turn_off(self) -> bool:
3647
"""Turn device off."""
37-
result = await self._send_command(HUMIDIFIER_OFF_KEY)
48+
result = await self._send_command(self._generate_command(on=False))
3849
ret = self._check_command_result(result, 0, {0x01})
39-
self._override_adv_data = {"isOn": False}
50+
self._override_state({"isOn": False})
4051
self._fire_callbacks()
4152
return ret
4253

4354
async def set_level(self, level: int) -> bool:
4455
"""Set level."""
4556
assert 1 <= level <= 100, "Level must be between 1 and 100"
46-
result = await self._send_command(
47-
f"{HUMIDIFIER_COMMAND}0101{level:02X}FFFFFFFF"
48-
)
57+
await self._set_level(level)
58+
59+
async def _set_level(self, level: int) -> bool:
60+
"""Set level."""
61+
result = await self._send_command(self._generate_command(level=level))
4962
ret = self._check_command_result(result, 0, {0x01})
50-
self._override_adv_data = {"isOn": False, "level": level}
63+
self._override_state({"level": level})
5164
self._fire_callbacks()
5265
return ret
5366

67+
async def async_set_auto(self) -> bool:
68+
"""Set auto mode."""
69+
await self._set_level(128)
70+
71+
async def async_set_manual(self) -> bool:
72+
"""Set manual mode."""
73+
await self._set_level(50)
74+
75+
def is_auto(self) -> bool:
76+
"""Return auto state from cache."""
77+
return self.get_level() == 128
78+
79+
def get_level(self) -> int | None:
80+
"""Return level state from cache."""
81+
return self._get_adv_value("level")
82+
5483
def is_on(self) -> bool | None:
5584
"""Return switch state from cache."""
5685
return self._get_adv_value("isOn")
86+
87+
def get_target_humidity(self) -> int | None:
88+
"""Return target humidity from cache."""
89+
level = self.get_level()
90+
is_auto = level == 128
91+
return None if is_auto else level

switchbot/devices/light_strip.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ def _update_state(self, result: bytes | None) -> None:
7474
self._state["r"] = result[3]
7575
self._state["g"] = result[4]
7676
self._state["b"] = result[5]
77-
self._override_adv_data = {
78-
"isOn": result[1] == 0x80,
79-
"color_mode": result[10],
80-
}
77+
self._override_state(
78+
{
79+
"isOn": result[1] == 0x80,
80+
"color_mode": result[10],
81+
}
82+
)
8183
_LOGGER.debug("%s: update state: %s = %s", self.name, result.hex(), self._state)
8284
self._fire_callbacks()

switchbot/devices/plug.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ async def turn_on(self) -> bool:
1919
"""Turn device on."""
2020
result = await self._send_command(PLUG_ON_KEY)
2121
ret = self._check_command_result(result, 1, {0x80})
22-
self._override_adv_data = {"isOn": True}
22+
self._override_state({"isOn": True})
2323
self._fire_callbacks()
2424
return ret
2525

2626
async def turn_off(self) -> bool:
2727
"""Turn device off."""
2828
result = await self._send_command(PLUG_OFF_KEY)
2929
ret = self._check_command_result(result, 1, {0x80})
30-
self._override_adv_data = {"isOn": False}
30+
self._override_state({"isOn": False})
3131
self._fire_callbacks()
3232
return ret
3333

0 commit comments

Comments
 (0)