RealtimeData._deserialize_asdict always reads a 2-byte (16-bit) flags field. For Cross Trainer Data (0x2ACE), this causes a 1-byte offset in all subsequent data fields, producing corrupt values for distance, time, energy, and other sensors.
Reading 3 bytes instead of 2 fixes the issue. Other implementations also use 3 bytes for Cross Trainer flags — see qdomyos-zwift (index += 3 for Cross Trainer vs index += 2 for other machine types).
We could not find an explicit "3-octet flags" statement in the FTMS service specification (Section 4.5.1.1, Table 4.6 shows 16 flag bits), but the fix works on a real BH cross trainer device. Other machine types (Treadmill, Indoor Bike, Rower) correctly use 16-bit flags.
Fix available at pafernanr/python-pyftms:upstream-fix — would you like me to open a PR?
RealtimeData._deserialize_asdictalways reads a 2-byte (16-bit) flags field. For Cross Trainer Data (0x2ACE), this causes a 1-byte offset in all subsequent data fields, producing corrupt values for distance, time, energy, and other sensors.Reading 3 bytes instead of 2 fixes the issue. Other implementations also use 3 bytes for Cross Trainer flags — see qdomyos-zwift (
index += 3for Cross Trainer vsindex += 2for other machine types).We could not find an explicit "3-octet flags" statement in the FTMS service specification (Section 4.5.1.1, Table 4.6 shows 16 flag bits), but the fix works on a real BH cross trainer device. Other machine types (Treadmill, Indoor Bike, Rower) correctly use 16-bit flags.
Fix available at pafernanr/python-pyftms:upstream-fix — would you like me to open a PR?