89 lines
2.8 KiB
JavaScript
89 lines
2.8 KiB
JavaScript
'use strict'
|
|
/*
|
|
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
|
|
|
Implements the Status Characteristics, that can be used to notify the central about the current
|
|
training machine settings. Currently only used to notify the central about training resets.
|
|
|
|
From the specs:
|
|
If the Server supports the Fitness Machine Control Point, the Fitness Machine Status characteristic
|
|
shall be exposed by the Server. Otherwise, supporting the Fitness Machine Status characteristic is optional.
|
|
*/
|
|
import bleno from '@abandonware/bleno'
|
|
import log from 'loglevel'
|
|
|
|
// see page 67 https://www.bluetooth.com/specifications/specs/fitness-machine-service-1-0
|
|
const StatusOpCode = {
|
|
reservedForFutureUse: 0x00,
|
|
reset: 0x01,
|
|
stoppedOrPausedByUser: 0x02,
|
|
stoppedBySafetyKey: 0x03,
|
|
startedOrResumedByUser: 0x04,
|
|
targetSpeedChanged: 0x05,
|
|
targetInclineChanged: 0x06,
|
|
targetResistanceLevelChanged: 0x07,
|
|
targetPowerChanged: 0x08,
|
|
targetHeartRateChanged: 0x09,
|
|
targetExpendedEnergyChanged: 0x0a,
|
|
targetNumberOfStepsChanged: 0x0b,
|
|
targetNumberOfStridesChanged: 0x0c,
|
|
targetDistanceChanged: 0x0d,
|
|
targetTrainingTimeChanged: 0x0e,
|
|
targetedTimeInTwoHeartRateZonesChanged: 0x0f,
|
|
targetedTimeInThreeHeartRateZonesChanged: 0x10,
|
|
targetedTimeInFiveHeartRateZonesChanged: 0x11,
|
|
indoorBikeSimulationParametersChanged: 0x12,
|
|
wheelCircumferenceChanged: 0x13,
|
|
spinDownStatus: 0x14,
|
|
targetedCadenceChanged: 0x15
|
|
}
|
|
|
|
export default class FitnessMachineStatusCharacteristic extends bleno.Characteristic {
|
|
constructor () {
|
|
super({
|
|
// Fitness Machine Status
|
|
uuid: '2ADA',
|
|
value: null,
|
|
properties: ['notify']
|
|
})
|
|
this._updateValueCallback = null
|
|
}
|
|
|
|
onSubscribe (maxValueSize, updateValueCallback) {
|
|
log.debug(`FitnessMachineStatusCharacteristic - central subscribed with maxSize: ${maxValueSize}`)
|
|
this._updateValueCallback = updateValueCallback
|
|
return this.RESULT_SUCCESS
|
|
}
|
|
|
|
onUnsubscribe () {
|
|
log.debug('FitnessMachineStatusCharacteristic - central unsubscribed')
|
|
this._updateValueCallback = null
|
|
return this.RESULT_UNLIKELY_ERROR
|
|
}
|
|
|
|
notify (status) {
|
|
if (!(status && status.name)) {
|
|
log.error('can not deliver status without name')
|
|
return this.RESULT_SUCCESS
|
|
}
|
|
if (this._updateValueCallback) {
|
|
const buffer = Buffer.alloc(2)
|
|
switch (status.name) {
|
|
case 'reset':
|
|
buffer.writeUInt8(StatusOpCode.reset, 0)
|
|
break
|
|
case 'stoppedOrPausedByUser':
|
|
buffer.writeUInt8(StatusOpCode.stoppedOrPausedByUser, 0)
|
|
break
|
|
case 'startedOrResumedByUser':
|
|
buffer.writeUInt8(StatusOpCode.startedOrResumedByUser, 0)
|
|
break
|
|
default:
|
|
log.error(`status ${status.name} is not supported`)
|
|
}
|
|
this._updateValueCallback(buffer)
|
|
}
|
|
return this.RESULT_SUCCESS
|
|
}
|
|
}
|