Skip to content

[New Sensor]: Ningui-Jinmiao HD02 BLE Scale #1487

@Solarbotics

Description

@Solarbotics

Sensor Description

Generic BLE scale labled HD02, compatible with Android "OpenScale" type OkOk.

Additional information

I have managed to integrate this via ESPhome, but am attempting migration to a BLE-embedded Raspberry Pi solution.

Setting up 'configuration.yaml' with:

  default: warn
  logs:
    custom_components.ble_monitor: info

ble_monitor:
  bt_interface: "DC:A6:32:C3:0B:F2"
  active_scan: true
  discovery: false
  devices:
    - mac: "C0:FF:00:14:D0:56"
      name: "HD02 Scale"
  period: 5```

Reports:

```This error originated from a custom integration.

Logger: custom_components.ble_monitor.ble_parser.xiaogui
Source: custom_components/ble_monitor/ble_parser/xiaogui.py:59
integration: Passive BLE monitor (documentation, issues)
First occurred: 12:24:58 AM (421 occurrences)
Last logged: 12:25:20 AM

Stabilized byte of Xiaogui scale is reporting a new value, please report an issue to the developers with this error: Payload is 10ffc000008700000a1104c0ff0014d056
Stabilized byte of Xiaogui scale is reporting a new value, please report an issue to the developers with this error: Payload is 10ffc00000c300000a1104c0ff0014d056
Stabilized byte of Xiaogui scale is reporting a new value, please report an issue to the developers with this error: Payload is 10ffc00000f500000a1104c0ff0014d056
Stabilized byte of Xiaogui scale is reporting a new value, please report an issue to the developers with this error: Payload is 10ffc000001e00000a1104c0ff0014d056
Stabilized byte of Xiaogui scale is reporting a new value, please report an issue to the developers with this error: Payload is 10ffc000000000000a1104c0ff0014d056```

ESPHome relevant code that returns valid data is:
```esp32_ble_tracker:
  scan_parameters:
    interval: 1100ms
    window: 1100ms
    active: true
  on_ble_advertise:
    - mac_address: C0:FF:00:14:D0:56
      then:
        - lambda: |-
            for (auto data : x.get_manufacturer_datas()) {
              if (data.data.size() >= 2) {
                // Big-endian bytes 0..1
                uint16_t weight_raw = (uint16_t(data.data[0]) << 8) | uint16_t(data.data[1]);
                float weight = weight_raw / 100.0f;  // kg
                if (weight > 5.0f && weight < 200.0f) {
                  id(alpha_weight).publish_state(weight);
                  ESP_LOGI("ble_weight", "Parsed: %.2f kg / %.2f lb (raw=0x%04X)", weight, weight * 2.20462f, weight_raw);
                }
              }
            }

sensor:
  # Base sensor in kg
  - platform: template
    name: "Scale Weight (kg)"
    id: alpha_weight
    unit_of_measurement: "kg"
    device_class: weight
    state_class: measurement
    accuracy_decimals: 1
    update_interval: never
    on_value:
      then:
        - sensor.template.publish:
            id: alpha_weight_lb
            state: !lambda 'return x * 2.20462f;'

  - platform: template
    name: "Scale Weight (lb)"
    id: alpha_weight_lb
    unit_of_measurement: "lb"
    device_class: weight
    state_class: measurement
    accuracy_decimals: 1
    update_interval: never

time:
  - platform: homeassistant
    id: homeassistant_time

Scale reports temperature as well, but have not figured out the bytes for that yet. Scale & PCB images already documented here

BLE advertisements

2025-08-05 23:27:46.44, -84 dBm, 0x10FFC000087000000A1104C0FF0014D056
2025-08-05 23:27:45.554, -86 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.553, -86 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.528, -85 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.528, -86 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.5, -86 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.499, -86 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.474, -85 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.473, -85 dBm, 0x10FFC00008CF00000A1104C0FF0014D056
2025-08-05 23:27:45.446, -85 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.445, -85 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.416, -85 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.416, -84 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.391, -85 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.388, -83 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.365, -82 dBm, 0x10FFC00008BB00000A1104C0FF0014D056
2025-08-05 23:27:45.364, -82 dBm, 0x10FFC00008BB00000A1104C0FF0014D056

Metadata

Metadata

Assignees

Labels

new sensorRequest for a new sensor

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions