@iotile/iotile-device
Version:
A typescript library for interfacing with IOTile BLE devices
147 lines • 5.27 kB
JavaScript
"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