2

I try to build a smart home trainer. at this moment, it is connected with Zwift with the Fitness Machine Service. I can send to zwift Power and Cadence and i can play. Now i try to add the control point (one of the characteristics included in FTMS) But i cannot finish the transaction described in the specifications. I think it's not very easy. The xml file which describe the control point is empty! There is no complete sequence diagram of flow chart. at this moment, i can receive a write event from zwift into the control point. First zwift send 0x7 and then 0x0 After that...again write 7 into the control point and then 0 I try to answer (indicate) 0x80, 0x801, 0x0180 for the 2 bytes needed (cf specification) I think i don't really understand the specification Have you somme informations to help me? any flow chart, sequence diagram for the resistance level update? do you confirme i juste need to indicate 2 bytes to answer to a write from zwift into the control point?

@Yonkee

HTDIYMan
  • 21
  • 2

1 Answers1

1

I agree that it's a bit weird that the Control Point XML is empty, since the FTMS specification PDF doesn't give a complete list of e.g. what to expect as parameters to the various commands.

However, I've managed to create an implementation that supports some of the use cases you might be interested in. It currently supports setting target resistance and power, but not the simulation parameters you will need for the regular simulation mode in Zwift. You can find this implementation on github. It's not complete, and I just handle a few commands there, but you can grasp the concept from the code.

I wrote this using the information I could find online, basically the Fitness Machine Specification and the different GATT Characteristics Specifications.

When an app like Zwift write to the CP it's an OP Code optionally followed by parameters, you should reply with the OP Code 0x80 (Response Code) followed by the OP Code that the reply is for, optionally followed by parameters.

In the case of OP Code 0x00 (Request Control) you should therefore reply with: 0x80, 0x00, 0x01. The last 0x01 is the result code for "Success".

In the case of OP Code 0x07 (Start/Resume), you should reply with: 0x80, 0x07, 0x01. Assuming you consider the request successful, the other possible responses are detailed in Table 4.24 of the FTMS Specification PDF.

On command you should look into is OP Code 0x11. When running Zwift in "non-workout mode", so just the normal mode, Zwift will use OP Code 0x11 followed by a set of simulation parameters: Wind Speed, Grade, Rolling resistance coeff and Wind resistance coeff. See the "4.16.2.18 Set Indoor Bike Simulation Parameters Procedure" of the PDF for details on the format of those parameters.

I hope this enables you to proceed. Happy hacking!

Erik Botö
  • 966
  • 7
  • 11
  • when you say "replay", do you mean the response replay or just write a new value to control point characteristic on server side (for example 0x80, 0x00, 0x01 like confirmation after request control package (0x0))? I'm a bit confused, because zwift just continue sends 0x0. 0x7, 0x11.. again and again and no ether of my answers can stop first two commands. I don't see reset and stop commands from Zwift side. Your implementation doesn't use stop/start too. Could you please advice why? – Georgiy Chebotarev Nov 29 '21 at 14:00
  • 1
    I think the start/stop is mostly interesting if you're sending some "session metrics" like total distance, average cadence etc. My example repo is just a very minimal example to help people getting started, since I myself had a bit of trouble when I wanted to under FTMS first, so therefore it's probably lacking some things that maybe should be ideally be there. And yes, I believe Zwift ignores the simulation flag, but if you start a "workout" in ERG-mode it will send a power target instead. – Erik Botö Nov 30 '21 at 18:17