135 lines
3.5 KiB
JavaScript
135 lines
3.5 KiB
JavaScript
'use strict'
|
|
/*
|
|
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
|
|
|
This manager creates the different Bluetooth Low Energy (BLE) Peripherals and allows
|
|
switching between them
|
|
*/
|
|
import config from '../tools/ConfigManager.js'
|
|
import { createFtmsPeripheral } from './ble/FtmsPeripheral.js'
|
|
import { createPm5Peripheral } from './ble/Pm5Peripheral.js'
|
|
import log from 'loglevel'
|
|
import EventEmitter from 'node:events'
|
|
import { createCpsPeripheral } from './ble/CpsPeripheral.js'
|
|
import { createCscPeripheral } from './ble/CscPeripheral.js'
|
|
import child_process from 'child_process'
|
|
import AntManager from './ant/AntManager.js'
|
|
import { createAntHrmPeripheral } from './ant/HrmPeripheral.js'
|
|
|
|
const modes = ['FTMS', 'FTMSBIKE', 'PM5', 'CSC', 'CPS']
|
|
function createPeripheralManager () {
|
|
const emitter = new EventEmitter()
|
|
let peripheral
|
|
let mode
|
|
|
|
createPeripheral(config.bluetoothMode)
|
|
|
|
function getPeripheral () {
|
|
return peripheral
|
|
}
|
|
|
|
function getPeripheralMode () {
|
|
return mode
|
|
}
|
|
|
|
function switchPeripheralMode (newMode) {
|
|
// if now mode was passed, select the next one from the list
|
|
if (newMode === undefined) {
|
|
newMode = modes[(modes.indexOf(mode) + 1) % modes.length]
|
|
}
|
|
createPeripheral(newMode)
|
|
}
|
|
|
|
function notifyMetrics (type, metrics) {
|
|
peripheral.notifyData(type, metrics)
|
|
}
|
|
|
|
function notifyStatus (status) {
|
|
peripheral.notifyStatus(status)
|
|
}
|
|
|
|
async function createPeripheral (newMode) {
|
|
if (peripheral) {
|
|
await peripheral.destroy()
|
|
}
|
|
|
|
switch (newMode) {
|
|
case 'PM5':
|
|
log.info('bluetooth profile: Concept2 PM5')
|
|
peripheral = createPm5Peripheral(controlCallback)
|
|
mode = 'PM5'
|
|
break
|
|
|
|
case 'FTMSBIKE':
|
|
log.info('bluetooth profile: FTMS Indoor Bike')
|
|
peripheral = createFtmsPeripheral(controlCallback, {
|
|
simulateIndoorBike: true
|
|
})
|
|
mode = 'FTMSBIKE'
|
|
break
|
|
case 'CSC':
|
|
log.info('bluetooth profile: Cycling Speed and Cadence')
|
|
peripheral = createCscPeripheral()
|
|
mode = 'CSC'
|
|
break
|
|
case 'CPS':
|
|
log.info('bluetooth profile: Cycling Power Meter')
|
|
peripheral = createCpsPeripheral()
|
|
mode = 'CPS'
|
|
break
|
|
|
|
case 'FTMS':
|
|
default:
|
|
log.info('bluetooth profile: FTMS Rower')
|
|
peripheral = createFtmsPeripheral(controlCallback, {
|
|
simulateIndoorBike: false
|
|
})
|
|
mode = 'FTMS'
|
|
break
|
|
}
|
|
peripheral.triggerAdvertising()
|
|
|
|
emitter.emit('control', {
|
|
req: {
|
|
name: 'peripheralMode',
|
|
peripheralMode: mode
|
|
}
|
|
})
|
|
}
|
|
|
|
function startBleHeartRateService () {
|
|
const hrmPeripheral = child_process.fork('./app/peripherals/ble/HrmPeripheral.js')
|
|
hrmPeripheral.on('message', (heartRateMeasurement) => {
|
|
emitter.emit('heartRateBleMeasurement', heartRateMeasurement)
|
|
})
|
|
}
|
|
|
|
function startAntHeartRateService () {
|
|
if (!this._antManager) {
|
|
this._antManager = new AntManager()
|
|
}
|
|
|
|
const antHrm = createAntHrmPeripheral(this._antManager)
|
|
|
|
antHrm.on('heartRateMeasurement', (heartRateMeasurement) => {
|
|
emitter.emit('heartRateAntMeasurement', heartRateMeasurement)
|
|
})
|
|
}
|
|
|
|
function controlCallback (event) {
|
|
emitter.emit('control', event)
|
|
}
|
|
|
|
return Object.assign(emitter, {
|
|
startAntHeartRateService,
|
|
startBleHeartRateService,
|
|
getPeripheral,
|
|
getPeripheralMode,
|
|
switchPeripheralMode,
|
|
notifyMetrics,
|
|
notifyStatus
|
|
})
|
|
}
|
|
|
|
export { createPeripheralManager }
|