OpenMQTTGateway
OpenMQTTGateway copied to clipboard
Blood pressure sensor Silvercrest SBM69
Is your feature request related to a problem? Please describe. No.
This is a request for a new BLE device, such as Silvercrest SBM69 sold by LIDL in Europe.
Describe the solution you'd like I need to integrate this blood pressure product on my Home Assistant instance, regarding my biometrics usage for automations and automatic long term register.
Captured data with the android APP "nRF Connect".
RAW Data: 0x060953424D36390201060302101804FF130601
Blood pressure service: 00001810-0000-1000-8000-00805f9b35fb Blood pressure measurement characteristic: 00002a35-0000-1000-8000-00805f9b34fb Properties: Indicate Value: Systolic: xxx.xx mmHg Disastolic: yyy.yy mmHg Mean AP: zzz.zz mmHg Timestamp: hh:mm:ss dd.mm.yyyy Pulse: aaa.a bpm User ID: 0
Describe alternatives you've considered No other solution known is available.
Additional context This device requires an active BLE connection, inserting a randomly key code generated only on the first pairing moment.
FCC info: https://fccid.io/OU9SBM69-B01
" inserting a randomly key code generated only on the first pairing moment." ...and the solution?
The device seems to use the much of the standard HDP for blood pressure monitoring with the exception of not using 16-bit floats for sys/dia/avg/pulse. Here's an ImHex pattern that recognises the output:
bitfield Flags {
blood_pressure_units: 1;
time_stamp: 1;
pulse_rate: 1;
user_id: 1;
measurement_status: 1;
reserved_for_future_use: 3;
};
bitfield MeasurementStatus {
body_movement_detected: 1;
cuff_too_loose: 1;
irregular_pulse: 1;
pulse_rate_exceeds_lower_limit: 1;
pulse_rate_exceeds_upper_limit: 1;
improper_measurement_position: 1;
reserved_for_future_use: 10;
};
struct BloodPressureMeasurement {
le Flags flags;
if (flags.blood_pressure_units) {
le u16 systolic_kpa;
le u16 diastolic_kpa;
le u16 mean_arterial_pressure_kpa;
} else {
le u16 systolic_mmhg;
le u16 diastolic_mmhg;
le u16 mean_arterial_pressure_mmhg;
}
if (flags.time_stamp) {
le u16 year;
u8 month;
u8 day;
u8 hours;
u8 minutes;
u8 seconds;
}
if (flags.pulse_rate) {
le u16 pulse_rate;
}
if (flags.user_id) {
u8 user_id;
}
if (flags.measurement_status) {
le MeasurementStatus measurement_status;
}
};
BloodPressureMeasurement bpm @ 0x00;
https://www.bluetooth.com/specifications/specs/gatt-specification-supplement/ https://www.bluetooth.com/specifications/specs/blood-pressure-service-1-1-1/ https://www.bluetooth.com/specifications/specs/blood-pressure-profile-1-1-1/
Python PoC that reads out all relevant data from the device:
import asyncio
from bleak import BleakClient
from bleak.backends.characteristic import BleakGATTCharacteristic
address = "b8:b7:7d:XX:XX:XX"
async def main(address):
async with BleakClient(address) as client:
for service in client.services:
print("Service: {0} ({1})".format(service.description, service.uuid))
for characteristic in service.characteristics:
print(" Characteristic: {0} ({1}), properties: {2}".format(characteristic.description, characteristic.uuid, ",".join(characteristic.properties)))
for descriptor in characteristic.descriptors:
print(" Descriptor: {0} ({1})".format(descriptor.description, descriptor.uuid))
if 'read' in characteristic.properties:
value = await client.read_gatt_char(characteristic.uuid)
print(" Value: {0} ({1})".format("".join(map(chr, value)), value.hex()))
if 'indicate' in characteristic.properties:
try:
await asyncio.wait_for(client.start_notify(characteristic.uuid, on_notification), timeout=2)
except TimeoutError:
await client.stop_notify(characteristic.uuid)
def on_notification(handle: BleakGATTCharacteristic, data: bytearray):
print(" Value: {0}".format(data.hex()))
asyncio.run(main(address))
Service: Device Information (0000180a-0000-1000-8000-00805f9b34fb)
Characteristic: PnP ID (00002a50-0000-1000-8000-00805f9b34fb), properties: read
Value: ()
Characteristic: Serial Number String (00002a25-0000-1000-8000-00805f9b34fb), properties: read
Value: XXXXXXXXXXXX (XXXXXXXXXXXXXXXXXXXXXXXX)
Characteristic: Software Revision String (00002a28-0000-1000-8000-00805f9b34fb), properties: read
Value: 2.0 (322e30)
Characteristic: Firmware Revision String (00002a26-0000-1000-8000-00805f9b34fb), properties: read
Value: 2.0 (322e30)
Characteristic: Hardware Revision String (00002a27-0000-1000-8000-00805f9b34fb), properties: read
Value: 7100 (37313030)
Characteristic: IEEE 11073-20601 Regulatory Cert. Data List (00002a2a-0000-1000-8000-00805f9b34fb), properties: read
Value: ()
Characteristic: Model Number String (00002a24-0000-1000-8000-00805f9b34fb), properties: read
Value: SBM69 (53424d3639)
Characteristic: Manufacturer Name String (00002a29-0000-1000-8000-00805f9b34fb), properties: read
Value: Hans Dinslage GmbH (48616e732044696e736c61676520476d6248)
Characteristic: System ID (00002a23-0000-1000-8000-00805f9b34fb), properties: read
Value: (0000000000000000)
Service: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
Characteristic: Service Changed (00002a05-0000-1000-8000-00805f9b34fb), properties: indicate
Descriptor: Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
Service: Blood Pressure (00001810-0000-1000-8000-00805f9b34fb)
Characteristic: Blood Pressure Feature (00002a49-0000-1000-8000-00805f9b34fb), properties: read
Value: (0400)
Characteristic: Intermediate Cuff Pressure (00002a36-0000-1000-8000-00805f9b34fb), properties: notify
Descriptor: Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
Characteristic: Blood Pressure Measurement (00002a35-0000-1000-8000-00805f9b34fb), properties: indicate
Descriptor: Client Characteristic Configuration (00002902-0000-1000-8000-00805f9b34fb)
Value: 1eXXXXXXXXXXXXe70702190d3200XX00000000
Value: 1eXXXXXXXXXXXXe70702190d3300XX00000000
Value: 1eXXXXXXXXXXXXe70702190d3500XX00000400
Value: 1eXXXXXXXXXXXXe7070219170000XX00000000
Unfortunately it is necessary for the device to be paired at first use. It refuses to respond unless paired.
Unless some functions require registration for NOTIFY, all others can be read by OpenMQTTGateway's READ command
For OpenMTTGateway to be able to directly publish decoded properties through the Theengs Decoder library, the Silvercrest SBM69 would need to broadcast its information in its advertisement data. If this is the case could you provide some sample data along with the relevant reading?
Unfortunately you need to subscribe to indicate
events for the 'Blood Pressure Measurement (00002a35-0000-1000-8000-00805f9b34fb)' characteristic in order to get the measurement data. No relevant data is part of the advertisements of the device.
Unfortunately this is then currently not accessible through OpenMQTTGateway.
FWIW I just created https://github.com/ignisf/sbm69 and will be looking into making a home assistant component that uses it.