-
-
Notifications
You must be signed in to change notification settings - Fork 5
Add Legacy Stationary Bike #124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
StephenHidem
merged 3 commits into
master
from
121-stationary-bike-fitness-equipment-type-0x15
Apr 14, 2026
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
AntPlus.UnitTests/DeviceProfiles/FitnessEquipment/StationaryBikeTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| using Microsoft.Extensions.Logging; | ||
| using Moq; | ||
| using SmallEarthTech.AntPlus.DeviceProfiles.FitnessEquipment; | ||
| using SmallEarthTech.AntRadioInterface; | ||
| using Xunit; | ||
|
|
||
| namespace AntPlus.UnitTests.DeviceProfiles.FitnessEquipment | ||
| { | ||
| public class StationaryBikeTests | ||
| { | ||
| private readonly StationaryBike _stationaryBike; | ||
|
|
||
| public StationaryBikeTests() | ||
| { | ||
| _stationaryBike = new(new ChannelId(0), Mock.Of<IAntChannel>(), Mock.Of<ILogger<StationaryBike>>(), It.IsAny<int>()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Parse_InstantaneousCadenceAndPower_Matches() | ||
| { | ||
| // Arrange | ||
| byte[] dataPage = [0x15, 0xFF, 0xFF, 0xFF, 60, 150, 0, 0]; | ||
|
|
||
| // Act | ||
| _stationaryBike.Parse(dataPage); | ||
|
|
||
| // Assert | ||
| Assert.Equal(60, _stationaryBike.Cadence); | ||
| Assert.Equal(150, _stationaryBike.InstantaneousPower); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Parse_PowerHighValue_Correct() | ||
| { | ||
| // Arrange - 274W = 0x0112 | ||
| byte[] dataPage = [0x15, 0xFF, 0xFF, 0xFF, 87, 0x12, 0x01, 0]; | ||
|
StephenHidem marked this conversation as resolved.
|
||
|
|
||
| // Act | ||
| _stationaryBike.Parse(dataPage); | ||
|
|
||
| // Assert | ||
| Assert.Equal(87, _stationaryBike.Cadence); | ||
| Assert.Equal(274, _stationaryBike.InstantaneousPower); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void Parse_CommonDataPage_Handled() | ||
| { | ||
| // Arrange - common page 0x50 (Manufacturer Info) | ||
| byte[] dataPage = [0x50, 0xFF, 0xFF, 16, 32, 0, 100, 0]; | ||
|
|
||
| // Act & Assert - should not throw | ||
| _stationaryBike.Parse(dataPage); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ToString_ReturnsExpected() | ||
| { | ||
| Assert.Equal("Stationary Bike", _stationaryBike.ToString()); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| using CommunityToolkit.Mvvm.ComponentModel; | ||
| using Microsoft.Extensions.Logging; | ||
| using SmallEarthTech.AntRadioInterface; | ||
| using System; | ||
|
|
||
| namespace SmallEarthTech.AntPlus.DeviceProfiles.FitnessEquipment | ||
| { | ||
| /// <summary> | ||
| /// This class supports the ANT+ Legacy Stationary Bike device profile. It extends the FitnessEquipment base class to provide specific properties and parsing logic for stationary bike data pages, including cadence and instantaneous power. | ||
| /// </summary> | ||
| public partial class StationaryBike : FitnessEquipment | ||
| { | ||
| /// <summary>Gets the instantaneous pedaling cadence in revolutions per minute.</summary> | ||
| /// <value>The instantaneous cadence. 255 (0xFF) indicates invalid.</value> | ||
| [ObservableProperty] | ||
| private byte cadence; | ||
| /// <summary>Gets the instantaneous power in watts.</summary> | ||
| /// <value>The instantaneous power. 65535 (0xFFFF) indicates invalid.</value> | ||
|
StephenHidem marked this conversation as resolved.
|
||
| [ObservableProperty] | ||
| private int instantaneousPower; | ||
|
|
||
| /// <summary>Initializes a new instance of the <see cref="StationaryBike" /> class.</summary> | ||
| /// <inheritdoc cref="AntDevice(ChannelId, IAntChannel, ILogger, int)"/> | ||
| public StationaryBike(ChannelId channelId, IAntChannel antChannel, ILogger logger, int timeout) : base(channelId, antChannel, logger, timeout) | ||
| { | ||
| } | ||
|
|
||
| /// <summary>Initializes a new instance of the <see cref="StationaryBike" /> class.</summary> | ||
| /// <inheritdoc cref="AntDevice(ChannelId, IAntChannel, ILogger, TimeoutOptions?)"/> | ||
| public StationaryBike(ChannelId channelId, IAntChannel antChannel, ILogger logger, TimeoutOptions? timeoutOptions) : base(channelId, antChannel, logger, timeoutOptions) | ||
| { | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Parses the specified data page and updates the relevant properties. | ||
| /// </summary> | ||
| /// <remarks>If the data page represents stationary bike data, the method extracts cadence and | ||
| /// instantaneous power values. For other data page types, common data page parsing is delegated to the | ||
| /// CommonDataPages class. The method does not process the page if it has already been handled.</remarks> | ||
| /// <param name="dataPage">A byte array containing the data page to parse.</param> | ||
| override public void Parse(byte[] dataPage) | ||
| { | ||
| base.Parse(dataPage); | ||
| if (handledPage) return; | ||
|
|
||
| if ((DataPage)dataPage[0] == DataPage.StationaryBikeData) | ||
| { | ||
| HandleFEState(dataPage); | ||
| Cadence = dataPage[4]; | ||
| InstantaneousPower = BitConverter.ToInt16(dataPage, 5); | ||
|
StephenHidem marked this conversation as resolved.
|
||
| } | ||
| else | ||
| { | ||
| CommonDataPages.ParseCommonDataPage(dataPage); | ||
|
StephenHidem marked this conversation as resolved.
|
||
| } | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public override string ToString() => "Stationary Bike"; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.