Skip to content

Commit

Permalink
Merge pull request #1273 from custom-components/SV40
Browse files Browse the repository at this point in the history
Add Lockin Smart Lock SV40
  • Loading branch information
Ernst79 authored Dec 16, 2023
2 parents 66483f4 + 3d70a47 commit bb105a8
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 1 deletion.
1 change: 1 addition & 0 deletions custom_components/ble_monitor/ble_parser/xiaomi.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
0x0DE7: "SU001-T",
0x20DB: "MJZNZ018H",
0x18E3: "ZX1",
0x11C2: "SV40",
}

# Structured objects for data conversions
Expand Down
2 changes: 2 additions & 0 deletions custom_components/ble_monitor/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,7 @@ class BLEMonitorBinarySensorEntityDescription(
'T700i' : [["consumable", "score", "battery", "rssi"], [], ["toothbrush"]],
'ZNMS16LM' : [["battery", "rssi"], [], ["lock", "door", "fingerprint", "armed away"]],
'ZNMS17LM' : [["battery", "rssi"], [], ["lock", "door", "fingerprint", "antilock", "childlock", "armed away"]],
'SV40' : [["battery", "rssi"], [], ["lock", "door", "fingerprint", "antilock", "childlock", "armed away"]],
'MJZNMSQ01YD' : [["battery", "rssi"], [], ["lock", "fingerprint"]],
'MJWSD05MMC' : [["temperature", "humidity", "battery", "rssi"], [], []],
'XMZNMST02YD' : [["battery", "rssi"], [], ["lock", "door", "fingerprint"]],
Expand Down Expand Up @@ -1749,6 +1750,7 @@ class BLEMonitorBinarySensorEntityDescription(
'HS1BB(MI)' : 'Linptech',
'XMWXKG01YL' : 'Xiaomi',
'XMWXKG01LM' : 'Xiaomi',
'SV40' : 'Lockin',
'SU001-T' : 'Petoneer',
'ATC' : 'ATC',
'Mi Scale V1' : 'Xiaomi',
Expand Down
2 changes: 1 addition & 1 deletion custom_components/ble_monitor/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"btsocket>=0.2.0",
"pyric>=0.1.6.3"
],
"version": "12.6.5"
"version": "12.7.0"
}
58 changes: 58 additions & 0 deletions custom_components/ble_monitor/test/test_xiaomi_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,64 @@ def test_Xiaomi_ZNMS16LM_lock(self):
assert sensor_msg["key id"] == 2
assert sensor_msg["rssi"] == -87

def test_Xiaomi_SV40_door(self):
"""Test Xiaomi parser for Lockin SV40."""
self.aeskeys = {}
data_string = "043E27020100003d04a3330c981B020106171695fe4855c211144e28703276fccd3d00000080e72280C0"
data = bytes(bytearray.fromhex(data_string))

aeskey = "54d84797cb77f9538b224b305c877d1e"

is_ext_packet = True if data[3] == 0x0D else False
mac = (data[8 if is_ext_packet else 7:14 if is_ext_packet else 13])[::-1]
mac_address = mac.hex()
p_mac = bytes.fromhex(mac_address.replace(":", "").lower())
p_key = bytes.fromhex(aeskey.lower())
self.aeskeys[p_mac] = p_key
# pylint: disable=unused-variable
ble_parser = BleParser(aeskeys=self.aeskeys)
sensor_msg, tracker_msg = ble_parser.parse_raw_data(data)

assert sensor_msg["firmware"] == "Xiaomi (MiBeacon V5 encrypted)"
assert sensor_msg["type"] == "SV40"
assert sensor_msg["mac"] == "980C33A3043D"
assert sensor_msg["packet"] == 20
assert sensor_msg["data"]
assert sensor_msg["door"] == 0
assert sensor_msg["door action"] == "close the door"
assert sensor_msg["rssi"] == -64

def test_Xiaomi_SV40_lock(self):
"""Test Xiaomi parser for Lockin SV40."""
self.aeskeys = {}
data_string = "043E2B020100003d04a3330c981F0201061b1695fe4855c211165068b6fe3c878095c8a5834f000000463221c6C0"
data = bytes(bytearray.fromhex(data_string))

aeskey = "54d84797cb77f9538b224b305c877d1e"

is_ext_packet = True if data[3] == 0x0D else False
mac = (data[8 if is_ext_packet else 7:14 if is_ext_packet else 13])[::-1]
mac_address = mac.hex()
p_mac = bytes.fromhex(mac_address.replace(":", "").lower())
p_key = bytes.fromhex(aeskey.lower())
self.aeskeys[p_mac] = p_key
# pylint: disable=unused-variable
ble_parser = BleParser(aeskeys=self.aeskeys)
sensor_msg, tracker_msg = ble_parser.parse_raw_data(data)

assert sensor_msg["firmware"] == "Xiaomi (MiBeacon V5 encrypted)"
assert sensor_msg["type"] == "SV40"
assert sensor_msg["mac"] == "980C33A3043D"
assert sensor_msg["packet"] == 22
assert sensor_msg["data"]
assert sensor_msg["lock"] == 1
assert sensor_msg["locktype"] == "lock"
assert sensor_msg["action"] == "unlock inside the door"
assert sensor_msg["method"] == "automatic"
assert sensor_msg["error"] is None
assert sensor_msg["key id"] == 0
assert sensor_msg["rssi"] == -64

def test_Xiaomi_YLAI003(self):
"""Test Xiaomi parser for YLAI003."""

Expand Down
77 changes: 77 additions & 0 deletions docs/_devices/Lockin_SV40.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
manufacturer: Lockin
name: Lockin Push-Pull Smart Lock SV40
model: SV40
image: Locking_SV40.png
physical_description:
broadcasted_properties:
- fingerprint
- lock
- battery
- result
- key id
- action
- method
- error
- timestamp
- door
- rssi
broadcasted_property_notes:
- property: fingerprint
note: The fingerprint sensor is `On` if the fingerprint scan was successful, otherwise it is `Off` The fingerprint entity has two extra attributes, `result` and `key id`.
- property: result
note: >
`result` shows the result of the last fingerprint reading and can have the following values:
* match successful
* match failed
* timeout
* low quality (too light, fuzzy)
* insufficient area
* skin is too dry
* skin is too wet
- property: key id
note: >
`key id` is an id number. For the fingerprint sensor, it can also be `administrator` or `unknown operator`
- property: lock
note: The state of the lock depends on the last `action`. The lock entity has five extra attributes, `action`, `method`, `error` and `key id` and `timestamp`
- property: action
note: >
`action` shows the last change of the lock and can have the following values:
* unlock outside the door
* lock
* turn on anti-lock
* turn off anti-lock
* unlock inside the door
* lock inside the door
* turn on child lock
* turn off child lock
* lock outside the door
* abnormal
- property: method
note: >
`method` shows the last used locking mechanism and can have the following values:
* unlock outside the door
* lock
* bluetooth
* password
* biometrics
* key
* turntable
* nfc
* one-time password
* two-step verification
* Homekit
* coercion
* manual
* automatic
* abnormal
- property: error
note: The error state of the lock
- property: timestamp
note: The timestamp of the latest lock change
broadcast_rate:
active_scan:
encryption_key:
custom_firmware:
notes:
---
Binary file added docs/assets/images/Lockin_SV40.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit bb105a8

Please sign in to comment.