Skip to content

Commit 7a292cb

Browse files
authored
Added support for Night Latch feature of EU firmware version of smart lock (#215)
1 parent 2db1006 commit 7a292cb

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

switchbot/adv_parsers/lock.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ def process_wolock(data: bytes | None, mfr_data: bytes | None) -> dict[str, bool
2727
"unclosed_alarm": bool(mfr_data[8] & 0b00100000),
2828
"unlocked_alarm": bool(mfr_data[8] & 0b00010000),
2929
"auto_lock_paused": bool(mfr_data[8] & 0b00000010),
30+
"night_latch": bool(mfr_data[9] & 0b00000001),
3031
}

switchbot/devices/lock.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
COMMAND_GET_CK_IV = f"{COMMAND_HEADER}0f2103"
2727
COMMAND_LOCK_INFO = f"{COMMAND_HEADER}0f4f8101"
2828
COMMAND_UNLOCK = f"{COMMAND_HEADER}0f4e01011080"
29+
COMMAND_UNLOCK_WITHOUT_UNLATCH = f"{COMMAND_HEADER}0f4e010110a0"
2930
COMMAND_LOCK = f"{COMMAND_HEADER}0f4e01011000"
3031
COMMAND_ENABLE_NOTIFICATIONS = f"{COMMAND_HEADER}0e01001e00008101"
3132
COMMAND_DISABLE_NOTIFICATIONS = f"{COMMAND_HEADER}0e00"
@@ -164,11 +165,17 @@ async def lock(self) -> bool:
164165
)
165166

166167
async def unlock(self) -> bool:
167-
"""Send unlock command."""
168+
"""Send unlock command. If unlatch feature is enabled in EU firmware, also unlatches door"""
168169
return await self._lock_unlock(
169170
COMMAND_UNLOCK, {LockStatus.UNLOCKED, LockStatus.UNLOCKING}
170171
)
171172

173+
async def unlock_without_unlatch(self) -> bool:
174+
"""Send unlock command. This command will not unlatch the door."""
175+
return await self._lock_unlock(
176+
COMMAND_UNLOCK_WITHOUT_UNLATCH, {LockStatus.UNLOCKED, LockStatus.UNLOCKING, LockStatus.NOT_FULLY_LOCKED}
177+
)
178+
172179
def _parse_basic_data(self, basic_data: bytes) -> dict[str, Any]:
173180
"""Parse basic data from lock."""
174181
return {
@@ -239,6 +246,10 @@ def is_auto_lock_paused(self) -> bool:
239246
"""Return True if auto lock is paused."""
240247
return self._get_adv_value("auto_lock_paused")
241248

249+
def is_night_latch_enabled(self) -> bool:
250+
"""Return True if Night Latch is enabled on EU firmware."""
251+
return self._get_adv_value("night_latch")
252+
242253
async def _get_lock_info(self) -> bytes | None:
243254
"""Return lock info of device."""
244255
_data = await self._send_command(key=COMMAND_LOCK_INFO, retry=self._retry_count)

tests/test_adv_parser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,7 @@ def test_parsing_lock_active():
12341234
"calibration": True,
12351235
"door_open": False,
12361236
"double_lock_mode": False,
1237+
"night_latch": False,
12371238
"status": LockStatus.LOCKED,
12381239
"unclosed_alarm": False,
12391240
"unlocked_alarm": False,
@@ -1267,6 +1268,7 @@ def test_parsing_lock_passive():
12671268
"calibration": True,
12681269
"door_open": False,
12691270
"double_lock_mode": False,
1271+
"night_latch": False,
12701272
"status": LockStatus.LOCKED,
12711273
"unclosed_alarm": False,
12721274
"unlocked_alarm": False,

0 commit comments

Comments
 (0)