Closed chriselsen closed 3 years ago
@ptx2 I'm a bit stuck on this effort, as I can't find an elegant way to implement this. The actual auto-detection piece is quite simple:
If it's not a Peloton bike, start scanning for BLE:
noble.on('stateChange', function(state) {
if (state === 'poweredOn') {
noble.startScanning(null, false);
console.log('Scanning...');
} else {
noble.stopScanning();
}
});
Next wait for advertisements and check if any of the LocalName matches a supported bike:
noble.on('discover', function(peripheral) {
switch(peripheral.advertisement.localName) {
case 'M3':
// Keiser M3 detected
break;
case 'IC Bike':
// Schwinn IC4 detected
break;
case 'Flywheel 1':
// Flywheel detected
break;
default:
// Keep looking
}
Modify autoDetectBikeClient to create a bike accrodingly.
But the last item is where I'm stuck: I would need to pause the control flow within autoDetectBikeClient until a supported bike is discovered. But that's a no-no in Node and I can't come up with an elegant workaround. Any idea?
Hey @chriselsen, sorry for the delay in reply it's been an unusually busy week.
I think we can solve this by making createBikeClient async and call it like bike = await createBikeClient()
from app.run()
.
The autodetect function could be something like:
async function createAutodetectBikeClient(options, noble) {
// same peloton check as before, but use async calls instead of fs.existsSync
const filters = {
name: (n) => ['Flywheel 1', 'IC Bike', 'M3'].includes(n);
}
let peripheral = await scan(noble, null, filters); // scan() from util/ble-scan.js
switch (peripheral.advertisement.localName) {
case 'M3': return createKeiserBikeClient(options, noble);
// etc.
}
}
Some thoughts:
Hey @chriselsen, do you have time / interest for this one still? If not, I have time today to take a look.
Hey @chriselsen, do you have time / interest for this one still? If not, I have time today to take a look.
I don't have the time right now to look into this. Please go ahead and take a look.
Added in #81.
Currently the default "autodect" bike type can only recognize the peloton and flywheel bike types, but not the newer bike types ic4 and keiser. It would be great if gymnasticon could automatically detect all currently supported bike types, making a manual specification via CLI only necessary in the unlikely event that more than one bike type could be present.
Currently the autodection of bikes is implemented within the autodetectBikeClient function, which discovers a Peleton bike based on the serial interface path and falls back to flywheel otherwise. Instead this function could - after failing to discover the Peleton - fall back to performing a BLE scan until one of the supported bike types are discovered. It should be possible to discover the supported bike types based on the advertisement.localName:
Afterwards the function can return with a corresponding createXXXBikeClient() call.