Skip to content

Add Bodytone DU30-B1D8 Fitness Bike#67

Open
netsoft-ruidias wants to merge 3 commits into
dudanov:mainfrom
netsoft-ruidias:feat/bodytone
Open

Add Bodytone DU30-B1D8 Fitness Bike#67
netsoft-ruidias wants to merge 3 commits into
dudanov:mainfrom
netsoft-ruidias:feat/bodytone

Conversation

@netsoft-ruidias
Copy link
Copy Markdown

This pull request improves the ability of the FTMS device discovery process to correctly identify machine types, especially for devices that do not advertise their type in service data. The main enhancement is a fallback mechanism that inspects GATT characteristics if the machine type cannot be determined from advertisement data. Additionally, the new utility function for GATT-based type detection has been added and exported for broader use.

Enhancements to FTMS device discovery:

  • Added a fallback mechanism in discover_ftms_devices to determine machine type by connecting to the device and inspecting its GATT characteristics when service data is insufficient. This increases compatibility with devices like the Bodytone DU30 that do not include machine type in their advertisements.

New utility for machine type detection:

  • Implemented get_machine_type_from_gatt, an async function that determines the fitness machine type by checking for known FTMS data characteristics on a connected device.
  • Exported get_machine_type_from_gatt in both src/pyftms/client/properties/__init__.py and src/pyftms/client/__init__.py for use elsewhere in the codebase. [1] [2]

Dependency and import updates:

  • Updated imports in several modules to include BleakClient, BleakError, and the new utility function, ensuring all necessary components are available for the new fallback logic. [1] [2]

Copilot AI review requested due to automatic review settings May 18, 2026 17:21
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a GATT-based fallback to FTMS discovery so devices that advertise the FTMS service but omit machine type service data can still be identified.

Changes:

  • Adds get_machine_type_from_gatt to infer machine type from FTMS data characteristics.
  • Uses the new helper as a fallback during discover_ftms_devices.
  • Exports the helper from the properties package and imports it into the client package.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/pyftms/client/properties/machine_type.py Adds GATT characteristic-based machine type detection.
src/pyftms/client/properties/__init__.py Re-exports the new GATT detection helper.
src/pyftms/client/__init__.py Adds discovery fallback logic that connects to devices lacking machine type service data.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +124 to +130
async with BleakClient(
dev, services=[FTMS_UUID]
) as cli:
machine_type = await get_machine_type_from_gatt(
cli
)
except (BleakError, NotFitnessMachineError, OSError):
Comment on lines +130 to +136
except (BleakError, NotFitnessMachineError, OSError):
_LOGGER.debug(
"Could not determine machine type for '%s' "
"via GATT fallback.",
dev.address,
)
continue
if cli.services.get_characteristic(uuid) is not None:
return machine_type

raise NotFitnessMachineError()
Comment on lines +13 to +15
MachineType,
get_machine_type_from_gatt,
get_machine_type_from_service_data
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from bleak.exc import BleakDeviceNotFoundError
from bleak.exc import BleakError, BleakDeviceNotFoundError
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

Comment on lines +13 to +15
MachineType,
get_machine_type_from_gatt,
get_machine_type_from_service_data
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from bleak.exc import BleakDeviceNotFoundError
from bleak.exc import BleakError, BleakDeviceNotFoundError
Comment on lines 126 to +131
except NotFitnessMachineError:
continue
# The device advertises the FTMS service UUID but does
# not include machine type in its service data (e.g.
# Bodytone DU30). Fall back to GATT characteristic
# inspection by briefly connecting to the device.
try:
if cli.services.get_characteristic(uuid) is not None:
return machine_type

raise NotFitnessMachineError()
Comment on lines +131 to +134
try:
async with BleakClient(
dev, services=[FTMS_UUID]
) as cli:
# advertise the FTMS UUID in service_uuids but provide no service data, so
# they would be silently dropped. We therefore scan for all BLE devices
# and filter manually.
async with BleakScanner(**kwargs) as scanner:
@netsoft-ruidias
Copy link
Copy Markdown
Author

Discovery result:

(.venv) homeserver:~/python-pyftms$ python -m pyftms
Scanning for available FTMS devices...
1. INDOOR_BIKE: name: DU30-B1D8, address: 24:00:0C:A0:3B:98

Connection to INDOOR_BIKE: name: DU30-B1D8, address: 24:00:0C:A0:3B:98
 1. Device Info: {}
 2. Supported settings: ['target_resistance', 'target_power']
 3. Supported ranges: {'target_resistance': SettingRange(min_value=0, max_value=32.0, step=1.0), 'target_power': SettingRange(min_value=0, max_value=999, step=1)}
 4. Supported properties: ['speed_instant', 'speed_average', 'cadence_instant', 'cadence_average', 'distance_total', 'resistance_level', 'power_instant', 'power_average', 'energy_total', 'energy_per_hour', 'energy_per_minute', 'heart_rate', 'time_elapsed', 'training_status']
 5. Available properties: ['speed_instant', 'speed_average', 'cadence_instant', 'cadence_average', 'distance_total', 'resistance_level', 'power_instant', 'power_average', 'energy_total', 'energy_per_hour', 'energy_per_minute', 'heart_rate', 'metabolic_equivalent', 'time_elapsed', 'time_remaining', 'training_status']

Done.

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