Files
Vibe Myass 13b95345c7 BM200 protocol findings and test bench
Spec with pseudocode and test vectors, APK disassembly, analysis tools,
shelved reference Python and the macOS BLE probe. Findings are not yet
validated against a real tag. The vendor XAPK and nested lib clone are
excluded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EinWd3UT2Xw7UakFtTp6hn
2026-11-01 02:58:16 +00:00

59 lines
2.1 KiB
YAML

# ANCEL BM200: live voltage only. History needs bm2.bm200 (reassembly across frames).
# The writes are AES-encrypted D15501, D1550200, D15507; without the last one the tag sends no live frames.
esp32_ble_tracker:
ble_client:
- mac_address: !secret bm2_mac
id: bm2_battery_meter
on_connect:
then:
- delay: 1s
- ble_client.ble_write:
id: bm2_battery_meter
service_uuid: 'fff0'
characteristic_uuid: 'fff3'
value: [0x1a, 0xd6, 0xf0, 0x5e, 0x49, 0x90, 0xab, 0x24, 0xb8, 0x4d, 0x57, 0xdf, 0x81, 0xd8, 0x76, 0x6e]
- delay: 500ms
- ble_client.ble_write:
id: bm2_battery_meter
service_uuid: 'fff0'
characteristic_uuid: 'fff3'
value: [0x9c, 0xb1, 0x80, 0x29, 0x77, 0x4c, 0x5c, 0xfc, 0x57, 0xc9, 0xf1, 0x14, 0xd4, 0x0d, 0xb4, 0xe8]
- delay: 500ms
- ble_client.ble_write:
id: bm2_battery_meter
service_uuid: 'fff0'
characteristic_uuid: 'fff3'
value: [0x69, 0x7e, 0xa0, 0xb5, 0xd5, 0x4c, 0xf0, 0x24, 0xe7, 0x94, 0x77, 0x23, 0x55, 0x55, 0x41, 0x14]
sensor:
- platform: ble_client
type: characteristic
ble_client_id: bm2_battery_meter
name: Voltage
service_uuid: 'fff0'
characteristic_uuid: 'fff4'
unit_of_measurement: 'V'
accuracy_decimals: 2
state_class: measurement
device_class: voltage
force_update: true
expire_after: 5min
notify: true
lambda: |-
if (x.size() != 16) return NAN;
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
unsigned char output[16];
unsigned char key[16] = { 108, 101, 97, 103, 101, 110, 100, 255, 254, 48, 49, 48, 48, 48, 48, 57 };
unsigned char iv[16] = {};
mbedtls_aes_setkey_dec(&aes, key, 128);
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, iv, (uint8_t*)&x[0], output);
mbedtls_aes_free(&aes);
// D1 55 07 only; 0xFF in byte 3 is the command ack
if (output[0] != 0xD1 || output[1] != 0x55 || output[2] != 0x07 || output[3] == 0xFF) return NAN;
return ((output[7] << 8) | output[8]) / 100.0f;
filters:
- filter_out: nan