82 lines
2.7 KiB
JavaScript
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)
|
|
}
|