UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

144 lines 6.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const config_1 = require("../../config"); const error_space_1 = require("../../common/error-space"); const iotile_common_1 = require("@iotile/iotile-common"); const types_1 = require("./types"); const utilities_1 = require("./utilities"); const utc_reconstruction_1 = require("./utc-reconstruction"); class POD1M extends iotile_common_1.LoggingBase { constructor(device, adapter) { super(config_1.catPOD1M); this.device = device; this.adapter = adapter; } async getShockInfo(shock) { let [peak, duration, dVx, dVy, dVz] = await this.adapter.typedRPC(12, 0x8004, 'BB', 'HHlll', [1, shock]); let peakVal = peak >> 2; let peakAxis = peak & 0b11; return new types_1.ShockInfo(peakVal, peakAxis, duration, dVx, dVy, dVz); } async getAccelerometerStatus() { try { let [last_err, shock_counter, tile_state, _unused, state, flags, x, y, z, _unused2, _unused3] = await this.adapter.typedRPC(12, 0x8006, "", "LLBBBBHHHBB", [], 3.0); let TILE_STATE_TABLE = { 0: "initializing", 1: "capturing", 2: "streaming" }; let status = { 'tile_state': TILE_STATE_TABLE[tile_state], 'recording': !!(flags & (1 << 0)), 'settled': !!(flags & (1 << 2)), 'streaming': !!(flags & (1 << 4)), }; return status; } catch (err) { this.logError("Couldn't get accelerometer tile status: ", err); throw new error_space_1.ConnectionError("Lost connection to accelerometer tile"); } } async downloadData(progress, highestReceivedWaveform) { let missingUTCCount = 0; let rawWaveforms = await this.getCompressedWaveforms(progress, highestReceivedWaveform); let decodedWaveforms = utilities_1.decompressWaveforms(rawWaveforms); for (let key in decodedWaveforms) { if (decodedWaveforms[key].utcTimestamp == null) missingUTCCount += 1; } if (missingUTCCount > 0) { this.logWarning(`Found ${missingUTCCount} waveforms without UTC timestamps, will need to reconstruct timestamps`); await this.device.acknowledgeStreamerRPC(0, 1, true); await this.device.acknowledgeStreamerRPC(2, 1, true); } else { this.logInfo("All waveforms had UTC timestamps, no reconstruction necessary"); } let reports = await this.downloadReports(progress); if (missingUTCCount > 0) { utc_reconstruction_1.ensureUTCTimestamps(decodedWaveforms, reports); let dropped = utc_reconstruction_1.dropNonUTCTimestamps(decodedWaveforms); if (dropped > 0) { this.logError(`Dropped ${dropped} waveforms whose timestamps could not be determined`); } } let waveformEvents = utilities_1.createWaveformEvents(decodedWaveforms); return [reports, waveformEvents]; } async sortReadings(skipID) { if (skipID == null) { skipID = 0; } let highestN = 100; let [count] = await this.adapter.errorHandlingRPC(12, 0x803a, "LHB", "LL", [skipID, highestN, 0]); return count; } async getCompressedWaveforms(notifier, skipID) { notifier.startOne("Entering Streaming Mode", 1); await this.adapter.errorHandlingRPC(12, 0x8038, "", "L", []); notifier.finishOne(); let expected = 100; let received = 0; let dropped = 0; try { notifier.startOne('Sorting Waveform Readings', 1); expected = await this.sortReadings(skipID); notifier.finishOne(); await this.adapter.enableTracing(); this.adapter.clearTrace(); let [err, count, filler] = await this.adapter.typedRPC(12, 0x803e, "", "HHH", [], 1.0); if (err) { this.logError(`Unable to stream sorted waveforms, error code: ${err}`); throw new iotile_common_1.BaseError('Unable to Stream Waveforms', 'Unable to stream sorted waveforms from device. Please disconnect and try again.'); } let subNotifier = notifier.startOne(`Downloading ${count} Waveforms from Device`, count); if (subNotifier == null) subNotifier = new iotile_common_1.ProgressNotifier(); this.logInfo(`Receiving ${count} waveform(s) from device.`); if (skipID != null) this.logInfo(`Dropping waveforms older than ${skipID}`); let waveforms = {}; for (received; received < count; received++) { let header = await this.adapter.waitForTracingData(20); let [fmtCode, _unused, compressedSize, uniqueId, timestamp, crcCode, _unused2, _unused3, _unused4, _unused5] = iotile_common_1.unpackArrayBuffer("BBHLLLBBBB", header); this.logDebug(`Received header ${received}: uniqueId: ${uniqueId}, compressedSize: ${compressedSize}, fmtCode: ${fmtCode}`); let waveform = await this.adapter.waitForTracingData(compressedSize); this.logDebug(`Received ${compressedSize} bytes of waveform data`); if (skipID != null && uniqueId <= skipID) { dropped += 1; continue; } waveforms[uniqueId] = { "timestamp": timestamp, "crcCode": crcCode, "rawWaveform": waveform }; subNotifier.finishOne(); } notifier.finishOne(); this.logInfo(`Dropped ${dropped} waveforms that were older than our skipID`); return waveforms; } catch (err) { notifier.addError(`Error receiving waveforms, successfully received ${received} of an expected ${expected}`); this.logError('Error getting compressed waveforms: ', err); throw err; } finally { let status = await this.getAccelerometerStatus(); while (status.streaming) { await iotile_common_1.delay(500); status = await this.getAccelerometerStatus(); } await this.adapter.errorHandlingRPC(12, 0x8039, "", "L", []); } } async downloadReports(notifier) { let options; options = { expectedStreamers: { 0: 'Environmental Report', 1: 'System Report', 2: 'Trip Report' }, requireAll: false }; let result = await this.device.receiveReports(options, notifier); return result.reports; } } exports.POD1M = POD1M; //# sourceMappingURL=device.js.map