Skip to content

Commit

Permalink
add control point commands, read properties and rizer example (#38)
Browse files Browse the repository at this point in the history
* fix control point opcodes

* add control point commands

* add target setting features

* add parse_target_setting_features

* add rizer service and example

* make sure parameters are integer or list

* update example for target setting features and simulation parameters

* fix linting

* add pylint exception
  • Loading branch information
bytosaur authored Apr 26, 2024
1 parent a5998eb commit 6ddc15c
Show file tree
Hide file tree
Showing 7 changed files with 473 additions and 55 deletions.
106 changes: 65 additions & 41 deletions examples/fitness_machine_service_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,49 @@ async def run(address):
async with BleakClient(address, timeout=10) as client:
ftms = FitnessMachineService(client)

# Print all 'read' characteristics
# Print 'read' characteristics

supported_resistance_level_range = (
await ftms.get_supported_resistance_level_range()
)
### Fitness Machine Features
fitness_machine_features, target_setting_features = await ftms.get_fitness_machine_feature()
fitness_machine_features = fitness_machine_features._asdict()
target_setting_features = target_setting_features._asdict()

print("Supported resistance level range:")
print(supported_resistance_level_range)
print()

max_resistance = supported_resistance_level_range.maximum_resistance
def print_features(features):
for key, value in features.items():
print(f"{key}: {value}")
print()

print("Fitness machine feature:")
print_features(fitness_machine_features)

supported_power_range = await ftms.get_supported_power_range()
print("Target setting features:")
print_features(target_setting_features)

print("Supported power range:")
print(supported_power_range)
print()
print(target_setting_features)

max_power = supported_power_range.maximum_power

fitness_machine_feature = await ftms.get_fitness_machine_feature()
if target_setting_features["resistance_target_setting_supported"]:
supported_resistance_level_range = (
await ftms.get_supported_resistance_level_range()
)
print("Supported resistance level range:")
print(supported_resistance_level_range)
print()
max_resistance = supported_resistance_level_range.maximum_resistance

print("Fitness machine feature:")
print(fitness_machine_feature)
print()
if target_setting_features["power_target_setting_supported"]:
supported_power_range = await ftms.get_supported_power_range()
print("Supported power range:")
print(supported_power_range)
print()
max_power = supported_power_range.maximum_power

# Start receiving and printing 'notify' characteristics
def print_indoor_bike_data(data):
print("Received indoor bike data:")
print(data)
print()

# Start receiving and printing 'notify' characteristics
ftms.set_indoor_bike_data_handler(print_indoor_bike_data)
await ftms.enable_indoor_bike_data_notify()

Expand Down Expand Up @@ -73,36 +84,49 @@ def print_control_point_response(message):
# 3. (recommended) 'write' a reset command
await ftms.reset()

print(
"Setting target resistance level to 25 percent of maximum resistance level..."
)
await ftms.set_target_resistance_level(max_resistance * 0.25)
# Set target resistance level
if target_setting_features["resistance_target_setting_supported"]:
print("Setting target resistance level to 25 percent of maximum resistance level...")
await ftms.set_target_resistance_level(max_resistance * 0.25)

await asyncio.sleep(5)
await asyncio.sleep(5)

print(
"Increasing target resistance level to 50 percent of maximum resistance level..."
)
await ftms.set_target_resistance_level(max_resistance * 0.5)
print("Increasing target resistance level to 50 percent of maximum resistance level...")
await ftms.set_target_resistance_level(max_resistance * 0.5)

await asyncio.sleep(5)
await asyncio.sleep(5)

# Reset target resistance level
print("Resetting target resistance level...")
# Reset target resistance level
print("Resetting target resistance level...")

await ftms.reset()
await ftms.reset()

power_level = 4 / 100 * max_power
print(f"Increasing target power to 4 percent of maximum power ({power_level}W).")
print("The trainer will automatically adjust resistance based on your leg speed.")
print(f"Try pedaling above {power_level}W to feel decreasing resistance, and vice versa.")
await ftms.set_target_power(power_level)
# Set target power
if target_setting_features["power_target_setting_supported"]:
power_level = 4 / 100 * max_power
print(f"Increasing target power to 4 percent of maximum power ({power_level}W).")
print("The trainer will automatically adjust resistance based on your leg speed.")
print(f"Try pedaling above {power_level}W to feel decreasing resistance, and vice versa.")
await ftms.set_target_power(power_level)

await asyncio.sleep(30)
await asyncio.sleep(30)

# Reset
print("Resetting target power...")
await ftms.reset()
# Reset
print("Resetting target power...")
await ftms.reset()

# Set simulation parameters
if target_setting_features["indoor_bike_simulation_parameters_supported"]:
print("Setting indoor bike simulation parameters to 0")
await ftms.set_simulation_parameters(0, 0, 0, 0)
await asyncio.sleep(5)
print("Setting indoor bike simulation grade to 10%")
print("if connected to a compatible machine (like elite rizer), this should set its grade to +10%")
await ftms.set_simulation_parameters(0, 1000, 0, 0)
await asyncio.sleep(5)

print("Resetting indoor bike simulation parameters...")
await ftms.reset()


if __name__ == "__main__":
Expand Down
34 changes: 34 additions & 0 deletions examples/rizer_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import asyncio
from bleak import BleakClient

from pycycling.rizer import Rizer

""" make sure the rizer is connected to a fitness machine otherwise the steering angle will not be transmitted """


async def run(address):
async with BleakClient(address) as client:
def steering_handler(steering_angle):
print(steering_angle)

await client.is_connected()
rizer = Rizer(client)
rizer.set_steering_measurement_callback(steering_handler)
await rizer.enable_steering_measurement_notifications()
await rizer.set_transmission_rate(0) # 8 Hz
await asyncio.sleep(4)
await rizer.set_transmission_rate(1) # 16 Hz
await asyncio.sleep(4)
await rizer.set_transmission_rate(2) # 32 Hz
await asyncio.sleep(4)
# recalibrate the rizer
#await rizer.set_center()

if __name__ == "__main__":
import os

os.environ["PYTHONASYNCIODEBUG"] = str(1)

device_address = "YOUR RIZER ADDRESS HERE"
loop = asyncio.get_event_loop()
loop.run_until_complete(run(device_address))
Loading

0 comments on commit 6ddc15c

Please sign in to comment.