PySwitchbot 2.7.0__py3-none-any.whl → 2.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PySwitchbot
3
- Version: 2.7.0
3
+ Version: 2.8.0
4
4
  Summary: A library to communicate with Switchbot
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -93,10 +93,10 @@ from switchbot.discovery import GetSwitchbotDevices
93
93
  from switchbot.devices import lock
94
94
  from switchbot.const import SwitchbotModel
95
95
 
96
- BLE_MAC="XX:XX:XX:XX:XX:XX" # The MAC of your lock
97
- KEY_ID="XX" # The key-ID of your encryption-key for your lock
98
- ENC_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # The encryption-key with key-ID "XX"
99
- LOCK_MODEL=SwitchbotModel.LOCK_PRO # Your lock model (here we use the Lock-Pro)
96
+ BLE_MAC = "XX:XX:XX:XX:XX:XX" # The MAC of your lock
97
+ KEY_ID = "XX" # The key-ID of your encryption-key for your lock
98
+ ENC_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # The encryption-key with key-ID "XX"
99
+ LOCK_MODEL = SwitchbotModel.LOCK_PRO # Your lock model (here we use the Lock-Pro)
100
100
 
101
101
 
102
102
  async def main():
@@ -117,10 +117,10 @@ from switchbot.discovery import GetSwitchbotDevices
117
117
  from switchbot.devices import lock
118
118
  from switchbot.const import SwitchbotModel
119
119
 
120
- BLE_MAC="XX:XX:XX:XX:XX:XX" # The MAC of your lock
121
- KEY_ID="XX" # The key-ID of your encryption-key for your lock
122
- ENC_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # The encryption-key with key-ID "XX"
123
- LOCK_MODEL=SwitchbotModel.LOCK_PRO # Your lock model (here we use the Lock-Pro)
120
+ BLE_MAC = "XX:XX:XX:XX:XX:XX" # The MAC of your lock
121
+ KEY_ID = "XX" # The key-ID of your encryption-key for your lock
122
+ ENC_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # The encryption-key with key-ID "XX"
123
+ LOCK_MODEL = SwitchbotModel.LOCK_PRO # Your lock model (here we use the Lock-Pro)
124
124
 
125
125
 
126
126
  async def main():
@@ -1,5 +1,5 @@
1
1
  switchbot/__init__.py,sha256=iItr_zGA3ARTGbneIjVDyW9fi6EviVFqN2yHyvMI5wA,4332
2
- switchbot/__version__.py,sha256=EtKWW0Hnl5oWglRNH0HZigvcDT2FEs58ek8buJdwW1E,22
2
+ switchbot/__version__.py,sha256=z6im3C9Qb6qiQIpaJdE4f9WQiCnFGSUQnQXDPw_dvDg,22
3
3
  switchbot/adv_parser.py,sha256=O5cVtZq4IRozO7X76hIrrQCGPna78Z7YHHkbROyHWcI,35353
4
4
  switchbot/adv_parsers/__init__.py,sha256=d39GEAICA1RrQiLy1ks49x0d9a-A_yKn9Awkj5za8Uk,46
5
5
  switchbot/adv_parsers/_sensor_th.py,sha256=ze182l3_YFHJJv98_vq6qB2twlUTExkxoC1sLZL3TLs,1199
@@ -51,7 +51,7 @@ switchbot/devices/base_light.py,sha256=WWJJdRHfvoSYMRHDSv_RCmo5D6hYoZRxQVYfsOXZ7
51
51
  switchbot/devices/blind_tilt.py,sha256=tY0JoZhyqU_6PlhjtnIaEeIG3Z-JdZKJ5Jwg_5b6xSQ,5761
52
52
  switchbot/devices/bot.py,sha256=Co2IiQa2si0WPs3HFize2CPpj5GVbMT570vMP5YWpaQ,4121
53
53
  switchbot/devices/bulb.py,sha256=ISxXck8JsBlFojLB8M5Wfip_z4o6_-VvyFbBvqK6_Bg,2313
54
- switchbot/devices/ceiling_light.py,sha256=DypuzNHZ2TLI-xg0BauTHo9yl8LNujXc17UeW1K-oqE,2652
54
+ switchbot/devices/ceiling_light.py,sha256=7gxgsZz5ku6Bx8jfHSBkPcydjgagwGEuPvl5N-cMO6M,4600
55
55
  switchbot/devices/contact.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
56
56
  switchbot/devices/curtain.py,sha256=p3qcPWHaSA5ewPONl811hL7swFRca37Omb2LKYoAxgo,7086
57
57
  switchbot/devices/device.py,sha256=MmbnWHxlWGTHZmhnxFyQQXwe_Fo6Ce7lu36lA06o0UU,49713
@@ -76,7 +76,7 @@ switchbot/enum.py,sha256=0IfWypBw2oe9lWgdRkrD_1FqqeHpakCxtwlSaUlmcPg,125
76
76
  switchbot/helpers.py,sha256=DJLvYZ4Dq0dkiGMOzfR--nSTM_8jE9QtB7t570PuGSU,2091
77
77
  switchbot/models.py,sha256=xibQOVGHC60FWWc54N6BW46vxFuJUjj6tK1Qw0_eTbI,372
78
78
  switchbot/utils.py,sha256=glU1SDBeoXuu9K46nSGvg1YVWGNAGC0bo13tJ-ccDNU,724
