@corvina/device-client
Version:
Corvina NodeJS Device Client
499 lines • 17.2 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessagePublisher_OnFieldLevelPolicy = exports.MessagePublisher_OnLevelPolicy = exports.LevelMode = exports.MessagePublisher_OnFieldChangedPolicy = exports.MessagePublisher_AnalogBandPolicy = exports.MessagePublisher_TimerPolicy = exports.MessagePublisher_OnChangedPolicy = exports.ChangeMask = exports.MessagePublisher_QualityPolicy = exports.MessagePublisher_OrPolicy = exports.MessagePublisher_AndPolicy = exports.MessagePublisher_OperatorPolicy = exports.MessagePublisherPolicy = exports.State = exports.Quality = exports.INVALID_STATE_TS = void 0;
const lodash_1 = __importDefault(require("lodash"));
exports.INVALID_STATE_TS = Number.MAX_SAFE_INTEGER;
var Quality;
(function (Quality) {
Quality[Quality["GOOD"] = 0] = "GOOD";
Quality[Quality["UNCERTAIN"] = 1] = "UNCERTAIN";
Quality[Quality["BAD"] = 2] = "BAD";
})(Quality = exports.Quality || (exports.Quality = {}));
class State {
value;
timestamp;
constructor(value, timestamp) {
this.value = value;
this.timestamp = timestamp;
}
get quality() {
if (this.value != undefined) {
return Quality.GOOD;
}
return Quality.UNCERTAIN;
}
clone() {
const s = new State(this.value, this.timestamp);
return s;
}
}
exports.State = State;
class MessagePublisherPolicy {
_nextTime;
constructor() {
this._nextTime = exports.INVALID_STATE_TS;
}
get nextTime() {
return this._nextTime;
}
rearm(currentTime) {
this._nextTime = exports.INVALID_STATE_TS;
return this._nextTime;
}
referencedTags() {
return [];
}
setDefaultTagName(tagName) {
}
setFieldTagName({ fieldName, tagName }) {
}
multiTagVersion(tags) {
return this.clone();
}
clone() {
return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
}
}
exports.MessagePublisherPolicy = MessagePublisherPolicy;
class MessagePublisher_OperatorPolicy extends MessagePublisherPolicy {
constructor(operands) {
super();
this._operands = operands;
}
addOperand(op) {
this._operands.push(op);
}
operand(i) {
return this._operands[i];
}
referencedTags() {
const referencedTags = [];
this._operands.forEach((o) => referencedTags.push(...o.referencedTags()));
return referencedTags;
}
setDefaultTagName(tagName) {
this._operands.forEach((o) => o.setDefaultTagName(tagName));
}
setFieldTagName({ fieldName, tagName }) {
this._operands.forEach((o) => o.setFieldTagName({ fieldName, tagName }));
}
updateState({ tagName, newState, currentTime, }) {
return exports.INVALID_STATE_TS;
}
multiTagVersion(tags) {
const clone = this.clone();
clone._operands = clone._operands.map((o) => o.multiTagVersion(tags));
return clone;
}
clear() {
this._operands = [];
}
toString() {
let ret;
for (let i = 0; i < this._operands.length; i++) {
ret += i == 0 ? "(" : ` ${this.operatorKeyword()} ` + `${this._operands[i].toString()})`;
}
return ret;
}
_operands;
clone() {
const cloned = super.clone();
cloned._operands = cloned._operands.map((o) => o.clone());
return cloned;
}
}
exports.MessagePublisher_OperatorPolicy = MessagePublisher_OperatorPolicy;
class MessagePublisher_AndPolicy extends MessagePublisher_OperatorPolicy {
constructor(operands) {
super(operands);
}
updateState({ tagName, newState, currentTime, }) {
this._nextTime = 0;
this._operands.forEach((o) => {
const bTime = o.updateState({ tagName, newState, currentTime });
this._nextTime = this._nextTime < bTime ? bTime : this._nextTime;
});
return this._nextTime;
}
rearm(currentTime) {
this._nextTime = 0;
this._operands.forEach((o) => {
const bTime = o.rearm(currentTime);
this._nextTime = this._nextTime < bTime ? bTime : this._nextTime;
});
return this._nextTime;
}
operatorKeyword() {
return "AND";
}
}
exports.MessagePublisher_AndPolicy = MessagePublisher_AndPolicy;
class MessagePublisher_OrPolicy extends MessagePublisher_OperatorPolicy {
constructor(operands) {
super(operands);
}
updateState({ tagName, newState, currentTime, }) {
this._nextTime = exports.INVALID_STATE_TS;
this._operands.forEach((o) => {
const bTime = o.updateState({ tagName, newState, currentTime });
this._nextTime = this._nextTime < bTime ? this._nextTime : bTime;
});
return this._nextTime;
}
rearm(currentTime) {
this._nextTime = exports.INVALID_STATE_TS;
this._operands.forEach((o) => {
const bTime = o.rearm(currentTime);
this._nextTime = this._nextTime < bTime ? this._nextTime : bTime;
});
return this._nextTime;
}
operatorKeyword() {
return "OR";
}
}
exports.MessagePublisher_OrPolicy = MessagePublisher_OrPolicy;
class MessagePublisher_TagBasedPolicy extends MessagePublisherPolicy {
constructor(tagName) {
super();
this._tagName = tagName;
}
get tagName() {
return this._tagName;
}
setDefaultTagName(tagName) {
if (!this._tagName || this._tagName.length === 0) {
this._tagName = tagName;
}
}
referencedTags() {
const referencedTags = [];
if (this._tagName && this._tagName.length !== 0)
referencedTags.push(this._tagName);
return referencedTags;
}
multiTagVersion(tags) {
if (this._tagName && this._tagName.length > 0) {
return this.clone();
}
const multiTagVersion = this.defaultMultitagOperator();
tags.forEach((t, i) => {
multiTagVersion.addOperand(this);
multiTagVersion.operand(i).setDefaultTagName(t);
});
return multiTagVersion;
}
toString() {
return `tag="${this._tagName}"`;
}
_tagName;
}
class MessagePublisher_QualityPolicy extends MessagePublisher_TagBasedPolicy {
_expectGood;
constructor({ tagName, expectGood }) {
super(tagName);
this._expectGood = expectGood;
}
updateState({ tagName, newState, currentTime, }) {
if (this._tagName && this._tagName.length != 0 && tagName != this._tagName) {
return this._nextTime;
}
this._nextTime = this._expectGood == (newState.quality == Quality.GOOD) ? 0 : exports.INVALID_STATE_TS;
return this._nextTime;
}
toString() {
return `${this._expectGood ? "qualitygood:" : "qualitybad:"}${super.toString()}`;
}
defaultMultitagOperator() {
return this._expectGood ? new MessagePublisher_AndPolicy() : new MessagePublisher_OrPolicy();
}
}
exports.MessagePublisher_QualityPolicy = MessagePublisher_QualityPolicy;
var ChangeMask;
(function (ChangeMask) {
ChangeMask[ChangeMask["ValueChange"] = 1] = "ValueChange";
ChangeMask[ChangeMask["QualityChange"] = 2] = "QualityChange";
ChangeMask[ChangeMask["SourceTimestampChange"] = 4] = "SourceTimestampChange";
ChangeMask[ChangeMask["AnyChange"] = 5] = "AnyChange";
})(ChangeMask = exports.ChangeMask || (exports.ChangeMask = {}));
class MessagePublisher_OnChangedPolicy extends MessagePublisher_TagBasedPolicy {
constructor({ tagName = "", changeMask = ChangeMask.ValueChange, skipFirstNChanges = 0, deadband = 0, isPercent = false, }) {
super(tagName);
this._lastState = new State();
this._changeMask = changeMask;
this._skipFirstNChanges = skipFirstNChanges;
this._deadband = deadband;
this._isPercent = isPercent;
}
updateState({ tagName, newState, currentTime, }) {
if (this._tagName && this._tagName.length != 0 && tagName != this._tagName) {
return this._nextTime;
}
let triggered = false;
if (this._changeMask & ChangeMask.ValueChange && newState.quality == Quality.GOOD) {
if (lodash_1.default.isArray(newState.value)) {
triggered =
newState.value.length != this._lastState?.value?.length ||
newState.value.reduce((acc, v, i) => {
return triggered || this.isOutOfDeadband(v, this._lastState[i]);
}, triggered);
}
else {
triggered = this.isOutOfDeadband(this._lastState.value, newState.value);
}
if (triggered) {
this._lastState.value = newState.value;
}
}
if (this._changeMask & ChangeMask.QualityChange && newState.quality != this._lastState.quality) {
this._lastState.value = newState.value;
triggered = true;
}
if (this._changeMask & ChangeMask.SourceTimestampChange && newState.timestamp != this._lastState.timestamp) {
this._lastState.timestamp = newState.timestamp;
triggered = true;
}
if (triggered) {
if (this._skipFirstNChanges > 0) {
this._skipFirstNChanges--;
}
else {
this._nextTime = 0;
}
}
return this._nextTime;
}
toString() {
return `onchange:${super.toString()}`;
}
defaultMultitagOperator() {
return new MessagePublisher_OrPolicy();
}
isOutOfDeadband(v1, v2) {
if (!lodash_1.default.isNumber(v1)) {
return !lodash_1.default.isEqual(v1, v2);
}
const delta = Math.abs(v1 - v2);
if (!this._isPercent) {
return delta > this._deadband;
}
const threshold = Math.abs((v1 * this._deadband) / 100.0);
return delta > threshold;
}
_lastState;
_changeMask;
_skipFirstNChanges;
_deadband;
_isPercent;
clone() {
const cloned = super.clone();
cloned._lastState = this._lastState.clone();
return cloned;
}
}
exports.MessagePublisher_OnChangedPolicy = MessagePublisher_OnChangedPolicy;
class MessagePublisher_TimerPolicy extends MessagePublisherPolicy {
constructor(interval = 1000) {
super();
this._interval = interval == 0 ? 1000 : interval;
this._nextTime = 0;
}
updateState({ tagName, newState, currentTime, }) {
return this._nextTime;
}
rearm(currentTime) {
this._nextTime = (1 + Math.floor(currentTime / this._interval)) * this._interval;
return this._nextTime;
}
toString() {
return `timer:${this._interval}`;
}
_interval;
}
exports.MessagePublisher_TimerPolicy = MessagePublisher_TimerPolicy;
class MessagePublisher_AnalogBandPolicy extends MessagePublisher_TagBasedPolicy {
_min;
_max;
_inside;
constructor({ tagName, min, max, inside }) {
super(tagName);
this._inside = inside;
this._min = min;
this._max = max;
if (!this._inside) {
this._nextTime = 0;
}
}
updateState({ tagName, newState, currentTime, }) {
if (this._tagName && this._tagName.length != 0 && tagName != this._tagName) {
return this._nextTime;
}
this._nextTime = 0;
if (lodash_1.default.isArray(newState.value)) {
for (const v of newState.value) {
if (!this.isInBand(v)) {
this._nextTime = exports.INVALID_STATE_TS;
break;
}
}
}
else {
if (!this.isInBand(newState.value)) {
this._nextTime = exports.INVALID_STATE_TS;
}
}
return this._nextTime;
}
toString() {
return `${this._inside ? "inband:" : "outband:"}${this._min},${this._max},${super.toString()}`;
}
defaultMultitagOperator() {
return new MessagePublisher_AndPolicy();
}
isInBand(v) {
if (!lodash_1.default.isNumber(v))
return true;
if (this._inside)
return v >= this._min && v <= this._max;
return v < this._min || v > this._max;
}
}
exports.MessagePublisher_AnalogBandPolicy = MessagePublisher_AnalogBandPolicy;
class MessagePublisher_OnFieldChangedPolicy extends MessagePublisher_OnChangedPolicy {
_fieldName;
constructor({ fieldName, changeMask = ChangeMask.ValueChange, skipFirstNChanges = 0, deadband = 0, isPercent = false, }) {
super({
tagName: "",
changeMask,
skipFirstNChanges,
deadband,
isPercent,
});
this._fieldName = fieldName;
}
setTagName(tagName) {
this._tagName = tagName;
}
get fieldName() {
return this._fieldName;
}
setFieldTagName({ fieldName, tagName }) {
if (this._fieldName == fieldName) {
this._tagName = tagName;
}
}
}
exports.MessagePublisher_OnFieldChangedPolicy = MessagePublisher_OnFieldChangedPolicy;
var LevelMode;
(function (LevelMode) {
LevelMode[LevelMode["OnEnter"] = 1] = "OnEnter";
LevelMode[LevelMode["OnExit"] = 2] = "OnExit";
LevelMode[LevelMode["OnEnterExit"] = 3] = "OnEnterExit";
})(LevelMode = exports.LevelMode || (exports.LevelMode = {}));
class MessagePublisher_OnLevelPolicy extends MessagePublisher_TagBasedPolicy {
_lastState;
_skipFirstNChanges;
_min;
_max;
_level;
_mode;
constructor({ tagName, level, levelMode = LevelMode.OnEnterExit, skipFirstNChanges = 0, deadband = 0, isPercent = false, }) {
super(tagName);
if (typeof level == "number") {
this._min = level - (isPercent ? (level * deadband) / 100 : deadband);
this._max = level + (isPercent ? (level * deadband) / 100 : deadband);
}
this._level = level;
this._mode = levelMode;
this._skipFirstNChanges = skipFirstNChanges;
this._lastState = new State();
}
toString() {
return `onlevel:${this._level},${super.toString()}`;
}
defaultMultitagOperator() {
return new MessagePublisher_OrPolicy();
}
updateState({ tagName, newState, currentTime, }) {
if (this._tagName && this._tagName.length != 0 && tagName != this._tagName) {
return this._nextTime;
}
let triggered = false;
if (newState.value != undefined) {
let inBand = false;
let wasInBand = false;
if (lodash_1.default.isArray(newState.value)) {
for (const i in newState.value) {
inBand = this.isInBand(newState.value[i]);
wasInBand = this.isInBand(this._lastState.value[i]);
if (inBand != wasInBand) {
break;
}
}
}
else {
inBand = this.isInBand(newState.value);
wasInBand = this.isInBand(this._lastState.value);
}
if (inBand != wasInBand) {
triggered =
(inBand && (this._mode & LevelMode.OnEnter) != 0) ||
(!inBand && (this._mode & LevelMode.OnExit) != 0);
this._lastState.value = newState;
}
}
if (triggered) {
if (this._skipFirstNChanges > 0) {
this._skipFirstNChanges--;
}
else {
this._nextTime = 0;
}
}
return this._nextTime;
}
isInBand(v) {
if (typeof v == "string") {
return v == this._level;
}
else if (typeof v == "number") {
return v >= this._min && v <= this._max;
}
}
clone() {
const cloned = super.clone();
cloned._lastState = this._lastState.clone();
return cloned;
}
}
exports.MessagePublisher_OnLevelPolicy = MessagePublisher_OnLevelPolicy;
class MessagePublisher_OnFieldLevelPolicy extends MessagePublisher_OnLevelPolicy {
_fieldName;
constructor({ fieldName, level, levelMode = LevelMode.OnEnterExit, skipFirstNChanges = 0, deadband = 0, isPercent = false, }) {
super({
tagName: "",
level,
levelMode,
skipFirstNChanges,
deadband,
isPercent,
});
this._fieldName = fieldName;
}
setTagName(tagName) {
this._tagName = tagName;
}
get fieldName() {
return this._fieldName;
}
setFieldTagName({ fieldName, tagName }) {
if (this._fieldName == fieldName) {
this._tagName = tagName;
}
}
}
exports.MessagePublisher_OnFieldLevelPolicy = MessagePublisher_OnFieldLevelPolicy;
//# sourceMappingURL=messagepublisherpolicies.js.map