@@ -49,6 +49,8 @@ class OneByoneHandler : ScaleDeviceHandler() {
4949 private val SVC_FFF0 = uuid16(0xFFF0 )
5050 private val CHR_FFF4 = uuid16(0xFFF4 ) // NOTIFY: mixed weight/body payloads (CF ...)
5151 private val CHR_FFF1 = uuid16(0xFFF1 ) // WRITE: command pipe (FD/ F1/ F2 ...)
52+ private val SVC_180F = uuid16(0x180F ) // battery service
53+ private val CHR_2A19 = uuid16(0x2A19 ) // battery characteristic
5254
5355 // --- Small runtime state ---------------------------------------------------
5456
@@ -64,8 +66,13 @@ class OneByoneHandler : ScaleDeviceHandler() {
6466
6567 override fun supportFor (device : ScannedDeviceInfo ): DeviceSupport ? {
6668 val name = device.name.lowercase()
67- val supports = name.equals(" Health Scale" .lowercase())
68- if (! supports) return null
69+
70+ val model = when {
71+ " t9146" in name -> " Eufy C1"
72+ " t9147" in name -> " Eufy P1"
73+ " Health Scale" .lowercase() in name -> " 1byone (classic)"
74+ else -> return null
75+ }
6976
7077 val caps = buildSet {
7178 add(DeviceCapability .BODY_COMPOSITION )
@@ -76,7 +83,7 @@ class OneByoneHandler : ScaleDeviceHandler() {
7683 }
7784
7885 return DeviceSupport (
79- displayName = " 1byone (classic) " ,
86+ displayName = model ,
8087 capabilities = caps,
8188 implemented = caps,
8289 linkMode = LinkMode .CONNECT_GATT
@@ -97,15 +104,28 @@ class OneByoneHandler : ScaleDeviceHandler() {
97104 waitAckClock = true
98105 writeTo(SVC_FFF0 , CHR_FFF1 , clock)
99106
107+ // 1) Battery: subscribe + read once
108+ setNotifyOn(SVC_180F , CHR_2A19 )
109+ readFrom(SVC_180F , CHR_2A19 )
110+
100111 // NOTE: After we receive the ACK, we will request history (F2 00) in onNotification().
101112 }
102113
103114 override fun onNotification (characteristic : UUID , data : ByteArray , user : ScaleUser ) {
104- if (characteristic != CHR_FFF4 ) {
115+ if (characteristic != CHR_FFF4 && characteristic != CHR_2A19 ) {
105116 logD(" Unexpected notify from $characteristic ${data.toHexPreview(24 )} " )
106117 return
107118 }
108119
120+ if (characteristic == CHR_2A19 ) {
121+ val level = (data.first().toInt() and 0xFF )
122+ logD(" Reported battery level: $level %" )
123+ if (level <= 10 ) {
124+ userWarn(R .string.bluetooth_scale_warning_low_battery, level)
125+ }
126+ return
127+ }
128+
109129 // Two-byte ACKs appear during setup:
110130 if (data.size == 2 ) {
111131 when {
0 commit comments