node-opcua-aggregates
Version: 
pure nodejs OPCUA SDK - module aggregates
117 lines • 5.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateBadAndGood = calculateBadAndGood;
const node_opcua_status_code_1 = require("node-opcua-status-code");
const interval_1 = require("./interval");
const a = (s, options) => !s || s === node_opcua_status_code_1.StatusCodes.BadNoData
    ? node_opcua_status_code_1.StatusCodes.BadNoData
    : s.isBad() || (options.treatUncertainAsBad && (0, interval_1.isUncertain)(s))
        ? node_opcua_status_code_1.StatusCodes.Bad
        : node_opcua_status_code_1.StatusCodes.Good;
function findLowBound(interval, options) {
    const indexStart = interval.index;
    const initialValue = interval.dataValues[indexStart];
    if (initialValue.sourceTimestamp.getTime() === interval.startTime.getTime()) {
        return { previousStatus: initialValue.statusCode, previousTime: interval.startTime.getTime(), indexStart: indexStart + 1 };
    }
    const previousStatus = indexStart === 0 || !interval.dataValues[indexStart - 1]
        ? node_opcua_status_code_1.StatusCodes.BadNoData
        : a(interval.dataValues[indexStart - 1].statusCode, options);
    const previousTime = interval.startTime.getTime();
    return { previousStatus, previousTime, indexStart };
}
// eslint-disable-next-line max-statements, complexity
function calculateBadAndGood(interval, options) {
    if (interval.count === 0) {
        return {
            durationGood: 0,
            durationBad: 0,
            durationUnknown: 0,
            percentBad: 0,
            percentGood: 0,
            statusCode: node_opcua_status_code_1.StatusCodes.BadNoData
        };
    }
    let durationGood = 0;
    let durationBad = 0;
    let durationUnknown = 0;
    let partialFlag = interval.isPartial ? node_opcua_status_code_1.extraStatusCodeBits.HistorianPartial : 0;
    let { previousStatus, previousTime, indexStart } = findLowBound(interval, options);
    if (previousStatus === node_opcua_status_code_1.StatusCodes.BadNoData) {
        partialFlag = node_opcua_status_code_1.extraStatusCodeBits.HistorianPartial;
        previousStatus = node_opcua_status_code_1.StatusCodes.Bad;
    }
    let nbGood = 0;
    let nbBad = 0;
    let nbUncertain = 0;
    indexStart += 0;
    for (let i = indexStart; i < interval.index + interval.count; i++) {
        const dataValue = interval.dataValues[i];
        if (dataValue.statusCode.isGoodish()) {
            nbGood++;
        }
        if ((0, interval_1.isUncertain)(dataValue.statusCode)) {
            nbUncertain++;
        }
        if (dataValue.statusCode.isBad()) {
            nbBad++;
        }
        const currentStatus = a(dataValue.statusCode, options);
        if (currentStatus === node_opcua_status_code_1.StatusCodes.BadNoData) {
            partialFlag = node_opcua_status_code_1.extraStatusCodeBits.HistorianPartial;
        }
        const currentTime = dataValue.sourceTimestamp.getTime();
        // debugLog(" ", dataValue.sourceTimestamp?.toISOString(), dataValue.statusCode.toString(), dataValue.value.value);
        if (currentStatus === previousStatus)
            continue;
        if (previousStatus === node_opcua_status_code_1.StatusCodes.Good) {
            // if (isBadWithUncertain(currentStatus, options.treatUncertainAsBad)) {
            //     durationBad += currentTime - previousTime;
            // } else {
            durationGood += currentTime - previousTime;
            // }
        }
        else if (previousStatus === node_opcua_status_code_1.StatusCodes.BadNoData) {
            durationUnknown += currentTime - previousTime;
        }
        else {
            durationBad += currentTime - previousTime;
        }
        previousStatus = currentStatus;
        previousTime = currentTime;
    }
    // final step
    const currentTime = interval.getEffectiveEndTime();
    if (previousStatus === node_opcua_status_code_1.StatusCodes.Good) {
        durationGood += currentTime - previousTime;
    }
    else if (previousStatus === node_opcua_status_code_1.StatusCodes.BadNoData) {
        durationUnknown += currentTime - previousTime;
    }
    else {
        durationBad += currentTime - previousTime;
    }
    if (nbGood === 0) {
        if (nbBad > 0) {
            // we need at lest a Good Status in the intervale to be good & no bad !
            durationGood = -1;
        }
        else {
            durationGood = 0;
        }
    }
    const effectiveProcessingInterval = currentTime - interval.startTime.getTime();
    const percentGood = (durationGood / effectiveProcessingInterval) * 100;
    const percentBad = (durationBad / effectiveProcessingInterval) * 100;
    let percentDataGood = options.percentDataGood === undefined ? 100 : options.percentDataGood;
    const percentDataBad = options.percentDataBad === undefined ? 100 : options.percentDataBad;
    if (percentBad >= percentDataBad || (nbGood === 0 && nbUncertain === 0)) {
        durationGood = 0; // BAD
        percentDataGood = -1;
        // const statusCode = StatusCodes.Bad;
        //return { durationGood, durationBad, durationUnknown, percentBad, percentGood, statusCode };
    }
    const statusCode = node_opcua_status_code_1.StatusCode.makeStatusCode(node_opcua_status_code_1.StatusCodes.Good, node_opcua_status_code_1.extraStatusCodeBits.HistorianCalculated | partialFlag);
    return { durationGood, durationBad, durationUnknown, percentBad, percentGood, statusCode };
}
//# sourceMappingURL=calculate_bad_good.js.map