Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions src/pyftms/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from collections.abc import AsyncIterator
from typing import Any

from bleak import BleakScanner
from bleak import BleakClient, BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from bleak.exc import BleakDeviceNotFoundError
from bleak.exc import BleakError, BleakDeviceNotFoundError
Comment thread
netsoft-ruidias marked this conversation as resolved.
Comment thread
netsoft-ruidias marked this conversation as resolved.
from bleak.uuids import normalize_uuid_str

from .backends import (
Expand All @@ -32,6 +32,7 @@
MachineType,
MovementDirection,
SettingRange,
get_machine_type_from_gatt,
get_machine_type_from_service_data,
)

Expand Down Expand Up @@ -112,7 +113,27 @@ async def discover_ftms_devices(
machine_type = get_machine_type_from_service_data(adv)

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.
if normalize_uuid_str(FTMS_UUID) not in adv.service_uuids:
continue

try:
Comment on lines 126 to +131
async with BleakClient(
dev, services=[FTMS_UUID]
) as cli:
Comment on lines +131 to +134
machine_type = await get_machine_type_from_gatt(
cli
)
except (BleakError, NotFitnessMachineError, OSError):
Comment thread
netsoft-ruidias marked this conversation as resolved.
_LOGGER.debug(
"Could not determine machine type for '%s' "
"via GATT fallback.",
dev.address,
)
continue
Comment on lines +138 to +144

devices.add(dev.address)

Expand Down
7 changes: 6 additions & 1 deletion src/pyftms/client/properties/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
SettingRange,
read_features,
)
from .machine_type import MachineType, get_machine_type_from_service_data
from .machine_type import (
MachineType,
get_machine_type_from_gatt,
get_machine_type_from_service_data
Comment thread
netsoft-ruidias marked this conversation as resolved.
Comment thread
netsoft-ruidias marked this conversation as resolved.
)

__all__ = [
"DeviceInfo",
"get_machine_type_from_gatt",
"get_machine_type_from_service_data",
"MachineFeatures",
"MachineSettings",
Expand Down
37 changes: 36 additions & 1 deletion src/pyftms/client/properties/machine_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
import operator
from enum import Flag, auto

from bleak import BleakClient
from bleak.backends.scanner import AdvertisementData
from bleak.uuids import normalize_uuid_str

from ..const import FTMS_UUID
from ..const import (
CROSS_TRAINER_DATA_UUID,
FTMS_UUID,
INDOOR_BIKE_DATA_UUID,
ROWER_DATA_UUID,
TREADMILL_DATA_UUID,
)
from ..errors import NotFitnessMachineError


Expand Down Expand Up @@ -79,3 +86,31 @@ def get_machine_type_from_service_data(
return mt

raise NotFitnessMachineError(data)


async def get_machine_type_from_gatt(cli: BleakClient) -> MachineType:
"""Determines fitness machine type from connected GATT characteristics.

Used as a fallback when the device advertises the FTMS service UUID but
does not include machine type information in its advertisement service data
(e.g. Bodytone DU30).

Parameters:
cli: Connected `BleakClient` instance with FTMS service discovered.

Returns:
Fitness machine type.
"""

_UUID_TO_TYPE = (
(TREADMILL_DATA_UUID, MachineType.TREADMILL),
(CROSS_TRAINER_DATA_UUID, MachineType.CROSS_TRAINER),
(ROWER_DATA_UUID, MachineType.ROWER),
(INDOOR_BIKE_DATA_UUID, MachineType.INDOOR_BIKE),
)

for uuid, machine_type in _UUID_TO_TYPE:
if cli.services.get_characteristic(uuid) is not None:
return machine_type

raise NotFitnessMachineError()
Comment thread
netsoft-ruidias marked this conversation as resolved.
Comment thread
netsoft-ruidias marked this conversation as resolved.
Loading