openrowingmonitor/app/peripherals/PeripheralManager.js

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 }