Skip to content

A Flutter library for interacting with fitness equipment that uses the CSAFE protocol (such as Concept2 rowing machines)

License

Notifications You must be signed in to change notification settings

OpenRowingCommunity/csafe-fitness

Repository files navigation

CSAFE Fitness Library

This is a dart library that implements the CSAFE Protocol Framework used by fitness machines.

This CSAFE protocol is used in at least some devices made by:

Why was this library developed?

This library was originally developed to support a flutter Bluetooth library for Concept2 fitness equipment. However, because many other fitness equipment manufacturers are likely to use CSAFE, it seeemed like a useful thing to break out into a separate dart-only library in case someone else is able to make use of it for a different project supporting different fitness equipment.

Features

Currently this library has the ability to:

  • Handle the most basic aspects of the CSAFE framing protocols
  • Send CSAFE commands and receive the responses to them
  • Represent CSAFE data types as Dart classes
  • Provide objects to allow custom commands to be created beyond those present in the standard
  • limit how many bytes are written to a device at a time to avoid exceeding limits

Some of its current limitations are:

  • there has not yet been a lot of focus on handling unsolicited CSAFE frames sent by a device
  • some commands, particularly for adjusting configuration parameters, are not yet added/supported
  • there may potentially be timing issues with regard to matching commands with their responses if too many commands are sent too quickly or of a device responds to a command out of order

Usage

To use this library, you will need to create a read function and a write function that can either accept some bytes and send them to the device you want to communicate with, or receive some bytes from that device using a Stream.

To set up Csafe, just import the Csafe class and provide it with your read and write functions:

import 'package:csafe_fitness/csafe_fitness.dart';
// Create a Csafe instance
Csafe csafe = Csafe(myReadFunction, myWriteFunction);

A full example with fake read and write commands is provided in the example folder.

The Csafe class

The Csafe class is the core of the command processing as it contains the code to handle new data coming in from the read method's Stream as well as grouping and sending commands to the device. This class exposes a sendCommands() method where you can send either predefined commands, or ones you create yourself.

//Send a predefined command to tell the device to go to the inUse state.
csafe.sendCommands([cmdGoInUse]);

// Create a custom command with a payload containing 2 bytes
CsafeCommand customCommand =
      CsafeCommand.long(0xAB, 2, Uint8List.fromList([0xBE, 0xEF]).asCsafe());

// Send the custom command
csafe.sendCommands([customCommand]);

This sendCommands function returns a Future so you can access the results of each command in the order that you sent them.

List<CsafeCommandResponse> responses = await csafe.sendCommands([customCommand]);

//or you can use .then!

// send the command. You get a future for when the results come back!
csafe.sendCommands([customCommand]).then((responses) => {
	//your handling of responses goes here
	for (response in responses) {
		//...
	}
});

Vocabulary

Where possible, this library tries to re-use language from the CSAFE specification.

One notable exception to this is that this library will use the term "server" instead of "slave" to represent the fitness device providing the data and the term "client" instead of "master" to represent the device that is requesting the data.

Unit Testing

Tests can be run with dart test.

Coverage reports can be created with the following commands:

dart test --coverage=./coverage
dart run coverage:format_coverage --packages=.packages --report-on=lib --lcov -o ./coverage/lcov.info -i ./coverage # create the lcov.info file
genhtml -o ./coverage/report ./coverage/lcov.info # generate the report

These lines have also been added to a shell script located in scripts/coveragereport.sh.

How it works

If you want to learn more about how it works, check out the API documentation

Assumptions made about the spec

This library assumes that, when a Csafe Frame is sent containing multiple commands, the responses to those commands will also be contained in a single frame.

This library also relies quite heavily on the order in which commands are responded to (and the order of responses within a frame) in order to match responses with the commands that they should go with. This is currently one area where improvement is needed in the future.

About

A Flutter library for interacting with fitness equipment that uses the CSAFE protocol (such as Concept2 rowing machines)

Resources

License

Stars

Watchers

Forks

Packages

No packages published