UNPKG

sensecap

Version:

## Install ``` npm install sensecap --save ```

333 lines (305 loc) 13 kB
var logger = require('../utils/loggerUtil') var assert = require('assert'); function DataResult(options) { this.context = options; } DataResult.prototype = { /** * 获取最新一条数据 */ latestData: function (callback) { var deviceEui = this.context.deviceEui; assert(deviceEui, 'deviceEui is required'); var channelIndex = this.context.channelIndex; var measurementId = this.context.measurementId; var telemetryDataListener = this.context.telemetryDataListener; this.context.dataNetModule.viewLatestTelemetryData(deviceEui, channelIndex, measurementId, function (error, body) { var telemetryDataList = []; if (!error) { var data = body.data; if (data && data.length > 0) { for (var i = 0; i < data.length; i++) { for (var j=0; j< data[i].points.length; j++) { data[i].points[j].time = new Date(data[i].points[j].time).valueOf() / 1000; } telemetryDataList.push(data[i]); } } } if (callback) { callback(error, telemetryDataList); } }) this._handlerTelemetryDataListener(deviceEui, channelIndex, measurementId, telemetryDataListener); }, /** * 获取历史数据 */ dataList: function (callback) { var deviceEui = this.context.deviceEui; assert(deviceEui, 'deviceEui is required'); var channelIndex = this.context.channelIndex; var measurementId = this.context.measurementId; var startTime = this.context.startTime; var endTime = this.context.endTime; var limit = this.context.limit; var telemetryDataListener = this.context.telemetryDataListener; var that = this; if (startTime !== 0 || endTime !== 0) { this.context.dataNetModule.viewHistoryTelemetryData(deviceEui, channelIndex, measurementId, startTime, endTime, limit, function (error, body) { var telemetryDataList = []; if (!error) { // telemetryDataList = body.data.list; telemetryDataList = that._clearUpTelemetryData(body.data.list); } if (callback) { callback(error, telemetryDataList); } }) } this._handlerTelemetryDataListener(deviceEui, channelIndex, measurementId, telemetryDataListener); }, /** * 获取折线图数据点,原openapi方式 */ getChartPointData: function (callback) { var deviceEui = this.context.deviceEui; assert(deviceEui, 'deviceEui is required'); var channelIndex = this.context.channelIndex; var measurementId = this.context.measurementId; var startTime = this.context.startTime; var endTime = this.context.endTime; var interval = this.context.interval; var that = this; this.context.dataNetModule.viewChartPoints(deviceEui, channelIndex, measurementId, interval, startTime, endTime, function (error, body) { var telemetryDataList = []; if (!error) { // telemetryDataList = body.data; telemetryDataList = that._clearUpChartPointData(body.data); } if (callback) { callback(error, telemetryDataList); } }) }, /** * 获取折线图数据 */ getChartData: function (callback) { var deviceEui = this.context.deviceEui; assert(deviceEui, 'deviceEui is required'); var channelIndex = this.context.channelIndex; var measurementId = this.context.measurementId; var endTime = this.context.endTime || new Date().getTime(); var startTime = this.context.startTime || (endTime - 86400000); var interval = this.context.interval || 30; var that = this; var intervalTime = 0; var pointInterval = 0; if (endTime - startTime <= 86400000) { // 一天内返回所有点 intervalTime = 1000; } else { intervalTime = interval * 60 * 1000 // 转成毫秒 } if (interval < 60) { pointInterval = 7200; // 秒 2小时 } else { pointInterval = interval * 2 * 60; // 秒 } // 获取历史数据 this.context.dataNetModule.viewHistoryTelemetryData(deviceEui, channelIndex, measurementId, startTime, endTime, null, function (error, body) { var telemetryDataList = []; if (!error) { telemetryDataList = that._clearUpTelemetryData(body.data.list); telemetryDataList = that._clearUpChartData(telemetryDataList, intervalTime, pointInterval, startTime, endTime); } if (callback) { callback(error, telemetryDataList); } }) }, /** * [{ "channelIndex": 1, "measurementId": 4099, "values": [ [1606023000, null], [1606375800, null], [1606728600, 267.34], [1607491800, 1765.96], [1607493508, 2421.47] ] }] */ _clearUpTelemetryData: function (telemetryDataList) { var dataList = [] var channelAndMeasurementIdArr = telemetryDataList[0] var valueAndTimeArr = telemetryDataList[1] for (var i = 0; i < channelAndMeasurementIdArr.length; i++) { var item = channelAndMeasurementIdArr[i]; var data = { 'channel_index': item[0], 'measurement_id': item[1], 'values': [] } for (var j = 0; j < valueAndTimeArr[i].length; j++) { var element = valueAndTimeArr[i][j]; var value = element[0]; var time = new Date(element[1]).valueOf() / 1000; data.values.push([value, time]) } dataList.push(data); } return dataList }, /** * openapi方式的图表数据整理 */ _clearUpChartPointData: function (pointData) { var dataList = []; for (var i = 0; i < pointData.length; i++) { var item = pointData[i]; var measurementList = {}; for (var j = 0; j < item.lists.length; j++) { var element = item.lists[j]; var measurementId = element.measurement_id if (!measurementList[measurementId]) { measurementList[measurementId] = [] } measurementList[measurementId].push([new Date(element.time) / 1000, element.average_value]) } var measurementIds = Object.keys(measurementList); for (var j = 0; j < measurementIds.length; j++) { var data = { 'channel_index': item.channel, 'measurement_id': measurementIds[j], 'values': measurementList[measurementIds[j]] } dataList.push(data); } } return dataList; }, /** * "values":[[0.74,1607500530000]] * * 补点规则 * interval<=60 每缺两个小时的数据中间补一个点 * interval>60 每缺 interval*2 小时的数据中间补一个点 * 首位补点 * 比较【查询时间开始点】和【实际数据首位时间点】按照补点规则补点,满足规则则补上首位点时间 * 末尾补点 * 比较【查询时间结束点】和【实际数据末尾时间点】按照补点规则补点,满足规则则补上末尾点,末尾时间按查询结束时间精确到具体秒补点 */ _clearUpChartData: function (telemetryDataList, intervalTime, pointInterval, startTime, endTime) { for (var i = 0; i < telemetryDataList.length; i++) { var item = telemetryDataList[i]; var values = item.values; var newValues = []; var list = { value: {}, count: {} } var keyList = [] for (var j = 0; j < values.length; j++) { var element = values[j]; var key = parseInt(element[1] / intervalTime + 1); if (list.value[key]) { list.value[key] = list.value[key] + element[0]; list.count[key]++; } else { list.value[key] = element[0]; list.count[key] = 1; keyList.push(key); // logger.log('key========: ' + key + ',element[1]: ' + new Date(element[1]).toLocaleString() + ',time: ' + element[1]) } } var keys = Object.keys(list.value) for (var j = 0; j < keys.length; j++) { var key = keys[j]; var data = [] if (key < new Date().valueOf() / 10000) { data[0] = key * (intervalTime / 1000); } else { data[0] = key; } if (list.value[key] !== null) { data[1] = list.value[key] / list.count[key]; } else { data[1] = null; } newValues.push(data); } // logger.log('newValues before========'); // for (var i = 0; i < newValues.length; i++) { // logger.log('newValues time========' + new Date(newValues[i][0] * 1000).toLocaleString() + ',value:' + newValues[i][1] + ',time: ' + newValues[i][0]) // } // 补点 var fullValues = [] startTime = startTime / 1000; // 补首点 if (newValues[0][0] - startTime > pointInterval) { fullValues[0] = [startTime, null]; fullValues[1] = [(startTime + newValues[0][0]) / 2, null]; fullValues[2] = newValues[0]; } // 补中间点 for (var i = 0; i < newValues.length - 1; i++) { var value1 = newValues[i]; var value2 = newValues[i + 1]; while (value2[0] - value1[0] > pointInterval) { fullValues.push([value1[0] + pointInterval, null]) value1[0] = value1[0] + pointInterval; } fullValues.push(value2) } // 补尾点 endTime = endTime / 1000; if (endTime - newValues[newValues.length - 1][0] > pointInterval) { fullValues.push([(endTime + newValues[newValues.length - 1][0]) / 2, null]); fullValues.push([endTime, null]); } // logger.log('fullValues after========'); // for (var i = 0; i < fullValues.length; i++) { // logger.log('fullValues time========' + new Date(fullValues[i][0] * 1000).toLocaleString() + ',value:' + fullValues[i][1] + ',time: ' + fullValues[i][0]) // } item.values = fullValues; } return telemetryDataList; }, /** * 关闭订阅 */ stopTelemetryDataListener: function (callback) { var deviceEui = this.context.deviceEui; assert(deviceEui, 'deviceEui is required'); var channelIndex = this.context.channelIndex; var measurementId = this.context.measurementId; this.context.dataNetModule.baseMqtt.unSubscribe(deviceEui, channelIndex, measurementId, callback); }, _handlerTelemetryDataListener: function (deviceEui, channelIndex, measurementId, telemetryDataListener) { if (telemetryDataListener) { // 订阅最新消息 var that = this this.context.dataNetModule.getOrganizationId(function (error, body) { if (!error) { that.context.dataNetModule.baseMqtt.setOrgId(body.data.orgId) that._connectMqtt(deviceEui, channelIndex, measurementId, telemetryDataListener); } else { telemetryDataListener(error); } }); } }, _connectMqtt: function (deviceEui, channelIndex, measurementId, telemetryDataListener) { var that = this this.context.dataNetModule.baseMqtt.connect(function (error) { if (!error) { that.context.dataNetModule.baseMqtt.subscribeData(deviceEui, channelIndex, measurementId, telemetryDataListener) } else { telemetryDataListener(error.toString()); } }) } }; module.exports = DataResult;