79
- pyswitchbot-2.7.0.dist-info/METADATA,sha256=P_NtAvbLh_laeMkE4m6MkiPq7tjt0EDRE9vR1DP5WfM,5794
80
- pyswitchbot-2.7.0.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
81
- pyswitchbot-2.7.0.dist-info/licenses/LICENSE,sha256=_hdUCmoRDzki4fYDJfn-5KpG7-7p6YJ6IsbMfrTXN6Y,1078
82
- pyswitchbot-2.7.0.dist-info/RECORD,,
79
+ pyswitchbot-2.8.0.dist-info/METADATA,sha256=lxm-a4Q9rETewBYZtbawGv0VsRwMMEI5aUccaqBE8e8,5818
80
+ pyswitchbot-2.8.0.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
81
+ pyswitchbot-2.8.0.dist-info/licenses/LICENSE,sha256=_hdUCmoRDzki4fYDJfn-5KpG7-7p6YJ6IsbMfrTXN6Y,1078
82
+ pyswitchbot-2.8.0.dist-info/RECORD,,
switchbot/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.7.0"
1
+ __version__ = "2.8.0"
@@ -27,6 +27,7 @@ class SwitchbotCeilingLight(SwitchbotSequenceBaseLight):
27
27
  _turn_off_command = f"{CEILING_LIGHT_CONTROL_HEADER}02FF01FFFF"
28
28
  _set_brightness_command = f"{CEILING_LIGHT_CONTROL_HEADER}01FF01{{}}"
29
29
  _set_color_temp_command = f"{CEILING_LIGHT_CONTROL_HEADER}01FF01{{}}"
30
+ _set_night_light_command = f"{CEILING_LIGHT_CONTROL_HEADER}01{{}}01{{}}"
30
31
  _get_basic_info_command = ["5702", "570f5581"]
31
32
 
32
33
  @property
@@ -37,9 +38,8 @@ class SwitchbotCeilingLight(SwitchbotSequenceBaseLight):
37
38
  @property
38
39
  def color_mode(self) -> ColorMode:
39
40
  """Return the current color mode."""
40
- device_mode = CeilingLightColorMode(
41
- value if (value := self._get_adv_value("color_mode")) is not None else 10
42
- )
41
+ value = self._state.get("color_mode", self._get_adv_value("color_mode"))
42
+ device_mode = CeilingLightColorMode(value if value is not None else 10)
43
43
  return _CEILING_LIGHT_COLOR_MODE_MAP.get(device_mode, ColorMode.OFF)
44
44
 
45
45
  @update_after_operation
@@ -52,6 +52,40 @@ class SwitchbotCeilingLight(SwitchbotSequenceBaseLight):
52
52
  result = await self._send_command(self._set_brightness_command.format(hex_data))
53
53
  return self._check_command_result(result, 0, {1})
54
54
 
55
+ @update_after_operation
56
+ async def set_night_light(self, is_on: bool, brightness: int | None = None) -> bool:
57
+ """
58
+ Toggle night light color mode on or off.
59
+
60
+ Powers the light on and, unless `brightness` is given, resets
61
+ brightness to 20% (night) or 100% (otherwise) — mirroring the
62
+ official app's night light toggle.
63
+ """
64
+ color_mode = (
65
+ CeilingLightColorMode.NIGHT if is_on else CeilingLightColorMode.COLOR_TEMP
66
+ )
67
+ hex_mode = f"{color_mode.value:02X}"
68
+ if brightness is None:
69
+ # The app's night light toggle always pairs NIGHT with 20%
70
+ # brightness and COLOR_TEMP with 100%, carrying over the
71
+ # last-set color temp.
72
+ brightness = 20 if is_on else 100
73
+ else:
74
+ self._validate_brightness(brightness)
75
+ color_temp = self._state.get("cw", DEFAULT_COLOR_TEMP)
76
+ hex_data = f"{brightness:02X}{color_temp:04X}"
77
+ result = await self._send_command(
78
+ self._set_night_light_command.format(hex_mode, hex_data)
79
+ )
80
+ return self._check_command_result(result, 0, {1})
81
+
82
+ def is_night_light_on(self) -> bool | None:
83
+ """Return the cached night light color mode state."""
84
+ value = self._state.get("color_mode")
85
+ if value is None:
86
+ return None
87
+ return value == CeilingLightColorMode.NIGHT.value
88
+
55
89
  async def get_basic_info(self) -> dict[str, Any] | None:
56
90
  """Get device basic settings."""
57
91
  if not (
@@ -60,11 +94,19 @@ class SwitchbotCeilingLight(SwitchbotSequenceBaseLight):
60
94
  return None
61
95
  _version_info, _data = res
62
96
 
63
- self._state["cw"] = int.from_bytes(_data[3:5], "big")
97
+ color_temp = int.from_bytes(_data[3:5], "big")
98
+ if self.min_temp <= color_temp <= self.max_temp:
99
+ self._state["cw"] = color_temp
100
+ else:
101
+ self._state.setdefault("cw", DEFAULT_COLOR_TEMP)
102
+ # Cached in self._state (not the adv-data merge) because the
103
+ # advertisement parser hardcodes color_mode, which would otherwise
104
+ # clobber this value on the next advertisement.
105
+ self._state["color_mode"] = (_data[1] & 0b01000000) >> 6
64
106
 
65
107
  return {
66
108
  "isOn": bool(_data[1] & 0b10000000),
67
- "color_mode": (_data[1] & 0b01000000) >> 6,
109
+ "color_mode": self._state["color_mode"],
68
110
  "brightness": _data[2] & 0b01111111,
69
111
  "cw": self._state["cw"],
70
112
  "firmware": _version_info[2] / 10.0,