openrowingmonitor/app/ble/csc/CscMeasurementCharacteristi...

82 lines
2.7 KiB
JavaScript

'use strict'
/*
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
*/
import bleno from '@abandonware/bleno'
import log from 'loglevel'
import BufferBuilder from '../BufferBuilder.js'
export default class CyclingSpeedCadenceMeasurementCharacteristic extends bleno.Characteristic {
constructor () {
super({
// Cycling Speed and Cadence Measurement
uuid: '2A5B',
value: null,
properties: ['notify'],
descriptors: [
new bleno.Descriptor({
uuid: '2901',
value: 'Cycling Speed and Cadence Measurement'
})
]
})
this._updateValueCallback = null
this._subscriberMaxValueSize = null
}
onSubscribe (maxValueSize, updateValueCallback) {
log.debug(`CyclingSpeedCadenceMeasurementCharacteristic - central subscribed with maxSize: ${maxValueSize}`)
this._updateValueCallback = updateValueCallback
this._subscriberMaxValueSize = maxValueSize
return this.RESULT_SUCCESS
}
onUnsubscribe () {
log.debug('CyclingSpeedCadenceMeasurementCharacteristic - central unsubscribed')
this._updateValueCallback = null
this._subscriberMaxValueSize = null
return this.RESULT_UNLIKELY_ERROR
}
notify (data) {
// ignore events without the mandatory fields
if (!('cyclePower' in data)) {
log.error('can not deliver bike data without mandatory fields')
return this.RESULT_SUCCESS
}
if (this._updateValueCallback) {
const bufferBuilder = new BufferBuilder()
// Features flag
bufferBuilder.writeUInt8(cscFeaturesFlags.crankRevolutionDataSupported | cscFeaturesFlags.wheelRevolutionDataSupported)
// Wheel revolution count (basically the distance in cm)
bufferBuilder.writeUInt32LE(Math.round(Math.round(data.totalLinearDistance * 100)))
// Wheel revolution time (ushort with 1024 resolution, resetting in every 64sec)
bufferBuilder.writeUInt16LE(Math.round(data.totalMovingTime * 1024) % Math.pow(2, 16))
// Total stroke count
bufferBuilder.writeUInt16LE(Math.round(data.totalNumberOfStrokes))
// last stroke time time (ushort with 1024 resolution, resetting in every 64sec)
bufferBuilder.writeUInt16LE(Math.round(data.driveLastStartTime * 1024) % Math.pow(2, 16))
const buffer = bufferBuilder.getBuffer()
if (buffer.length > this._subscriberMaxValueSize) {
log.warn(`CyclingSpeedCadenceMeasurementCharacteristic - notification of ${buffer.length} bytes is too large for the subscriber`)
}
this._updateValueCallback(bufferBuilder.getBuffer())
}
return this.RESULT_SUCCESS
}
}
export const cscFeaturesFlags =
{
wheelRevolutionDataSupported: (0x01 << 0),
crankRevolutionDataSupported: (0x01 << 1),
multipleSensorLocationSupported: (0x01 << 2)
}