Ampler eBike Bluetooth protocol

I have an Ampler Stout eBike which exposes metrics as Bluetooth attributes over GATT. I’d like to track the battery level and odomoter, so spent some time and decoded some of the attributes.

The bike exposes:

CharacteristicExample data
340d1528-a89e-4d4e-9078-06d21096ea360x5b 0x00 0x00 0x00 0x11 0x02 0x00 0x00 0x04 0x01 0x00 0x00 0x00 0x00 0x00 0x00
340d1529-a89e-4d4e-9078-06d21096ea360x00 0x00 0x00 0x00 0xdf 0x14 0x00 0x00 0x9c 0x0a 0x90 0x00
340d1530-a89e-4d4e-9078-06d21096ea360xa0 0x00 0x90 0x01 0x02 0x00 0x06 0x00 0x64 0x00 0xfa 0x00
340d1542-a89e-4d4e-9078-06d21096ea360x58 0x02
340d1545-a89e-4d4e-9078-06d21096ea360x0a 0x18 0xe2 0x64
340d1547-a89e-4d4e-9078-06d21096ea360xff 0x02 0x11 0x00 0x00 0x00 0x03 0x00
340d1548-a89e-4d4e-9078-06d21096ea360x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00
340d1549-a89e-4d4e-9078-06d21096ea360x00 0x00 0x00 0x00

The format appears to pack related values into the same characteristic. Values are little endian and either half words or words. The units seem to be metric such as m for range and m/s for speed with a power of 10 multiplier, such as the voltage being in decivolts:

340d1528-a89e-4d4e-9078-06d21096ea36HHhH% charged, voltage (dV), temperature (dºC), ?
340d1529-a89e-4d4e-9078-06d21096ea36III?, speed (mm/s), odometer (dm)
340d1536-a89e-4d4e-9078-06d21096ea36Bassist level (0, 1, 2)
340d1538-a89e-4d4e-9078-06d21096ea36? (bool)light
340d1545-a89e-4d4e-9078-06d21096ea36I? increases over time 1692538885

The time value isn’t clear but might be a POSIX time, i.e. roughly Sunday, 20 August 2023.

Decoding the example above gives:

340d1528-a89e-4d4e-9078-06d21096ea3691 % charged, 52.9 V, 26.0 ºC, 0
340d1529-a89e-4d4e-9078-06d21096ea360, 5343 mm/s (19.2 km/h), 943.9900 km
340d1536-a89e-4d4e-9078-06d21096ea36assist level 1
340d1538-a89e-4d4e-9078-06d21096ea36light off

Next step is to implement a decoder, export this to Home Assistant, and collect it via Prometheus.

Michael Hope
Software Engineer