|
26 | 26 | COMMAND_GET_CK_IV = f"{COMMAND_HEADER}0f2103" |
27 | 27 | COMMAND_LOCK_INFO = f"{COMMAND_HEADER}0f4f8101" |
28 | 28 | COMMAND_UNLOCK = f"{COMMAND_HEADER}0f4e01011080" |
| 29 | +COMMAND_UNLOCK_WITHOUT_UNLATCH = f"{COMMAND_HEADER}0f4e010110a0" |
29 | 30 | COMMAND_LOCK = f"{COMMAND_HEADER}0f4e01011000" |
30 | 31 | COMMAND_ENABLE_NOTIFICATIONS = f"{COMMAND_HEADER}0e01001e00008101" |
31 | 32 | COMMAND_DISABLE_NOTIFICATIONS = f"{COMMAND_HEADER}0e00" |
@@ -164,11 +165,17 @@ async def lock(self) -> bool: |
164 | 165 | ) |
165 | 166 |
|
166 | 167 | async def unlock(self) -> bool: |
167 | | - """Send unlock command.""" |
| 168 | + """Send unlock command. If unlatch feature is enabled in EU firmware, also unlatches door""" |
168 | 169 | return await self._lock_unlock( |
169 | 170 | COMMAND_UNLOCK, {LockStatus.UNLOCKED, LockStatus.UNLOCKING} |
170 | 171 | ) |
171 | 172 |
|
| 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 | + |
172 | 179 | def _parse_basic_data(self, basic_data: bytes) -> dict[str, Any]: |
173 | 180 | """Parse basic data from lock.""" |
174 | 181 | return { |
@@ -239,6 +246,10 @@ def is_auto_lock_paused(self) -> bool: |
239 | 246 | """Return True if auto lock is paused.""" |
240 | 247 | return self._get_adv_value("auto_lock_paused") |
241 | 248 |
|
| 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 | + |
242 | 253 | async def _get_lock_info(self) -> bytes | None: |
243 | 254 | """Return lock info of device.""" |
244 | 255 | _data = await self._send_command(key=COMMAND_LOCK_INFO, retry=self._retry_count) |
|
0 commit comments