Skip to content

Support FTMS devices without service_data (data‑only fallback + detect type after connect)#49

Open
mhamzahkhan wants to merge 1 commit into
dudanov:mainfrom
mhamzahkhan:main
Open

Support FTMS devices without service_data (data‑only fallback + detect type after connect)#49
mhamzahkhan wants to merge 1 commit into
dudanov:mainfrom
mhamzahkhan:main

Conversation

@mhamzahkhan

Copy link
Copy Markdown

Hi! I ran into this on a budget SLUNSE Exercise Bike I bought on Amazon. It advertises the FTMS service UUID (0x1826) but doesn’t include the FTMS service_data in the advertisement. Because of that, pyftms rejected it with NotFitnessMachineError even though, after connecting, the device does expose the FTMS data stream and sends notifications.

Context: I discovered this while trying to integrate the bike into Home Assistant using the FTMS custom component.

This PR lets pyftms still connect and read data in that situation.

I’m not sure how common this pattern is across other devices. I tried to keep the change as generic and low‑risk as possible so it can help similar cases without impacting fully compliant devices.

What I changed:

  • Try anyway if FTMS UUID is there: When the advertisement can’t be parsed but the FTMS UUID is present, pyftms now creates a placeholder client and connects.
  • Detect the real type after connecting: It checks which FTMS data characteristic is present and notifiable (2AD2/2ACD/2ACE/2AD1) and switches to that machine type/data model.
  • Data‑only mode: If the FTMS Feature characteristic is missing, it continues without controls/ranges (still subscribes to the live data stream).
  • Subscribe fallback: If subscribing to the first picked data characteristic fails, it falls back to 2AD2 (indoor bike data) when available. This might be a problem if there are other non-bike devices that have the same issue.

Is the placeholder approach okay? It gets corrected right after connect.
I’m not sure this is the best way to solve it; very open to advice, critique, or alternative approaches.

I haven't tested if this fixes the Home Assistant component yet.

Happy to provide any further information or debugging if needed to make a better fix.

@michaelw

Copy link
Copy Markdown

I tested this branch against a Wahoo KICKR CORE C23A through a Home Assistant dev harness with an ESPHome Bluetooth proxy.

Observed advertisement shape:

  • name: KICKR CORE C23A
  • service UUIDs: 1818, 1826
  • service data: empty

With the Home Assistant integration also matching FTMS service_uuid advertisements, this PR's pyftms changes let the FTMS config flow progress past connection, detect MachineType.INDOOR_BIKE, read Wahoo device info, expose the expected indoor bike sensors/settings, and create a loaded config entry titled Wahoo Fitness GENERIC (254941722).

Relevant runtime evidence from the harness:

  • Machine type: <MachineType.INDOOR_BIKE: 32>
  • available sensors included training_status
  • supported settings included target_resistance and target_power
  • supported ranges included resistance 0..10 and power 0..2000
  • the created Home Assistant entry loaded successfully

So this approach fixes the UUID-only advertisement case for this KICKR CORE path in practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants