UNPKG

@corvina/device-client

Version:
499 lines 17.2 kB
"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