Skip to content

Commit 4777397

Browse files
authored
Merge pull request #1380 from zt8989/master
Add initial support for Senssun scale
2 parents d8518a9 + 532717b commit 4777397

File tree

9 files changed

+105
-1
lines changed

9 files changed

+105
-1
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ This custom component for [Home Assistant](https://www.home-assistant.io) passiv
5454
- Ruuvitag
5555
- Sensirion
5656
- SensorPush
57+
- Senssun (Scale)
5758
- SmartDry
5859
- Switchbot
5960
- Teltonika

custom_components/ble_monitor/ble_parser/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from .ruuvitag import parse_ruuvitag
3939
from .sensirion import parse_sensirion
4040
from .sensorpush import parse_sensorpush
41+
from .senssun import parse_senssun
4142
from .smartdry import parse_smartdry
4243
from .switchbot import parse_switchbot
4344
from .teltonika import parse_teltonika
@@ -422,6 +423,10 @@ def parse_advertisement(
422423
# Laica
423424
sensor_data = parse_laica(self, man_spec_data, mac)
424425
break
426+
elif comp_id == 0x0100 and data_len == 0x14:
427+
# Senssun IF_B7
428+
sensor_data = parse_senssun(self, man_spec_data, mac)
429+
break
425430

426431
# Filter on part of the UUID16
427432
elif man_spec_data[2] == 0xC0 and data_len == 0x10:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""Parser for Senssun Scale BLE advertisements"""
2+
3+
import logging
4+
from struct import unpack
5+
6+
from .helpers import to_mac, to_unformatted_mac
7+
8+
_LOGGER = logging.getLogger(__name__)
9+
10+
11+
def read_stable(ctr1):
12+
"""Parse Stable"""
13+
return int((ctr1 & 0xA0) == 0xA0)
14+
15+
def parse_senssun(self, data: bytes, mac: str):
16+
"""Parser for Senssun Scales."""
17+
xvalue = data[13:19]
18+
19+
(division, weight, impedance, ctr1) = unpack(">bhhb", xvalue)
20+
result = {
21+
"type": "Senssun Smart Scale",
22+
"firmware": "Senssun",
23+
"mac": to_unformatted_mac(mac),
24+
"data": True,
25+
"impedance": impedance,
26+
"weight": weight / 100.0,
27+
"stabilized": read_stable(ctr1),
28+
}
29+
30+
# Check for duplicate messages
31+
packet_id = xvalue.hex()
32+
try:
33+
prev_packet = self.lpacket_ids[mac]
34+
except KeyError:
35+
# start with empty first packet
36+
prev_packet = None
37+
if prev_packet == packet_id:
38+
# only process new messages
39+
if self.filter_duplicates is True:
40+
return None
41+
self.lpacket_ids[mac] = packet_id
42+
if prev_packet is None:
43+
if self.filter_duplicates is True:
44+
# ignore first message after a restart
45+
return None
46+
47+
result.update({
48+
"packet": packet_id,
49+
})
50+
return result

custom_components/ble_monitor/const.py

+2
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,7 @@ class BLEMonitorBinarySensorEntityDescription(
19751975
'K6 Sensor Beacon' : [["temperature", "humidity", "acceleration", "voltage", "battery", "rssi"], [], []],
19761976
'DSL-C08' : [["battery", "rssi", "voltage"], [], ["lock", "childlock"]],
19771977
'SmartDry cloth dryer' : [["temperature", "humidity", "voltage", "battery", "shake", "rssi"], [], ["switch"]],
1978+
'Senssun Smart Scale' : [["rssi"], ["weight", "impedance"], []],
19781979
}
19791980

19801981
# Sensor manufacturer dictionary
@@ -2111,6 +2112,7 @@ class BLEMonitorBinarySensorEntityDescription(
21112112
'Laica Smart Scale' : 'Laica',
21122113
'K6 Sensor Beacon' : 'KKM',
21132114
'SmartDry cloth dryer' : 'SmartDry',
2115+
'Senssun Smart Scale' : 'Senssun',
21142116
}
21152117

21162118

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""The tests for the Senssun ble_parser."""
2+
3+
import datetime
4+
5+
from ble_monitor.ble_parser import BleParser
6+
7+
8+
class TestSenssun:
9+
"""Tests for the Senssun parser"""
10+
11+
def test_Senssun_IF_B7(self):
12+
"""Test Senssun parser for IF_B7."""
13+
data_string = "043E2B0201030033B3C1937A181F020106060949465F423714FF0001020311187A93C1B333021A4500B4A1AB61C5"
14+
data = bytes(bytearray.fromhex(data_string))
15+
16+
# pylint: disable=unused-variable
17+
ble_parser = BleParser()
18+
sensor_msg, tracker_msg = ble_parser.parse_raw_data(data)
19+
20+
assert sensor_msg["firmware"] == "Senssun"
21+
assert sensor_msg["type"] == "Senssun Smart Scale"
22+
assert sensor_msg["mac"] == "187A93C1B333"
23+
assert sensor_msg["packet"] == "021a4500b4a1"
24+
assert sensor_msg["data"]
25+
assert sensor_msg["weight"] == 67.25
26+
assert sensor_msg["stabilized"] == 1
27+
assert sensor_msg["impedance"] == 180
28+
assert sensor_msg["rssi"] == -59

docs/_devices/Senssun_Smart_Scale.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
manufacturer: Senssun
3+
name: Senssun Smart Scale
4+
model: IF_B7
5+
image: IF_B7.jpg
6+
physical_description:
7+
broadcasted_properties:
8+
- weight
9+
- impedance
10+
- rssi
11+
broadcasted_property_notes:
12+
broadcast_rate:
13+
active_scan:
14+
encryption_key:
15+
custom_firmware:
16+
notes:
17+
---

docs/assets/images/IF_B7.jpg

5.98 KB
Loading

docs/config_params.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Data from sensors with other addresses will be ignored. Default value: True
123123

124124
**Report unknown sensors**
125125

126-
(`Off`, `Acconeer`, `Air Mentor`, `Amazfit`, `ATC`, `BlueMaestro`, `Blustream`, `Brifit`, `BTHome`, `Chef iQ`, `Govee`, `Grundfos`, `HolyIOT`, `Hormann`, `HHCC`, `iNode`, `iBeacon`, `Jinou`, `Kegtron`, `Mi Scale`, `Mi Band`,`Mikrotik`, `Oras`, `Qingping`, `Relsib`, `rbaron`, `Ruuvitag`, `Sensirion`, `SensorPush`, `SmartDry`, `Switchbot`, `Teltonika`, `Thermoplus`, `Xiaogui`, `Xiaomi`, `Other` or `False`)(Optional) This option is needed primarily for those who want to request an implementation of device support that is not in the list of [supported sensors](devices). If you set this parameter to one of the sensor brands, then the component will log all messages from unknown devices of the specified brand to the Home Assistant log (`logger` component must be enabled at info level, see for instructions the [FAQ](faq#my-sensor-from-the-xiaomi-ecosystem-is-not-in-the-list-of-supported-ones-how-to-request-implementation)). Using a sensor brand might not catch all BLE advertisements.
126+
(`Off`, `Acconeer`, `Air Mentor`, `Amazfit`, `ATC`, `BlueMaestro`, `Blustream`, `Brifit`, `BTHome`, `Chef iQ`, `Govee`, `Grundfos`, `HolyIOT`, `Hormann`, `HHCC`, `iNode`, `iBeacon`, `Jinou`, `Kegtron`, `Mi Scale`, `Mi Band`,`Mikrotik`, `Oras`, `Qingping`, `Relsib`, `rbaron`, `Ruuvitag`, `Sensirion`, `SensorPush`, `Senssun`, `SmartDry`, `Switchbot`, `Teltonika`, `Thermoplus`, `Xiaogui`, `Xiaomi`, `Other` or `False`)(Optional) This option is needed primarily for those who want to request an implementation of device support that is not in the list of [supported sensors](devices). If you set this parameter to one of the sensor brands, then the component will log all messages from unknown devices of the specified brand to the Home Assistant log (`logger` component must be enabled at info level, see for instructions the [FAQ](faq#my-sensor-from-the-xiaomi-ecosystem-is-not-in-the-list-of-supported-ones-how-to-request-implementation)). Using a sensor brand might not catch all BLE advertisements.
127127

128128
If you can't find the advertisements in this way, you can set this option to `Other`, which will result is all BLE advertisements being logged. You can also enable this option at device level. **Attention!** Enabling this option can lead to huge output to the Home Assistant log, especially when set to `Other`, do not enable it if you do not need it! If you know the MAC address of the sensor, its advised to set this option at device level. Details in the [FAQ](faq#my-sensor-from-the-xiaomi-ecosystem-is-not-in-the-list-of-supported-ones-how-to-request-implementation). Default value: `Off`
129129

info.md

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ This custom component for [Home Assistant](https://www.home-assistant.io) passiv
5555
- Ruuvitag
5656
- Sensirion
5757
- SensorPush
58+
- Senssun
5859
- SmartDry
5960
- Switchbot
6061
- Teltonika

0 commit comments

Comments
 (0)