UNPKG

incyclist-ant-plus

Version:

Incyclist library for ANT+ - originally forked from longhorn/ant-plus

202 lines (201 loc) 8.85 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.HeartRateSensorState = void 0; const consts_1 = require("../consts"); const messages_1 = require("../messages"); const base_sensor_1 = __importStar(require("./base-sensor")); class HeartRateSensorState extends base_sensor_1.SensorState { } exports.HeartRateSensorState = HeartRateSensorState; const DEVICE_TYPE = 120; const PROFILE = 'HR'; const PERIOD = 8070; class HeartRateSensor extends base_sensor_1.default { constructor() { super(...arguments); this.states = {}; this.pages = {}; } getDeviceType() { return DEVICE_TYPE; } getProfile() { return PROFILE; } getDeviceID() { return this.deviceID; } getChannelConfiguration() { return { type: 'receive', transmissionType: 0, timeout: consts_1.Constants.TIMEOUT_NEVER, period: PERIOD, frequency: 57 }; } onEvent(data) { return; } onMessage(data) { const channel = this.getChannel(); if (!channel) return; const channelNo = channel.getChannelNo(); if (data.readUInt8(messages_1.Messages.BUFFER_INDEX_CHANNEL_NUM) !== channelNo) { return; } const deviceID = data.readUInt16LE(messages_1.Messages.BUFFER_INDEX_EXT_MSG_BEGIN + 1); const deviceType = data.readUInt8(messages_1.Messages.BUFFER_INDEX_EXT_MSG_BEGIN + 3); if (deviceType !== this.getDeviceType()) { return; } if (!this.states[deviceID]) { this.states[deviceID] = new HeartRateSensorState(deviceID); this.states[deviceID].Channel = channelNo; } if (!this.pages[deviceID]) { this.pages[deviceID] = { oldPage: -1, pageState: PageState.INIT_PAGE }; } if (data.readUInt8(messages_1.Messages.BUFFER_INDEX_EXT_MSG_BEGIN) & 0x40) { if (data.readUInt8(messages_1.Messages.BUFFER_INDEX_EXT_MSG_BEGIN + 5) === 0x20) { this.states[deviceID].Rssi = data.readInt8(messages_1.Messages.BUFFER_INDEX_EXT_MSG_BEGIN + 6); this.states[deviceID].Threshold = data.readInt8(messages_1.Messages.BUFFER_INDEX_EXT_MSG_BEGIN + 7); } } switch (data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_TYPE)) { case consts_1.Constants.MESSAGE_CHANNEL_BROADCAST_DATA: case consts_1.Constants.MESSAGE_CHANNEL_ACKNOWLEDGED_DATA: case consts_1.Constants.MESSAGE_CHANNEL_BURST_DATA: updateState(this.states[deviceID], this.pages[deviceID], data); if (this.deviceID === 0 || this.deviceID === deviceID) { channel.onDeviceData(this.getProfile(), deviceID, this.states[deviceID]); } break; default: break; } } } exports.default = HeartRateSensor; const TOGGLE_MASK = 0x80; var PageState; (function (PageState) { PageState[PageState["INIT_PAGE"] = 0] = "INIT_PAGE"; PageState[PageState["STD_PAGE"] = 1] = "STD_PAGE"; PageState[PageState["EXT_PAGE"] = 2] = "EXT_PAGE"; })(PageState || (PageState = {})); function updateState(state, page, data) { const pageNum = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA); if (page.pageState === PageState.INIT_PAGE) { page.pageState = PageState.STD_PAGE; } else if ((pageNum !== page.oldPage) || (page.pageState === PageState.EXT_PAGE)) { page.pageState = PageState.EXT_PAGE; switch (pageNum & ~TOGGLE_MASK) { case 1: state.OperatingTime = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 1); state.OperatingTime |= data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2) << 8; state.OperatingTime |= data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 3) << 16; state.OperatingTime *= 2; break; case 2: state.ManId = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 1); state.SerialNumber = state.DeviceID; state.SerialNumber |= data.readUInt16LE(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2) << 16; state.SerialNumber >>>= 0; break; case 3: state.HwVersion = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 1); state.SwVersion = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2); state.ModelNum = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 3); break; case 4: state.PreviousBeat = data.readUInt16LE(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2); break; case 5: state.IntervalAverage = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 1); state.IntervalMax = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2); state.SessionAverage = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 3); break; case 6: state.SupportedFeatures = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2); state.EnabledFeatures = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 3); break; case 7: { const batteryLevel = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 1); const batteryFrac = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 2); const batteryStatus = data.readUInt8(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 3); if (batteryLevel !== 0xFF) { state.BatteryLevel = batteryLevel; } const coarseBatteryVoltage = batteryStatus & 0x0F; if (coarseBatteryVoltage !== 0x0F) { state.BatteryVoltage = coarseBatteryVoltage + (batteryFrac / 256); } const batteryFlags = (batteryStatus & 0x70) >>> 4; switch (batteryFlags & 0x07) { case 0: state.BatteryStatus = `Reserved (0)`; 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; case 6: state.BatteryStatus = `Reserved (6)`; default: state.BatteryStatus = `Invalid`; break; } break; } default: break; } } DecodeDefaultHRM(state, data.slice(messages_1.Messages.BUFFER_INDEX_MSG_DATA + 4)); page.oldPage = pageNum; } function DecodeDefaultHRM(state, pucPayload) { state.BeatTime = pucPayload.readUInt16LE(0); state.BeatCount = pucPayload.readUInt8(2); state.ComputedHeartRate = pucPayload.readUInt8(3); }