UNPKG

node-aurora

Version:

Provides an interface to the Aurora Dreamband.

250 lines (175 loc) 8.23 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _assign = require('babel-runtime/core-js/object/assign'); var _assign2 = _interopRequireDefault(_assign); var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _AuroraConstants = require('./AuroraConstants'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var AuroraSessionParser = function AuroraSessionParser() { (0, _classCallCheck3.default)(this, AuroraSessionParser); }; AuroraSessionParser.parseSessionTxtObject = function (sessionTxtObject) { var session = { awakenings: 0, sleepOnset: 0, incomplete: false, awakeAt: 0, asleepAt: 0, sleepScore: 0, sleepDuration: { total: 0, unknown: 0, awake: 0, light: 0, deep: 0, rem: 0 }, events: [], streams: [] }; var throwError = function throwError(error) { session.error = error; return _promise2.default.reject(session); }; if ((typeof sessionTxtObject === 'undefined' ? 'undefined' : (0, _typeof3.default)(sessionTxtObject)) != 'object') return throwError('Session object invalid.'); //TODO: consider using deep assign (0, _assign2.default)(session, sessionTxtObject); if (!session.version || !session.date || !session.profile || !session.duration) return throwError('Session corrupted.'); if (parseInt(session.version) < 20001) return throwError('Aurora firmware version no longer supported.'); if (!Array.isArray(session.events)) return throwError('Session event array corrupted.'); if (!Array.isArray(session.streams)) return throwError('Session stream array corrupted.'); //if (session.duration < 1000 * 60 * 30) return throwError('Session is shorter than 30 minutes.'); for (var i = 0; i < session.events.length; i++) { var event = session.events[i]; if (!event || (typeof event === 'undefined' ? 'undefined' : (0, _typeof3.default)(event)) != 'object') { //todo: fix this mess... //console.log('Missing event at index: ' + i); session.events.splice(i, 1); i--; continue; } if (typeof event.id == 'undefined' || typeof event.time == 'undefined' || typeof event.flags == 'undefined') { //console.log('Session event corrupted at index: ' + i); session.events.splice(i, 1); i--; continue; } event.date = session.date + event.time; } if (session.streams) { for (var _i = 0; _i < session.streams.length; _i++) { var stream = session.streams[_i]; if (!stream || (typeof stream === 'undefined' ? 'undefined' : (0, _typeof3.default)(stream)) != 'object') { //console.log('Missing stream at index: ' + i); session.streams.splice(_i, 1); _i--; continue; } if (typeof stream.id == 'undefined' || typeof stream.time == 'undefined' || typeof stream.type == 'undefined' || !stream.file) { //console('Session stream corrupted at index: ' + i); session.streams.splice(_i, 1); _i--; continue; } stream.date = session.date + stream.time; } } var firstSignalStageTime = 0; var currentStage = 0; var currentStageTime = 0; var currentStageDate = 0; var stageDurations = new Array((0, _keys2.default)(_AuroraConstants.SleepStages).length).fill(0); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (0, _getIterator3.default)(session.events), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _event = _step.value; switch (_event.id) { case _AuroraConstants.EventIds.SLEEP_TRACKER_MONITOR: var stage = _event.flags; if (!firstSignalStageTime && stage > _AuroraConstants.SleepStages.UNKNOWN) { firstSignalStageTime = _event.time; } if (currentStageTime) { stageDurations[currentStage] += _event.time - currentStageTime; } //is this a non-awake stage? if (stage > _AuroraConstants.SleepStages.AWAKE) { //is this the first non-awake sleep stage? if (!session.asleepAt) { session.asleepAt = _event.date; session.sleepOnset = _event.time - firstSignalStageTime; } } //is this an awake stage and have we found the first sleep event? else if (stage == _AuroraConstants.SleepStages.AWAKE && session.asleepAt) { session.awakeAt = _event.date; } //update current stage/time currentStage = stage; currentStageTime = _event.time; currentStageDate = _event.date; break; case _AuroraConstants.EventIds.AUTO_SHUTDOWN: session.incomplete = true; break; case _AuroraConstants.EventIds.AWAKENING: session.awakenings++; break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } session.sleepDuration.total = stageDurations.reduce(function (p, c) { return p + c; }); session.sleepDuration.unknown = stageDurations[_AuroraConstants.SleepStages.UNKNOWN]; session.sleepDuration.awake = stageDurations[_AuroraConstants.SleepStages.AWAKE]; session.sleepDuration.light = stageDurations[_AuroraConstants.SleepStages.LIGHT]; session.sleepDuration.deep = stageDurations[_AuroraConstants.SleepStages.DEEP]; session.sleepDuration.rem = stageDurations[_AuroraConstants.SleepStages.REM]; if (session.sleepDuration.total) { session.sleepScore = Math.round(1 / (1 + Math.exp(-3.7 * ((session.sleepDuration.rem + session.sleepDuration.deep) / session.sleepDuration.total - 0.25))) * 100); } //if we have a complete session with a valid sleep start time //figure out when the awake time occurred if (session.asleepAt && !session.incomplete) { //is the last stage was awake (as it should be in the general case) //we can use the last stage time as the awake time if (currentStage == _AuroraConstants.SleepStages.AWAKE) { session.awakeAt = currentStageDate; } //for any other known stages, (/or if the last known stage was short enough) //we'll just use the session end time else if (currentStage != _AuroraConstants.SleepStages.UNKNOWN || session.duration - currentStageTime < 1000 * 60 * 15) { session.awakeAt = session.date + session.duration; } } return _promise2.default.resolve(session); }; exports.default = AuroraSessionParser; ;