openrowingmonitor/app/peripherals/PeripheralManager.js

188 lines
4.7 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 AntManager from './ant/AntManager.js'
import { createAntHrmPeripheral } from './ant/HrmPeripheral.js'
import { createBleHrmPeripheral } from './ble/HrmPeripheral.js'
const bleModes = ['FTMS', 'FTMSBIKE', 'PM5', 'CSC', 'CPS', 'OFF']
const hrmModes = ['ANT', 'BLE', 'OFF']
function createPeripheralManager () {
const emitter = new EventEmitter()
let _antManager
let blePeripheral
let bleMode
let hrmPeripheral
let hrmMode
createBlePeripheral(config.bluetoothMode)
createHrmPeripheral(config.heartRateMode)
function getBlePeripheral () {
return blePeripheral
}
function getBlePeripheralMode () {
return bleMode
}
function getHrmPeripheral () {
return hrmPeripheral
}
function getHrmPeripheralMode () {
return hrmMode
}
function switchBlePeripheralMode (newMode) {
// if now mode was passed, select the next one from the list
if (newMode === undefined) {
newMode = bleModes[(bleModes.indexOf(bleMode) + 1) % bleModes.length]
}
createBlePeripheral(newMode)
}
function notifyMetrics (type, metrics) {
blePeripheral.notifyData(type, metrics)
}
function notifyStatus (status) {
blePeripheral.notifyStatus(status)
}
async function createBlePeripheral (newMode) {
if (blePeripheral) {
await blePeripheral.destroy()
}
switch (newMode) {
case 'PM5':
log.info('bluetooth profile: Concept2 PM5')
blePeripheral = createPm5Peripheral(controlCallback)
bleMode = 'PM5'
break
case 'FTMSBIKE':
log.info('bluetooth profile: FTMS Indoor Bike')
blePeripheral = createFtmsPeripheral(controlCallback, {
simulateIndoorBike: true
})
bleMode = 'FTMSBIKE'
break
case 'CSC':
log.info('bluetooth profile: Cycling Speed and Cadence')
blePeripheral = createCscPeripheral()
bleMode = 'CSC'
break
case 'CPS':
log.info('bluetooth profile: Cycling Power Meter')
blePeripheral = createCpsPeripheral()
bleMode = 'CPS'
break
case 'FTMS':
log.info('bluetooth profile: FTMS Rower')
blePeripheral = createFtmsPeripheral(controlCallback, {
simulateIndoorBike: false
})
bleMode = 'FTMS'
break
default:
log.info('bluetooth profile: Off')
bleMode = 'OFF'
}
if (bleMode.toLocaleLowerCase() !== 'OFF'.toLocaleLowerCase()) { blePeripheral.triggerAdvertising() }
emitter.emit('control', {
req: {
name: 'blePeripheralMode',
peripheralMode: bleMode
}
})
}
function switchHrmMode (newMode) {
if (newMode === undefined) {
newMode = hrmModes[(hrmModes.indexOf(hrmMode) + 1) % hrmModes.length]
}
createHrmPeripheral(newMode)
}
async function createHrmPeripheral (newMode) {
if (hrmPeripheral) {
await hrmPeripheral.destroy()
hrmPeripheral.removeAllListeners()
if (_antManager && newMode !== 'ANT') { await _antManager.closeAntStick() }
}
switch (newMode) {
case 'ANT':
log.info('heart rate profile: ANT')
if (!_antManager) {
_antManager = new AntManager()
}
hrmPeripheral = createAntHrmPeripheral(_antManager)
hrmMode = 'ANT'
await hrmPeripheral.attach()
break
case 'BLE':
log.info('heart rate profile: BLE')
hrmPeripheral = createBleHrmPeripheral()
hrmMode = 'BLE'
break
default:
log.info('heart rate profile: Off')
hrmMode = 'OFF'
}
if (hrmMode.toLocaleLowerCase() !== 'OFF'.toLocaleLowerCase()) {
hrmPeripheral.on('heartRateMeasurement', (heartRateMeasurement) => {
emitter.emit('heartRateMeasurement', heartRateMeasurement)
})
}
emitter.emit('control', {
req: {
name: 'hrmPeripheralMode',
peripheralMode: hrmMode
}
})
}
function controlCallback (event) {
emitter.emit('control', event)
}
return Object.assign(emitter, {
getBlePeripheral,
getBlePeripheralMode,
getHrmPeripheral,
getHrmPeripheralMode,
switchHrmMode,
switchBlePeripheralMode,
notifyMetrics,
notifyStatus
})
}
export { createPeripheralManager }