Skip to content

Commit 7bba65c

Browse files
authored
Merge pull request #1375 from custom-components/linptech
Add Linptech KS1 en KS1BP
2 parents be45311 + a5799af commit 7bba65c

File tree

7 files changed

+254
-1
lines changed

7 files changed

+254
-1
lines changed

custom_components/ble_monitor/ble_parser/xiaomi.py

+140-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
0x38BB: "PTX",
7979
0x3531: "XMPIRO2SXS",
8080
0x3F4C: "PS1BB",
81+
0x3A61: "KS1",
82+
0x3E17: "KS1BP",
8183
}
8284

8385
# Structured objects for data conversions
@@ -700,6 +702,13 @@ def obj3003(xobj):
700702
# The following data objects are device specific. For now only added for
701703
# LYWSD02MMC, XMWSDJ04MMC, MJWSD05MMC, XMWXKG01YL, LINPTECH MS1BB(MI), HS1BB(MI), K9BB
702704
# https://miot-spec.org/miot-spec-v2/instances?status=all
705+
706+
def obj4801(xobj):
707+
"""Temperature"""
708+
(temp,) = struct.unpack("f", xobj)
709+
return {"temperature": temp}
710+
711+
703712
def obj4803(xobj):
704713
"""Battery"""
705714
batt = xobj[0]
@@ -731,6 +740,12 @@ def obj4806(xobj):
731740
return {"moisture detected": wet}
732741

733742

743+
def obj4808(xobj):
744+
"""Humidity"""
745+
(humi,) = struct.unpack("f", xobj)
746+
return {"humidity": humi}
747+
748+
734749
def obj4810(xobj):
735750
"""Sleep State"""
736751
sleep_state = xobj[0]
@@ -1050,6 +1065,12 @@ def obj4e1c(xobj):
10501065
return {"device reset": xobj[0]}
10511066

10521067

1068+
def obj5003(xobj):
1069+
"""Battery"""
1070+
batt = xobj[0]
1071+
return {"battery": batt}
1072+
1073+
10531074
def obj5010(xobj):
10541075
"""Sleep State"""
10551076
sleep_state = xobj[0]
@@ -1073,12 +1094,111 @@ def obj5403(xobj):
10731094
return {"battery": xobj[0]}
10741095

10751096

1097+
def obj5414(xobj):
1098+
"""Mode"""
1099+
mode = xobj[0]
1100+
return {"mode": mode}
1101+
1102+
10761103
def obj5601(xobj):
10771104
"""Low Battery"""
10781105
low_batt = xobj[0]
10791106
return {"low battery": low_batt}
10801107

10811108

1109+
def obj560c(xobj, device_type):
1110+
"""Click"""
1111+
if device_type in ["KS1", "KS1BP"]:
1112+
click = xobj[0]
1113+
if click == 1:
1114+
result = {
1115+
"four btn switch 1": "toggle",
1116+
"button switch": "single press",
1117+
}
1118+
elif click == 2:
1119+
result = {
1120+
"four btn switch 2": "toggle",
1121+
"button switch": "single press",
1122+
}
1123+
elif click == 3:
1124+
result = {
1125+
"four btn switch 3": "toggle",
1126+
"button switch": "single press",
1127+
}
1128+
elif click == 4:
1129+
result = {
1130+
"four btn switch 4": "toggle",
1131+
"button switch": "single press",
1132+
}
1133+
else:
1134+
result = None
1135+
return result
1136+
else:
1137+
return None
1138+
1139+
1140+
def obj560d(xobj, device_type):
1141+
"""Click"""
1142+
if device_type in ["KS1", "KS1BP"]:
1143+
click = xobj[0]
1144+
if click == 1:
1145+
result = {
1146+
"four btn switch 1": "toggle",
1147+
"button switch": "double press",
1148+
}
1149+
elif click == 2:
1150+
result = {
1151+
"four btn switch 2": "toggle",
1152+
"button switch": "double press",
1153+
}
1154+
elif click == 3:
1155+
result = {
1156+
"four btn switch 3": "toggle",
1157+
"button switch": "double press",
1158+
}
1159+
elif click == 4:
1160+
result = {
1161+
"four btn switch 4": "toggle",
1162+
"button switch": "double press",
1163+
}
1164+
else:
1165+
result = None
1166+
return result
1167+
else:
1168+
return None
1169+
1170+
1171+
def obj560e(xobj, device_type):
1172+
"""Click"""
1173+
if device_type in ["KS1", "KS1BP"]:
1174+
click = xobj[0]
1175+
if click == 1:
1176+
result = {
1177+
"four btn switch 1": "toggle",
1178+
"button switch": "long press",
1179+
}
1180+
elif click == 2:
1181+
result = {
1182+
"four btn switch 2": "toggle",
1183+
"button switch": "long press",
1184+
}
1185+
elif click == 3:
1186+
result = {
1187+
"four btn switch 3": "toggle",
1188+
"button switch": "long press",
1189+
}
1190+
elif click == 4:
1191+
result = {
1192+
"four btn switch 4": "toggle",
1193+
"button switch": "long press",
1194+
}
1195+
else:
1196+
result = None
1197+
return result
1198+
else:
1199+
return None
1200+
1201+
10821202
def obj5a16(xobj):
10831203
"""Bed occupancy"""
10841204
event = xobj[0]
@@ -1124,10 +1244,12 @@ def obj5a16(xobj):
11241244
0x100E: obj100e,
11251245
0x2000: obj2000,
11261246
0x3003: obj3003,
1247+
0x4801: obj4801,
11271248
0x4803: obj4803,
11281249
0x4804: obj4804,
11291250
0x4805: obj4805,
11301251
0x4806: obj4806,
1252+
0x4808: obj4808,
11311253
0x4810: obj4810,
11321254
0x4811: obj4811,
11331255
0x4818: obj4818,
@@ -1158,10 +1280,15 @@ def obj5a16(xobj):
11581280
0x4e16: obj4e16,
11591281
0x4e17: obj4e17,
11601282
0x4e1c: obj4e1c,
1283+
0x5003: obj5003,
11611284
0x5010: obj5010,
11621285
0x5011: obj5011,
11631286
0x5403: obj5403,
1287+
0x5414: obj5414,
11641288
0x5601: obj5601,
1289+
0x560c: obj560c,
1290+
0x560d: obj560d,
1291+
0x560e: obj560e,
11651292
0x5a16: obj5a16,
11661293
}
11671294

