Skip to content

Add support for non-compliant devices (+ minor improvements)#54

Open
chkuendig wants to merge 5 commits intodudanov:mainfrom
chkuendig:sole-fix
Open

Add support for non-compliant devices (+ minor improvements)#54
chkuendig wants to merge 5 commits intodudanov:mainfrom
chkuendig:sole-fix

Conversation

@chkuendig
Copy link

@chkuendig chkuendig commented Jan 28, 2026

This is trying to solve the same issue as #49 but in a more generic way. I noticed various issues when trying to add my 2001 Sole F65. It lacks FTMS controls, doesn't advertise service_data and has a few other minor problems.

This adds a Unknown device type that's only to be used during discovery, to avoid some of the issues in #49 for devices where device type isn't clear before actually talking to them.

If anybody wants to test this: Just add https://github.com/chkuendig/hassio-ftms in HACS and install from there.

Details

Add Unknown device support for non-compliant FTMS devices

Some devices (e.g., Sole treadmills) advertise FTMS UUID but don't
provide proper service_data to determine machine type. This adds:

  • Unknown machine class that detects type by subscribing to all data UUIDs
  • MachineType.UNKNOWN enum value for initial discovery
  • Detection logic in get_machine_type_from_service_data
  • Data-only fallback when FTMS Feature characteristic is missing
  • Graceful handling of truncated/extra bytes in realtime data

After type detection, Unknown proxies all calls to the real client type.

Add debug logging for live_properties

No impact in default config, but helps in case of issues

Add fw_version to device info with sw_version fallback

  • Read firmware revision characteristic (0x2a26)
  • Use fw_version as sw_version if sw_version is missing or placeholder (0, 00, etc.)

Don't ignore 0 values in realtime data

Changed truthiness checks to explicit None checks so that properties
with value 0 (like speed=0, distance=0) are not filtered out. This helps during detection if e.g. heart beat is not active/connected.

@pafernanr
Copy link

pafernanr commented Jan 29, 2026

Hello,

Thank you so much @chkuendig++, I tested the PR on my HA and now the elliptical bike is recognised. There are some unsupported data training but after remove the unsupported items the bike was added.

  • This is the initial message.
image
  • In order to add the bike I removed next items:
    • speed
    • step_rate
    • movement_direction

Could these items can be mapped/added to the supported ones?

Regards,

@chkuendig chkuendig force-pushed the sole-fix branch 2 times, most recently from 364f547 to e209f2a Compare January 29, 2026 19:06
The movement_direction field in CrossTrainerData was missing model_meta(),
causing it to be excluded from available_properties. This resulted in
validation errors in the HA integration options flow.
@chkuendig
Copy link
Author

chkuendig commented Jan 29, 2026

@pafernanr I think I found the issue causing that error, try re-downloading the newest version ( fabde69 ) from my repo and see if that works.

@pafernanr
Copy link

Hi,

Sorry for the delay, I've been travelling for the last few days.

I am not able to test it, even installing hassio-ftms using HACS shows next error message. The requirements cannot be installed. I'm not experienced with containters, but I think it could be related to the recentrly introduced "Docker Containerd Snapshotter" (https://github.com/home-assistant/operating-system/releases/tag/17.0)

  • This is the Error message
Logger: homeassistant.util.package
Source: util/package.py:178
First occurred: 14:43:53 (3 occurrences)
Last logged: 14:43:54

Unable to install package pyftms==0.4.10: error: Failed to install: pyftms-0.4.10-py3-none-any.whl (pyftms==0.4.10) Caused by: No such file or directory (os error 2) at path "/usr/local/lib/python3.13/site-packages/pyftms-0.4.10.dist-info/.tmpid2UpO"
Unable to install package pyftms==0.4.10: error: Failed to install: pyftms-0.4.10-py3-none-any.whl (pyftms==0.4.10) Caused by: No such file or directory (os error 2) at path "/usr/local/lib/python3.13/site-packages/pyftms-0.4.10.dist-info/.tmpH063QI"
Unable to install package pyftms==0.4.10: error: Failed to install: pyftms-0.4.10-py3-none-any.whl (pyftms==0.4.10) Caused by: No such file or directory (os error 2) at path "/usr/local/lib/python3.13/site-packages/pyftms-0.4.10.dist-info/.tmp73li9B"

@chkuendig
Copy link
Author

That's an odd error, I didn't change anything related to how that works. Unfortunately I don't use HomeAssistant OS, so I can't reproduce this issue.

I am not able to test it, even installing hassio-ftms using HACS shows next error message.

do you mean even the regular hassio-ftms branch (not my fork)?

@pafernanr
Copy link

pafernanr commented Feb 7, 2026

I was finally able to test last changes.

  • This time only "Training status" was recognized automatically,.

  • After manually add some of the other items the CrossTrainer was added, but the HA logs shows some errors.

  • This one repeats three times

Logger: homeassistant.components.button
Source: helpers/entity_platform.py:680
integration: Button ([documentation](https://www.home-assistant.io/integrations/button), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+button%22))
First occurred: 10:40:39 (8 occurrences)
Last logged: 10:44:34

Error adding entity None for domain button with platform ftms
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 680, in _async_add_entities
    await self._async_add_entity(
        entity, False, entity_registry, config_subentry_id
    )
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 881, in _async_add_entity
    device = dr.async_get(self.hass).async_get_or_create(
        config_entry_id=self.config_entry.entry_id,
        config_subentry_id=config_subentry_id,
        **device_info,
    )
TypeError: DeviceRegistry.async_get_or_create() got an unexpected keyword argument 'fw_version'. Did you mean 'hw_version'?
  • This home shows one time:
Logger: homeassistant
Source: /usr/src/homeassistant/homeassistant/runner.py:238
First occurred: 10:38:21 (399 occurrences)
Last logged: 10:44:48

Error doing job: Exception in callback BleakClientBlueZDBus._register_notify_fd_reader.<locals>.on_data() at /usr/local/lib/python3.13/site-packages/bleak/backends/bluezdbus/client.py:870 (task: None)
Traceback (most recent call last):
  File "/usr/local/lib/python3.13/asyncio/events.py", line 89, in _run
    self._context.run(self._callback, *self._args)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/bleak/backends/bluezdbus/client.py", line 894, in on_data
    callback(bytearray(data))
    ~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/client/backends/updater.py", line 40, in _on_notify
    data_ = self._serializer.deserialize(data)._asdict()
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/serializer.py", line 13, in deserialize
    return self._deserialize(src)
           ~~~~~~~~~~~~~~~~~^^^^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/model.py", line 234, in _deserialize
    return self._cls._deserialize(src)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/model.py", line 146, in _deserialize
    return cls(**cls._deserialize_asdict(src))
                 ~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/models/realtime_data/common.py", line 25, in _deserialize_asdict
    for field, serializer in cls._iter_fields_serializers():
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/model.py", line 117, in _iter_fields_serializers
    serializers = _get_model_serializers(cls)
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/model.py", line 101, in _get_model_serializers
    result[field.name] = _get_model_field_serializer(field)
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/model.py", line 89, in _get_model_field_serializer
    return _get_serializer(type_)
  File "/usr/local/lib/python3.13/site-packages/pyftms/serializer/model.py", line 80, in _get_serializer
    raise TypeError(
        f"Format string for field '{field.name}' is required."
    )
TypeError: Format string for field 'movement_direction' is required.

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