Skip to content

Commit

Permalink
Merge pull request #1319 from custom-components/xiaomi_ptx
Browse files Browse the repository at this point in the history
Add PTX wireless switch
  • Loading branch information
Ernst79 authored Feb 26, 2024
2 parents ca10221 + 6ac5df6 commit 3120c4e
Show file tree
Hide file tree
Showing 42 changed files with 108 additions and 2 deletions.
39 changes: 38 additions & 1 deletion custom_components/ble_monitor/ble_parser/xiaomi.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
0x18E3: "ZX1",
0x11C2: "SV40",
0x3F0F: "RS1BB",
0x38BB: "PTX",
}

# Structured objects for data conversions
Expand Down Expand Up @@ -769,6 +770,30 @@ def obj4a08(xobj):
return {"motion": 1, "motion timer": 1, "illuminance": illu}


def obj4a0c(xobj):
"""Single click PTX"""
return {
"one btn switch": "toggle",
"button switch": "single press",
}


def obj4a0d(xobj):
"""Double click PTX"""
return {
"one btn switch": "toggle",
"button switch": "double press",
}


def obj4a0e(xobj):
"""Long click PTX"""
return {
"one btn switch": "toggle",
"button switch": "long press",
}


def obj4a0f(xobj):
"""Door/window broken open"""
dev_forced = xobj[0]
Expand Down Expand Up @@ -852,6 +877,12 @@ def obj4c14(xobj):
return {"mode": mode}


def obj4e01(xobj):
"""Low Battery"""
low_batt = xobj[0]
return {"low battery": low_batt}


def obj4e0c(xobj, device_type):
"""Click"""
if device_type == "XMWXKG01YL":
Expand Down Expand Up @@ -1065,6 +1096,9 @@ def obj5a16(xobj):
0x4818: obj4818,
0x4a01: obj4a01,
0x4a08: obj4a08,
0x4a0c: obj4a0c,
0x4a0d: obj4a0d,
0x4a0e: obj4a0e,
0x4a0f: obj4a0f,
0x4a12: obj4a12,
0x4a13: obj4a13,
Expand All @@ -1074,6 +1108,7 @@ def obj5a16(xobj):
0x4c03: obj4c03,
0x4c08: obj4c08,
0x4c14: obj4c14,
0x4e01: obj4e01,
0x4e0c: obj4e0c,
0x4e0d: obj4e0d,
0x4e0e: obj4e0e,
Expand Down Expand Up @@ -1267,7 +1302,9 @@ def parse_xiaomi(self, data: bytes, mac: str):
_LOGGER.debug("Invalid payload data length, payload: %s", payload.hex())
break
dobject = payload[payload_start + 3:next_start]
if dobject and obj_length != 0 or hex(obj_typecode) in ["0x4e0c", "0x4e0d", "0x4e0e"]:
if dobject and obj_length != 0 or hex(obj_typecode) in [
"0x4a0c", "0x4a0d", "0x4a0e", "0x4e0c", "0x4e0d", "0x4e0e"
]:
resfunc = xiaomi_dataobject_dict.get(obj_typecode, None)
if resfunc:
if hex(obj_typecode) in ["0x8", "0x100e", "0x1001", "0xf", "0xb", "0x4e0c", "0x4e0d", "0x4e0e"]:
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 @@ -1674,6 +1674,7 @@ class BLEMonitorBinarySensorEntityDescription(
'HS1BB(MI)' : [["illuminance", "battery", "rssi"], [], ["motion"]],
'XMWXKG01YL' : [["rssi"], ["two btn switch left", "two btn switch right"], []],
'XMWXKG01LM' : [["battery", "rssi"], ["one btn switch"], []],
'PTX' : [["battery", "rssi"], ["one btn switch"], []],
'YLAI003' : [["rssi", "battery"], ["button"], []],
'YLYK01YL' : [["rssi"], ["remote"], ["remote single press", "remote long press"]],
'YLYK01YL-FANCL' : [["rssi"], ["fan remote"], []],
Expand Down Expand Up @@ -1812,6 +1813,7 @@ class BLEMonitorBinarySensorEntityDescription(
'HS1BB(MI)' : 'Linptech',
'XMWXKG01YL' : 'Xiaomi',
'XMWXKG01LM' : 'Xiaomi',
'PTX' : 'Xiaomi',
'SV40' : 'Lockin',
'SU001-T' : 'Petoneer',
'ATC' : 'ATC',
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.9.2"
"version": "12.9.3"
}
27 changes: 27 additions & 0 deletions custom_components/ble_monitor/test/test_xiaomi_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1037,3 +1037,30 @@ def test_XMWXKG01LM_long_click(self):
assert sensor_msg["one btn switch"] == "toggle"
assert sensor_msg["button switch"] == "long press"
assert sensor_msg["rssi"] == -64

def test_Xiaomi_PTX(self):
"""Test Xiaomi parser for PTX BLE wireless switch."""
self.aeskeys = {}
data_string = "043E2802010000adb9a538c1a41c020106181695fe5859bb3804adb9a538c1a4dc10b50400002c122fb6CC"
data = bytes(bytearray.fromhex(data_string))

aeskey = "a74510b40386d35ae6227a7451efc76e"

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"] == "PTX"
assert sensor_msg["mac"] == "A4C138A5B9AD"
assert sensor_msg["packet"] == 4
assert sensor_msg["data"]
assert sensor_msg["one btn switch"] == "toggle"
assert sensor_msg["button switch"] == "single press"
assert sensor_msg["rssi"] == -52
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions docs/_devices/Xiaomi_PTX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
manufacturer: Xiaomi
name: BLE wireless switch
model: PTX
image: PTX.png
physical_description:
broadcasted_properties:
- one btn switch
- battery
- rssi
broadcasted_property_notes:
- property: one btn switch
note: returns 'single press', 'double press' or 'long press'
broadcast_rate:
active_scan: false
encryption_key: Yes
custom_firmware: false
notes:
- The switch sensor state will return to `no press` after the time set with the [reset_timer](configuration_params#reset_timer) option. It is advised to change the reset time to 1 second (default = 35 seconds).
---
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions docs/_devices/Xiaomi_XMWXKG01LM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
manufacturer: Xiaomi
name: Mijia wireless switch
model: XMWXKG01LM
image: XMWXKG01LM.png
physical_description: round switch
broadcasted_properties:
- one btn switch
- battery
- rssi
broadcasted_property_notes:
- property: one btn switch
note: returns 'single press', 'double press' or 'long press'
broadcast_rate:
active_scan: false
encryption_key: Yes
custom_firmware: false
notes:
- The switch sensor state will return to `no press` after the time set with the [reset_timer](configuration_params#reset_timer) option. It is advised to change the reset time to 1 second (default = 35 seconds).
---
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added docs/assets/images/PTX.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 3120c4e

Please sign in to comment.