Skip to content
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

Using Keiser M3i in gym/multi bikes #84

Open
nealjane opened this issue May 24, 2021 · 14 comments
Open

Using Keiser M3i in gym/multi bikes #84

nealjane opened this issue May 24, 2021 · 14 comments

Comments

@nealjane
Copy link

nealjane commented May 24, 2021

@ptx2 @chriselsen
gymnasticon has been working flawlessly since you added Keiser (so many thanks for the addition. 🙏)

Keiser M3i is a fairly common bike in gyms, (some of others may also be?) and I’ve been trying to think of a way that Gymnasticon could be used in these locations - With the issue of multiple bikes to pair to?

So simplest solution I could think of was to

  • get gymnasticon to only pair with a Bike with a certain low cadence/ or low power perhaps? - was thinking maybe only connect to bike with a cadence of eg less than 25 say??

could this be added as an option in the setup ‘gymnasticon.json’ file perhaps??

@cagnulein
Copy link

cagnulein commented May 24, 2021 via email

@nealjane
Copy link
Author

nealjane commented May 24, 2021

Don’t want qd, otherwise I’d have used qd thanks…🙄

@cagnulein
Copy link

cagnulein commented May 24, 2021 via email

@aortizdp
Copy link

aortizdp commented Jun 1, 2021

Hi @nealjane,

Did you try to modify the file gymnasticon.service at path "/etc/systemd/system" to change the parameter "Description=Gymnasticon" to something as "Description=M3i-bike-1" and "Description=M3i-bike-2".....

In theory the Zwift and other apps should see different bikes, you just need to assing the bike number (1,2,3...) at the gym to the corresponding raspberry pi you defined (1,2,3...).

I will test later at home but I think it should work.

@nealjane
Copy link
Author

nealjane commented Jun 1, 2021

@aortizdp - I don’t think that'll work.
I’m assuming whatever needs changing , it needs to be in Keiser.js file - as that’s the file that scans/connects to the bike - prior to forwarding the stats to gymnasticon.

@aortizdp
Copy link

aortizdp commented Jun 2, 2021

Hi @nealjane,
You were right but finally modifying the
/etc/gymnasticon.json
{
"bike": "keiser",
"server-name": "M3i-1"
}
You may assign one different server-name per bike.

The main problem is how to link the raspberry to one unique bike (in a gym will be several), I've seen on flywheel bike you may link to one unique Bluetooth address but this is not the case for keiser bikes.

I think is needed another parameter to force to search for one selected bluetooth bike address in the configuration file.

Hope it helps,
Alber

@aortizdp
Copy link

aortizdp commented Jun 2, 2021

I forgot to mention I tested with FulGaz and bike was presented as "M3i-1" instead as previous "Gymnasticon" name.

The question is this is only working at
"APP - Raspberry" side, still needs to be solved "bike - Raspberry" side which solution seems to be to force the Bluetooth lookup to the bike.

Or either to reduce hci0 power to link to closest bike (keiser console) or to force to look to one bike Bluetooth mac both should work.

@djwasser
Copy link

djwasser commented Jun 9, 2021

In my gym each of the Keiser bikes have the bike id set to a unique number (1, 2, 3, 4, 5,.... 25) for the 25 bikes and don't particularly like clients changing them. If one always uses the same bike one could hard-code the bike id. But then you might have to kick someone off "your" bike ;-)

Perhaps a another option would be for the Gymnasticon app on startup to look for an M3i transmitting in "summary" mode versus real-time mode. Summary mode is activated when one stops peddling (I think you need to peddle for at least a minute before stopping for the summary mode to activate). The M3i will transmit summary data for about a minute or so and then stop transmitting altogether. So one could get on a bike, peddle for a minute, start/powerup Gymnasticon and stop peddling. It is then pretty likely the bike you are on is the only one transmitting summary info. Gymnasticon could then find the bike transmitting summary stats, connect to it and then start processing real-time data once you start peddling again.

@aortizdp
Copy link

aortizdp commented Jun 9, 2021