@@ -1350,7 +1477,19 @@ def parse_xiaomi(self, data: bytes, mac: str):
13501477
]:
13511478
resfunc = xiaomi_dataobject_dict.get(obj_typecode, None)
13521479
if resfunc:
1353-
if hex(obj_typecode) in ["0x8", "0x100e", "0x1001", "0xf", "0xb", "0x4e0c", "0x4e0d", "0x4e0e"]:
1480+
if hex(obj_typecode) in [
1481+
"0x8",
1482+
"0x100e",
1483+
"0x1001",
1484+
"0xf",
1485+
"0xb",
1486+
"0x4e0c",
1487+
"0x4e0d",
1488+
"0x4e0e",
1489+
"0x560c",
1490+
"0x560d",
1491+
"0x560e"
1492+
]:
13541493
result.update(resfunc(dobject, device_type))
13551494
else:
13561495
result.update(resfunc(dobject))

custom_components/ble_monitor/const.py

+48
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,50 @@ class BLEMonitorBinarySensorEntityDescription(
17231723
device_class=None,
17241724
state_class=None,
17251725
),
1726+
BLEMonitorSensorEntityDescription(
1727+
key="four btn switch 1",
1728+
sensor_class="SwitchSensor",
1729+
update_behavior="Instantly",
1730+
name="ble four button switch 1",
1731+
unique_id="btn_switch_1_",
1732+
icon="mdi:gesture-tap-button",
1733+
native_unit_of_measurement=None,
1734+
device_class=None,
1735+
state_class=None,
1736+
),
1737+
BLEMonitorSensorEntityDescription(
1738+
key="four btn switch 2",
1739+
sensor_class="SwitchSensor",
1740+
update_behavior="Instantly",
1741+
name="ble four button switch 2",
1742+
unique_id="btn_switch_2_",
1743+
icon="mdi:gesture-tap-button",
1744+
native_unit_of_measurement=None,
1745+
device_class=None,
1746+
state_class=None,
1747+
),
1748+
BLEMonitorSensorEntityDescription(
1749+
key="four btn switch 3",
1750+
sensor_class="SwitchSensor",
1751+
update_behavior="Instantly",
1752+
name="ble four button switch 3",
1753+
unique_id="btn_switch_3_",
1754+
icon="mdi:gesture-tap-button",
1755+
native_unit_of_measurement=None,
1756+
device_class=None,
1757+
state_class=None,
1758+
),
1759+
BLEMonitorSensorEntityDescription(
1760+
key="four btn switch 4",
1761+
sensor_class="SwitchSensor",
1762+
update_behavior="Instantly",
1763+
name="ble four button switch 4",
1764+
unique_id="btn_switch_4_",
1765+
icon="mdi:gesture-tap-button",
1766+
native_unit_of_measurement=None,
1767+
device_class=None,
1768+
state_class=None,
1769+
),
17261770
BLEMonitorSensorEntityDescription(
17271771
key="remote",
17281772
sensor_class="BaseRemoteSensor",
@@ -1850,6 +1894,8 @@ class BLEMonitorBinarySensorEntityDescription(
18501894
'MS1BB(MI)' : [["battery", "rssi"], ["button"], ["opening"]],
18511895
'HS1BB(MI)' : [["illuminance", "battery", "rssi"], [], ["motion"]],
18521896
'PS1BB' : [["battery", "rssi", "pressure present duration", "pressure not present duration", "pressure present time set", "pressure not present time set"], [], ["reset", "pressure state"]],
1897+
'KS1' : [["battery", "rssi"], ["four btn switch 1", "four btn switch 2", "four btn switch 3", "four btn switch 4"], []],
1898+
'KS1BP' : [["temperature", "humidity", "battery", "rssi"], ["four btn switch 1", "four btn switch 2", "four btn switch 3", "four btn switch 4"], []],
18531899
'XMPIRO2SXS' : [["illuminance", "battery", "rssi"], [], ["motion"]],
18541900
'XMWXKG01YL' : [["rssi"], ["two btn switch left", "two btn switch right"], []],
18551901
'XMWXKG01LM' : [["battery", "rssi"], ["one btn switch"], []],
@@ -1990,6 +2036,8 @@ class BLEMonitorBinarySensorEntityDescription(
19902036
'MS1BB(MI)' : 'Linptech',
19912037
'HS1BB(MI)' : 'Linptech',
19922038
'PS1BB' : 'Linptech',
2039+
'KS1' : 'Linptech',
2040+
'KS1BP' : 'Linptech',
19932041
'XMWXKG01YL' : 'Xiaomi',
19942042
'XMWXKG01LM' : 'Xiaomi',
19952043
'PTX' : 'Xiaomi',

custom_components/ble_monitor/sensor.py

+4
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ class BaseSensor(RestoreSensor, SensorEntity):
395395
# | | |**three btn switch left
396396
# | | |**three btn switch middle
397397
# | | |**three btn switch right
398+
# | | |**four btn switch 1
399+
# | | |**four btn switch 2
400+
# | | |**four btn switch 3
401+
# | | |**four btn switch 4
398402
# | |--BaseRemoteSensor (Class)
399403
# | | |**remote
400404
# | | |**fan remote

docs/_devices/Linptech_KS1.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
manufacturer: Linptech
3+
name: Smart Wireless Switch KS1
4+
model: KS1
5+
image: Linptech_KS1.png
6+
physical_description:
7+
broadcasted_properties:
8+
- four btn switch 1
9+
- four btn switch 2
10+
- four btn switch 3
11+
- four btn switch 4
12+
- battery
13+
- rssi
14+
broadcasted_property_notes:
15+
- property: four btn switch 1
16+
note: returns 'short press', 'double press' or 'long press'
17+
- property: four btn switch 2
18+
note: returns 'short press', 'double press' or 'long press'
19+
- property: four btn switch 3
20+
note: returns 'short press', 'double press' or 'long press'
21+
- property: four btn switch 4
22+
note: returns 'short press', 'double press' or 'long press'
23+
broadcast_rate:
24+
active_scan:
25+
encryption_key: Probably (not confirmed yet)
26+
custom_firmware:
27+
notes:
28+
- There are two different versions of this switch, without temperature/humidity (KS1) and with temperature/humidity (KS1).
29+
- 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).
30+
---

docs/_devices/Linptech_KS1BP.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
manufacturer: Linptech
3+
name: Smart Wireless Switch KS1 Pro
4+
model: KS1BP
5+
image: Linptech_KS1BP.png
6+
physical_description:
7+
broadcasted_properties:
8+
- temperature
9+
- humidity
10+
- four btn switch 1
11+
- four btn switch 2
12+
- four btn switch 3
13+
- four btn switch 4
14+
- battery
15+
- rssi
16+
broadcasted_property_notes:
17+
- property: four btn switch 1
18+
note: returns 'short press', 'double press' or 'long press'
19+
- property: four btn switch 2
20+
note: returns 'short press', 'double press' or 'long press'
21+
- property: four btn switch 3
22+
note: returns 'short press', 'double press' or 'long press'
23+
- property: four btn switch 4
24+
note: returns 'short press', 'double press' or 'long press'
25+
broadcast_rate:
26+
active_scan:
27+
encryption_key: Probably (not confirmed yet)
28+
custom_firmware:
29+
notes:
30+
- There are two different versions of this switch, without temperature/humidity (KS1) and with temperature/humidity (KS1BP).
31+
- 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).
32+
---

docs/assets/images/Linptech_KS1.png

8.93 KB
Loading

docs/assets/images/Linptech_KS1BP.png

13 KB
Loading

0 commit comments

Comments
 (0)