UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

147 lines 5.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const iotile_common_1 = require("@iotile/iotile-common"); const config_1 = require("../config"); let SECONDS_AT_2000 = Date.UTC(2000, 0, 1).valueOf() / 1000; class UTCAssigner { constructor(options) { this.imprecise = options.allowImprecise; this.logger = config_1.catUTCAssigner; this.anchorPoints = []; this.addedIDSet = {}; this.anchorPointsSorted = false; this.anchorStreams = {}; this.breakStreams = {}; this.initBreakStreams(); } initBreakStreams() { this.breakStreams[0x5c00] = true; } assignUTCTimestamp(readingID, uptime) { if (uptime === 0xFFFFFFFF) uptime = null; if (this.anchorPoints.length === 0) throw new iotile_common_1.ArgumentError("Cannot assign timestamp because there are no anchor points"); if (readingID > this.anchorPoints[this.anchorPoints.length - 1].readingId) throw new iotile_common_1.ArgumentError("Extrapolation of UTC times is not yet supported"); let i = this.bisectLeftAnchors(readingID); let last = copyAnchor(this.anchorPoints[i]); if (uptime != null) last.uptime = uptime; let exact = true; let accumDelta = 0; if (last.readingId === readingID && last.utcTime != null) return last.utcTime; i += 1; while (i < this.anchorPoints.length) { let curr = this.anchorPoints[i]; if (last.uptime == null || curr.uptime == null) { exact = false; } else if (curr.isBreak || curr.uptime < last.uptime) { exact = false; } else { accumDelta += curr.uptime - last.uptime; } last = curr; if (curr.utcTime != null) break; i += 1; } if (last.utcTime == null) throw new iotile_common_1.ArgumentError("There were no points with a UTC reference after the designed reading id"); if (this.imprecise === false && !exact) throw new iotile_common_1.ArgumentError("Could not assign precise UTC Timestamp"); return new Date(last.utcTime.valueOf() - (accumDelta * 1000)); } bisectLeftAnchors(readingID) { let low = 0; let high = this.anchorPoints.length; this.ensureAnchorPointsSorted(); while (low < high) { let mid = low + high >>> 1; if (this.anchorPoints[mid].readingId < readingID) { low = mid + 1; } else { high = mid; } } return low; } ensureAnchorPointsSorted() { if (this.anchorPointsSorted) return; this.anchorPoints.sort((a, b) => { return a.readingId - b.readingId; }); this.anchorPointsSorted = true; } addAnchorPoint(readingID, uptime, utc, isBreak = false) { if (readingID === 0) return; if (uptime == null && utc == null) return; if (readingID in this.addedIDSet) return; if (uptime != null && uptime & (1 << 31)) { if (utc != null) return; uptime &= (1 << 31) - 1; utc = rtcTimestampToDate(uptime); uptime = null; } let anchorPoint = { readingId: readingID, uptime: uptime, utcTime: utc, isBreak: isBreak }; this.anchorPoints.push(anchorPoint); this.addedIDSet[readingID] = true; this.anchorPointsSorted = false; } addReading(reading) { let isBreak = false; let utc = null; if (reading.stream in this.breakStreams) isBreak = true; if (reading.stream in this.anchorStreams) { utc = this.anchorStreams[reading.stream](reading.stream, reading.id, reading.timestamp, reading.value); } this.addAnchorPoint(reading.id, reading.timestamp, utc, isBreak); } markAnchorStream(streamID, valueProcessor) { if (valueProcessor == null || valueProcessor === "rtc") { valueProcessor = function (_streamID, _readingID, _uptime, value) { return rtcTimestampToDate(value); }; } else if (valueProcessor === "epoch") { valueProcessor = function (_streamID, _readingID, _uptime, value) { return new Date(value * 1000); }; } this.anchorStreams[streamID] = valueProcessor; } addAnchorsFromReport(report) { for (let reading of report.readings) { this.addReading(reading); } this.addAnchorPoint(report.header.reportID, report.header.sentTime, report.receivedTime); } } exports.UTCAssigner = UTCAssigner; function rtcTimestampToDate(seconds) { return new Date((seconds + SECONDS_AT_2000) * 1000); } function copyAnchor(src) { return { readingId: src.readingId, uptime: src.uptime, utcTime: src.utcTime, isBreak: src.isBreak }; } //# sourceMappingURL=utc-assigner.js.map