Hi @djwasser sorry but I don't get what you mean.

I was meaning to fit one raspberry per bike assigned to each bike number:
Bike1 - Raspberry1 (server-name bike1)
Bike2 - Raspberry2 (server-name bike2)
..
Bike25 - Raspberry25 (server-name bike25)

When you get into the bike 5, start pedaling, open on your tablet app (ex Fulgaz) and select bike 5 on the list select power and cadence and go.

Ideal would be to get bike Id from the console (you can assign an I'd per bike in m3i console).

My question is how to link each raspberry Bluetooth to only listen to one bike Bluetooth mac address. Maybe reducing power of hci0 and set raspberry very close to m3i console.

I think Intelligence Cycling which is prepared to that without gymnasticon do this as is prepared for gym classes.

@nealjane
Copy link
Author

nealjane commented Jun 9, 2021

@djwasser - connecting only at summary mode yes, that’s the type of thing would be workable I imagine!👍🏻

@aortizdp - think what you’re after is having say 25 pis for 25 Keiser bikes setup in a gym,
Ideally I guess you want the gymnasticon.Json file to be edited to allow for ‘say’ - connect to ‘Keiser’ , and then specific bike no ‘001’, next pi to have ‘002’ etc up to 25 in your case.

I guess gymnasticon is currently setup to just find ‘M3’ name which is found in the Keiser broadcast packet, in this packet is the additional info that’s required ‘equipment id’ - see attached. I’m assuming this all needs to be added to the ‘Keiser.js’ in src/bikes - lines 7-17, needs something along lines of
‘Keiser..._equip Id = 5; // equipment Id 000-200’ - this is all beyond me though..! And then this all needs to be connected to gymnasticon.json to control etc...

@nealjane
Copy link
Author

nealjane commented Jun 9, 2021

see this - https://dev.keiser.com/mseries/direct/#advertising-data-structure

IMG_1598

@aortizdp
Copy link

Thanks @nealjane this is very useful information I was not aware, I will do some tests with that to see if I can add a parameter to force Equipment ID in the gymnasticon.json file.

In the documentation there's also the Data Type attribute which could be 'real' or 'review' modes... I guess this what @djwasser wants with 'summary' mode.

@nealjane
Copy link
Author

So I thinks it’s pretty clear what we’re needing to be able to use this in a gym environment-

@aortizdp - would like to be able to setup pi’s to connect to a single specific bike number/I’d (using the ‘equipment Id’ which is in the data stream)- this could ideally be stated in the gymnasticon.json file.
Me (nealjane) - thinking more for users who take gymnasticon pi with them to gym (with pi plugged into a usb battery)- trying to connect to a single bike (possibly different Id each time) - @djwasser suggestion of being able to select the bike that’s currently in ‘review’ mode which is also in the data stream sounds like a great solution! This could also be selected on the gymnasticon file as well.

Unfortunately, I have no skills in coding. @chriselsen did all the M3i work (and it looks like he’s busy as he’s not ben around much recently) @ptx2 unfortunately hasn’t been here much either - so I think we’re stuck for now - who knows, maybe they’ll get round to it - I would imagine it’s quite clear what we’re suggesting.

@aortizdp
Copy link

@nealjane I started to looking into code from the information you provided to see if is possible, from what I see it is... but I can do only on my spare time which is not much at the moment.
Let me some time, and to do some tests, I never programmed nodeJS but I did in Javascript in past and is quite similar.

What I see at first sight:

  1. Connect to specific bike: createFilterName(name) (name is just hardcoded to 'M3') function could be easily replaced to createFilter(name, address) (address is bluetooth address) where we can force bluetooth address easily. But I want to assign it from the EquipmentID (no the bluetooth address, much simpler) which is inside the data-stream, a bit more complex to read than bluetooth address which is just in the header.

  2. To detect change between 'review' or 'real' codes and to link only on 'review' mode is possible too but it will take longer as it modifies quite a lot the behavior of keiser.js I will try to do this too but I think it will take longer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants