UNPKG

ant-plus

Version:
190 lines 7.73 kB
"use strict"; /* * ANT+ profile: https://www.thisisant.com/developer/ant-plus/device-profiles/#521_tab * Spec sheet: https://www.thisisant.com/resources/bicycle-power/ */ Object.defineProperty(exports, "__esModule", { value: true }); exports.MuscleOxygenScanner = exports.MuscleOxygenSensor = void 0; const ant_1 = require("./ant"); class MuscleOxygenSensorState { constructor(deviceID) { this.DeviceID = deviceID; } } class MuscleOxygenScanState extends MuscleOxygenSensorState { } class MuscleOxygenSensor extends ant_1.AntPlusSensor { attach(channel, deviceID) { super.attach(channel, 'receive', deviceID, MuscleOxygenSensor.deviceType, 0, 255, 8192); this.state = new MuscleOxygenSensorState(deviceID); } updateState(deviceId, data) { this.state.DeviceID = deviceId; updateState(this, this.state, data); } _sendTimeCmd(cmd, cbk) { const now = new Date(); const utc = Math.round((now.getTime() - Date.UTC(1989, 11, 31, 0, 0, 0, 0)) / 1000); const offset = -Math.round(now.getTimezoneOffset() / 15); const payload = [0x10, cmd & 0xFF, 0xFF, offset & 0xFF, (utc >> 0) & 0xFF, (utc >> 8) & 0xFF, (utc >> 16) & 0xFF, (utc >> 24) & 0xFF]; const msg = ant_1.Messages.acknowledgedData(this.channel, payload); this.send(msg, cbk); } setUTCTime(cbk) { this._sendTimeCmd(0x00, cbk); } startSession(cbk) { this._sendTimeCmd(0x01, cbk); } stopSession(cbk) { this._sendTimeCmd(0x02, cbk); } setLap(cbk) { this._sendTimeCmd(0x03, cbk); } } exports.MuscleOxygenSensor = MuscleOxygenSensor; MuscleOxygenSensor.deviceType = 0x1F; class MuscleOxygenScanner extends ant_1.AntPlusScanner { constructor() { super(...arguments); this.states = {}; } deviceType() { return MuscleOxygenSensor.deviceType; } createStateIfNew(deviceId) { if (!this.states[deviceId]) { this.states[deviceId] = new MuscleOxygenScanState(deviceId); } } updateRssiAndThreshold(deviceId, rssi, threshold) { this.states[deviceId].Rssi = rssi; this.states[deviceId].Threshold = threshold; } updateState(deviceId, data) { updateState(this, this.states[deviceId], data); } } exports.MuscleOxygenScanner = MuscleOxygenScanner; function updateState(sensor, state, data) { const oldEventCount = state._EventCount || 0; const page = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA); switch (page) { case 0x01: { let eventCount = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 1); const notifications = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 2); const capabilities = data.readUInt16LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 3); const total = data.readUInt16LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 4) & 0xFFF; const previous = (data.readUInt16LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 5) >> 4) & 0x3FF; const current = (data.readUInt16LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 6) >> 6) & 0x3FF; if (eventCount !== oldEventCount) { state._EventCount = eventCount; if (oldEventCount > eventCount) { //Hit rollover value eventCount += 255; } } state.UTCTimeRequired = (notifications & 0x01) === 0x01; state.SupportANTFS = (capabilities & 0x01) === 0x01; switch ((capabilities >> 1) & 0x7) { case 1: state.MeasurementInterval = 0.25; break; case 2: state.MeasurementInterval = 0.5; break; case 3: state.MeasurementInterval = 1; break; case 4: state.MeasurementInterval = 2; break; default: delete state.MeasurementInterval; } switch (total) { case 0xFFE: state.TotalHemoglobinConcentration = 'AmbientLightTooHigh'; break; case 0xFFF: state.TotalHemoglobinConcentration = 'Invalid'; break; default: state.TotalHemoglobinConcentration = total; } switch (previous) { case 0x3FE: state.PreviousSaturatedHemoglobinPercentage = 'AmbientLightTooHigh'; break; case 0x3FF: state.PreviousSaturatedHemoglobinPercentage = 'Invalid'; break; default: state.PreviousSaturatedHemoglobinPercentage = previous; } switch (current) { case 0x3FE: state.CurrentSaturatedHemoglobinPercentage = 'AmbientLightTooHigh'; break; case 0x3FF: state.CurrentSaturatedHemoglobinPercentage = 'Invalid'; break; default: state.CurrentSaturatedHemoglobinPercentage = current; } break; } case 0x50: { state.HwVersion = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 3); state.ManId = data.readUInt16LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 4); state.ModelNum = data.readUInt16LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 6); break; } case 0x51: { const swRevSup = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 2); const swRevMain = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 3); const serial = data.readInt32LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 4); state.SwVersion = swRevMain; if (swRevSup !== 0xFF) { state.SwVersion += swRevSup / 1000; } if (serial !== 0xFFFFFFFF) { state.SerialNumber = serial; } break; } case 0x52: { const batteryId = data.readUInt8(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 2); const operatingTime = data.readUInt32LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 3) & 0xFFFFFF; const batteryFrac = data.readInt32LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 6); const batteryStatus = data.readInt32LE(ant_1.Messages.BUFFER_INDEX_MSG_DATA + 7); state.OperatingTime = operatingTime * (((batteryStatus & 0x80) === 0x80) ? 2 : 16); state.BatteryVoltage = (batteryStatus & 0x0F) + (batteryFrac / 256); const batteryFlags = (batteryStatus & 0x70) >>> 4; switch (batteryFlags) { case 1: state.BatteryStatus = 'New'; break; case 2: state.BatteryStatus = 'Good'; break; case 3: state.BatteryStatus = 'Ok'; break; case 4: state.BatteryStatus = 'Low'; break; case 5: state.BatteryStatus = 'Critical'; break; default: state.BatteryVoltage = undefined; state.BatteryStatus = 'Invalid'; break; } break; } default: return; } if (page !== 0x01 || state._EventCount !== oldEventCount) { sensor.emit('oxygenData', state); } } //# sourceMappingURL=muscle-oxygen-sensors.js.map