UNPKG

node-opcua-aggregates

Version:

pure nodejs OPCUA SDK - module aggregates

206 lines 7.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Interval = void 0; exports.isGoodish2 = isGoodish2; exports.isUncertain = isUncertain; exports._findGoodDataValueBefore = _findGoodDataValueBefore; exports._findGoodDataValueAfter = _findGoodDataValueAfter; exports.adjustProcessingOptions = adjustProcessingOptions; exports.getInterval = getInterval; /** * @module node-opca-aggregates */ const node_opcua_data_value_1 = require("node-opcua-data-value"); const node_opcua_status_code_1 = require("node-opcua-status-code"); function isGoodish2(statusCode, { treatUncertainAsBad }) { if (statusCode.isGoodish()) return true; if (isUncertain(statusCode)) return !treatUncertainAsBad; return false; } function isUncertain(statusCode) { return (statusCode.value & 0x40000000) === 0x40000000 && statusCode.value !== node_opcua_status_code_1.StatusCodes.BadNoData.value; } function _findGoodDataValueBefore(dataValues, index, bTreatUncertainAsBad) { index--; while (index >= 0) { const dataValue1 = dataValues[index]; if (!bTreatUncertainAsBad && !dataValue1.statusCode.isBad()) { return { index, dataValue: dataValue1 }; } if (bTreatUncertainAsBad && dataValue1.statusCode.isGood()) { return { index, dataValue: dataValue1 }; } index -= 1; } // not found return { dataValue: new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNoData }), index: -1 }; } function _findGoodDataValueAfter(dataValues, index, bTreatUncertainAsBad) { while (index < dataValues.length) { const dataValue1 = dataValues[index]; if (!bTreatUncertainAsBad && !dataValue1.statusCode.isBad()) { return { dataValue: dataValue1, index }; } if (bTreatUncertainAsBad && dataValue1.statusCode.isGood()) { return { dataValue: dataValue1, index }; } index += 1; } // not found return { dataValue: new node_opcua_data_value_1.DataValue({ statusCode: node_opcua_status_code_1.StatusCodes.BadNoData }), index: -1 }; } function adjustProcessingOptions(options) { options = options || {}; options.treatUncertainAsBad = options.treatUncertainAsBad || false; options.useSlopedExtrapolation = options.useSlopedExtrapolation || false; options.stepped = options.stepped || false; options.percentDataBad = parseInt(options.percentDataBad, 10); options.percentDataGood = parseInt(options.percentDataGood, 10); return options; } class Interval { startTime; dataValues; index; count; isPartial; processingInterval; // startTime // dataValues // index: index of first dataValue inside the interval // count: number of dataValue inside the interval constructor(options) { this.startTime = options.startTime; this.dataValues = options.dataValues; this.index = options.index; this.count = options.count; this.isPartial = options.isPartial; this.processingInterval = options.processingInterval; } getPercentBad() { return 100; } /** * returns true if a raw data exists at start */ hasRawDataAsStart() { const index = this.index; if (index < 0) { return false; } const dataValue1 = this.dataValues[index]; return this.startTime.getTime() === dataValue1.sourceTimestamp.getTime(); } /** * Find the first good or uncertain dataValue * just preceding this interval * @returns {*} */ beforeStartDataValue(bTreatUncertainAsBad) { return _findGoodDataValueBefore(this.dataValues, this.index, bTreatUncertainAsBad); } nextStartDataValue(bTreatUncertainAsBad) { return _findGoodDataValueAfter(this.dataValues, this.index, bTreatUncertainAsBad); } toString() { let str = ""; str += "startTime " + this.startTime.toUTCString() + "\n"; str += "start " + this.index + " "; str += "count " + this.count + " "; str += "isPartial " + this.isPartial + "\n"; if (this.index >= 0) { for (let i = this.index; i < this.index + this.count; i++) { const dataValue = this.dataValues[i]; str += " " + dataValue.sourceTimestamp.toUTCString() + dataValue.statusCode.toString(); str += dataValue.value ? dataValue.value.toString() : ""; str += "\n"; } } return str; } getEffectiveEndTime() { const e = this.startTime.getTime() + this.processingInterval; if (!this.dataValues || this.dataValues.length === 0) { return e; } let i = this.dataValues.length - 1; while (i >= 0 && this.dataValues[i].statusCode.equals(node_opcua_status_code_1.StatusCodes.BadNoData)) { i--; } if (i < 0) { return e; } const lastTimestamp = this.dataValues[i].sourceTimestamp; return Math.min(e, lastTimestamp.getTime() + 1); } /** * * @returns the interval duration */ duration() { const t1 = this.dataValues[this.index].sourceTimestamp.getTime(); const e = this.getEffectiveEndTime(); return e - t1; } /** * returns the region duration starting at index and finishing at index+1 or end limit of the interval */ regionDuration(index) { const t1 = this.dataValues[index].sourceTimestamp.getTime(); const e = this.getEffectiveEndTime(); const t2 = index < this.dataValues.length - 1 ? Math.min(this.dataValues[index + 1].sourceTimestamp.getTime(), e) : e; return t2 - t1; } } exports.Interval = Interval; function getInterval(startTime, processingInterval, indexHint, dataValues) { let count = 0; let index = -1; for (let i = indexHint; i < dataValues.length; i++) { if (dataValues[i].sourceTimestamp.getTime() < startTime.getTime()) { continue; } index = i; break; } if (index >= 0) { for (let i = index; i < dataValues.length; i++) { if (dataValues[i].sourceTimestamp.getTime() >= startTime.getTime() + processingInterval) { break; } count++; } } // check if interval is complete or partial (end or start) let isPartial = false; if (index + count >= dataValues.length && dataValues[dataValues.length - 1].sourceTimestamp.getTime() < startTime.getTime() + processingInterval) { isPartial = true; } if (index <= 0 && dataValues[0].sourceTimestamp.getTime() > startTime.getTime()) { isPartial = true; } return new Interval({ count, dataValues, index, isPartial, startTime, processingInterval }); } //# sourceMappingURL=interval.js.map