@corvina/device-client 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/CONTRIBUTING.md +31 -0
  3. package/LICENSE +21 -0
  4. package/README.md +138 -0
  5. package/dist/common/types.d.ts +89 -0
  6. package/dist/common/types.js +65 -0
  7. package/dist/common/types.js.map +1 -0
  8. package/dist/device.module.d.ts +2 -0
  9. package/dist/device.module.js +41 -0
  10. package/dist/device.module.js.map +1 -0
  11. package/dist/index.d.ts +6 -0
  12. package/dist/index.js +22 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/services/configparser.d.ts +232 -0
  15. package/dist/services/configparser.js +458 -0
  16. package/dist/services/configparser.js.map +1 -0
  17. package/dist/services/corvinadatainterface.d.ts +24 -0
  18. package/dist/services/corvinadatainterface.js +107 -0
  19. package/dist/services/corvinadatainterface.js.map +1 -0
  20. package/dist/services/device.service.d.ts +77 -0
  21. package/dist/services/device.service.js +464 -0
  22. package/dist/services/device.service.js.map +1 -0
  23. package/dist/services/devicerunner.interface.d.ts +3 -0
  24. package/dist/services/devicerunner.interface.js +3 -0
  25. package/dist/services/devicerunner.interface.js.map +1 -0
  26. package/dist/services/devicerunner.service.d.ts +8 -0
  27. package/dist/services/devicerunner.service.js +123 -0
  28. package/dist/services/devicerunner.service.js.map +1 -0
  29. package/dist/services/licensesaxiosinstance.d.ts +29 -0
  30. package/dist/services/licensesaxiosinstance.js +77 -0
  31. package/dist/services/licensesaxiosinstance.js.map +1 -0
  32. package/dist/services/logger.service.d.ts +8 -0
  33. package/dist/services/logger.service.js +9 -0
  34. package/dist/services/logger.service.js.map +1 -0
  35. package/dist/services/messagepublisher.d.ts +69 -0
  36. package/dist/services/messagepublisher.js +154 -0
  37. package/dist/services/messagepublisher.js.map +1 -0
  38. package/dist/services/messagepublisherpolicies.d.ts +222 -0
  39. package/dist/services/messagepublisherpolicies.js +499 -0
  40. package/dist/services/messagepublisherpolicies.js.map +1 -0
  41. package/dist/services/messagesender.d.ts +17 -0
  42. package/dist/services/messagesender.js +3 -0
  43. package/dist/services/messagesender.js.map +1 -0
  44. package/dist/services/messagesubscriber.d.ts +17 -0
  45. package/dist/services/messagesubscriber.js +32 -0
  46. package/dist/services/messagesubscriber.js.map +1 -0
  47. package/dist/services/simulation.d.ts +83 -0
  48. package/dist/services/simulation.js +610 -0
  49. package/dist/services/simulation.js.map +1 -0
  50. package/envs.md +67 -0
  51. package/package.json +105 -0
@@ -0,0 +1,83 @@
1
+ import { AlarmDesc, SimulationDesc } from "../common/types";
2
+ declare enum StepSimulationState {
3
+ STABLE = 0,
4
+ TRANSITION = 1
5
+ }
6
+ interface StepSimulationStateMachine {
7
+ state: StepSimulationState;
8
+ origin: number;
9
+ target: number;
10
+ current: number;
11
+ duration: number;
12
+ start: number;
13
+ }
14
+ export interface StepSimulationProperties extends SimulationDesc {
15
+ amplitude: number;
16
+ offset: number;
17
+ easing: string;
18
+ easingProps?: any;
19
+ jump_probability: number;
20
+ dt_min: number;
21
+ dt_max: number;
22
+ state?: StepSimulationStateMachine;
23
+ }
24
+ export interface SineSimulationProperties extends SimulationDesc {
25
+ amplitude: number;
26
+ offset: number;
27
+ period: number;
28
+ phase: number;
29
+ }
30
+ export interface FunctionSimulationProperties extends SimulationDesc {
31
+ f: string;
32
+ _f?: ($: any) => any;
33
+ }
34
+ export interface ConstSimulationProperties extends SimulationDesc {
35
+ value: number;
36
+ }
37
+ interface AbstractSimulator {
38
+ loop(): any;
39
+ }
40
+ export declare class BaseSimulator implements AbstractSimulator {
41
+ tag: string;
42
+ depsOut: Map<string, BaseSimulator>;
43
+ value: any;
44
+ lastSentValue: any;
45
+ static simulators: BaseSimulator[];
46
+ static simulatorsByTagName: Map<string, BaseSimulator>;
47
+ static inited: boolean;
48
+ static sorted: boolean;
49
+ static intervalID: any;
50
+ static filterDuplications: boolean;
51
+ static simulationMs: number;
52
+ constructor(tag: string);
53
+ static $: (source: BaseSimulator, tagName: string) => any;
54
+ loop(): void;
55
+ }
56
+ export declare class DataSimulator extends BaseSimulator {
57
+ private callback;
58
+ private type;
59
+ private defAmplitude;
60
+ private defPhase;
61
+ private defPeriod;
62
+ private desc;
63
+ constructor(tag: string, type: string, callback: (tagName: string, value: number, ts: number) => Promise<boolean>, desc: SimulationDesc);
64
+ applyNoise(v: number, min?: number, max?: number): number;
65
+ nullify(v: any, callback?: (nullifyingPrev: boolean, nullifyingCurrent: boolean) => void): any;
66
+ loop(): Promise<void>;
67
+ static clear(): void;
68
+ }
69
+ export declare class AlarmSimulator extends BaseSimulator {
70
+ private callback;
71
+ private alarm;
72
+ private alarmData;
73
+ private tagRefs;
74
+ static alarmSimulatorMapkey(alarmName: string): string;
75
+ constructor(alarm: AlarmDesc, callback: (AlarmData: any) => Promise<boolean>);
76
+ acknoledge(evTs: number, user: string, comment: string): void;
77
+ reset(evTs: number, user: string, comment: string): void;
78
+ disable(): void;
79
+ enable(): void;
80
+ private propagate;
81
+ loop(): Promise<void>;
82
+ }
83
+ export {};
@@ -0,0 +1,610 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AlarmSimulator = exports.DataSimulator = exports.BaseSimulator = void 0;
7
+ const mustache_1 = __importDefault(require("mustache"));
8
+ const types_1 = require("../common/types");
9
+ const ease = require("d3-ease");
10
+ const timers_1 = require("timers");
11
+ const logger_service_1 = require("./logger.service");
12
+ var StepSimulationState;
13
+ (function (StepSimulationState) {
14
+ StepSimulationState[StepSimulationState["STABLE"] = 0] = "STABLE";
15
+ StepSimulationState[StepSimulationState["TRANSITION"] = 1] = "TRANSITION";
16
+ })(StepSimulationState || (StepSimulationState = {}));
17
+ class BaseSimulator {
18
+ tag;
19
+ depsOut;
20
+ value;
21
+ lastSentValue;
22
+ static simulators = new Array();
23
+ static simulatorsByTagName;
24
+ static inited = false;
25
+ static sorted = false;
26
+ static intervalID = null;
27
+ static filterDuplications;
28
+ static simulationMs;
29
+ constructor(tag) {
30
+ this.tag = tag;
31
+ if (!BaseSimulator.simulatorsByTagName) {
32
+ BaseSimulator.simulatorsByTagName = new Map();
33
+ }
34
+ BaseSimulator.filterDuplications = !!(() => {
35
+ try {
36
+ return JSON.parse(process.env.FILTER_DUPS);
37
+ }
38
+ catch (err) {
39
+ return true;
40
+ }
41
+ })();
42
+ BaseSimulator.simulationMs = (() => {
43
+ try {
44
+ return JSON.parse(process.env.SIMULATION_MS);
45
+ }
46
+ catch (err) {
47
+ return 1000;
48
+ }
49
+ })();
50
+ if (!BaseSimulator.inited) {
51
+ BaseSimulator.intervalID = setInterval(() => {
52
+ if (!BaseSimulator.inited || !BaseSimulator.sorted) {
53
+ let idx = BaseSimulator.simulatorsByTagName.size;
54
+ BaseSimulator.simulators = new Array(idx);
55
+ for (const [k, d] of BaseSimulator.simulatorsByTagName) {
56
+ d.visited = false;
57
+ }
58
+ const visit = (n) => {
59
+ if (n.visited == true) {
60
+ return false;
61
+ }
62
+ n.visited = true;
63
+ if (n.depsOut) {
64
+ for (const [k, v] of n.depsOut) {
65
+ visit(v);
66
+ }
67
+ }
68
+ idx--;
69
+ if (idx < 0) {
70
+ return false;
71
+ }
72
+ BaseSimulator.simulators[idx] = n;
73
+ return true;
74
+ };
75
+ for (const [k, d] of BaseSimulator.simulatorsByTagName) {
76
+ visit(d);
77
+ }
78
+ BaseSimulator.sorted = true;
79
+ }
80
+ BaseSimulator.simulators.forEach((value) => {
81
+ try {
82
+ value.loop();
83
+ }
84
+ catch (e) {
85
+ logger_service_1.l.error("Error in simulation: ", e);
86
+ }
87
+ });
88
+ }, BaseSimulator.simulationMs);
89
+ BaseSimulator.inited = true;
90
+ }
91
+ }
92
+ static $ = (source, tagName) => {
93
+ const target = BaseSimulator.simulatorsByTagName.get(tagName);
94
+ if (target == undefined) {
95
+ logger_service_1.l.error(`Cannot resolve dependency ${tagName}`);
96
+ return;
97
+ }
98
+ if (!target.depsOut) {
99
+ target.depsOut = new Map();
100
+ }
101
+ if (!target.depsOut.has(source.tag)) {
102
+ logger_service_1.l.debug(`Tracked dependency from ${source.tag} to ${target.tag}`);
103
+ target.depsOut.set(source.tag, source);
104
+ BaseSimulator.sorted = false;
105
+ }
106
+ return target.value;
107
+ };
108
+ loop() {
109
+ }
110
+ }
111
+ exports.BaseSimulator = BaseSimulator;
112
+ class DataSimulator extends BaseSimulator {
113
+ callback;
114
+ type;
115
+ defAmplitude;
116
+ defPhase;
117
+ defPeriod;
118
+ desc;
119
+ constructor(tag, type, callback, desc) {
120
+ super(tag);
121
+ this.type = type;
122
+ this.desc = desc;
123
+ DataSimulator.simulatorsByTagName.set(tag, this);
124
+ if (tag.indexOf(".") >= 0) {
125
+ const structName = tag.split(".")[0];
126
+ let structSimulator = DataSimulator.simulatorsByTagName.get(structName);
127
+ if (!structSimulator) {
128
+ structSimulator = new DataSimulator(structName, "struct", callback, desc);
129
+ }
130
+ BaseSimulator.$(this, structName);
131
+ }
132
+ else {
133
+ this.callback = callback;
134
+ }
135
+ this.defAmplitude = 500 * Math.random();
136
+ this.defPhase = Math.random() * 4 * Math.PI;
137
+ this.defPeriod = Math.random() * 30000;
138
+ }
139
+ applyNoise(v, min = -Infinity, max = Infinity) {
140
+ const props = this.desc;
141
+ if (props.noise) {
142
+ let noised = v;
143
+ if (props.noise.type == types_1.NoiseSimulationType.ABSOLUTE) {
144
+ noised = v + (Math.random() - 0.5) * props.noise.amplitude;
145
+ }
146
+ else {
147
+ noised = v + (Math.random() - 0.5) * ((v * props.noise.amplitude) / 100);
148
+ }
149
+ if (noised < min) {
150
+ return min;
151
+ }
152
+ if (noised > max) {
153
+ return max;
154
+ }
155
+ return noised;
156
+ }
157
+ return v;
158
+ }
159
+ nullify(v, callback = null) {
160
+ const props = this.desc;
161
+ if (props.nullable) {
162
+ if (!props.nullable.state) {
163
+ props.nullable.state = {
164
+ nullifying: false,
165
+ duration: 0,
166
+ start: 0,
167
+ };
168
+ }
169
+ const oldState = props.nullable.state.nullifying;
170
+ const dice = Math.random();
171
+ const now = Date.now();
172
+ if (!props.nullable.state.nullifying) {
173
+ if (dice < props.nullable.probability) {
174
+ props.nullable.state.nullifying = true;
175
+ props.nullable.state.start = now;
176
+ props.nullable.state.duration =
177
+ BaseSimulator.simulationMs *
178
+ (props.nullable.dt_min + Math.random() * (props.nullable.dt_max - props.nullable.dt_min));
179
+ }
180
+ }
181
+ else {
182
+ if (now > props.nullable.state.start + props.nullable.state.duration) {
183
+ props.nullable.state.nullifying = false;
184
+ }
185
+ }
186
+ if (callback) {
187
+ callback(oldState, props.nullable.state.nullifying);
188
+ }
189
+ if (props.nullable.state.nullifying == true) {
190
+ if (typeof v == "number") {
191
+ return 0;
192
+ }
193
+ else if (typeof v == "boolean") {
194
+ return false;
195
+ }
196
+ else {
197
+ return "";
198
+ }
199
+ }
200
+ }
201
+ return v;
202
+ }
203
+ async loop() {
204
+ const ts = Date.now();
205
+ this.value = null;
206
+ if (this.type == "struct") {
207
+ if (!this.value) {
208
+ this.value = {};
209
+ }
210
+ Array.from(this.depsOut.values()).forEach((x) => {
211
+ this.value[x.tag.slice(this.tag.length + 1)] = x.value;
212
+ });
213
+ }
214
+ else {
215
+ if (!this.desc) {
216
+ switch (this.type) {
217
+ case "integer":
218
+ this.value = (Math.random() * this.defAmplitude) | 0;
219
+ break;
220
+ case "boolean":
221
+ this.value = Math.random() > this.defPeriod;
222
+ break;
223
+ case "double":
224
+ this.value = this.defAmplitude * Math.sin(this.defPhase + (ts * 2 * Math.PI) / this.defPeriod);
225
+ break;
226
+ case "string":
227
+ this.value = Math.random().toString();
228
+ break;
229
+ default:
230
+ throw "Unsupported type " + this.type;
231
+ }
232
+ }
233
+ else {
234
+ switch (this.desc.type) {
235
+ case types_1.SimulationType.FUNCTION:
236
+ {
237
+ const props = this.desc;
238
+ try {
239
+ if (!props._f) {
240
+ props._f = new Function("$", props.f);
241
+ }
242
+ this.value = props._f.call(this, (t) => {
243
+ return BaseSimulator.$(this, t);
244
+ });
245
+ }
246
+ catch (e) {
247
+ logger_service_1.l.error("Error evaluating", e);
248
+ }
249
+ if (this.value == null || this.value == undefined) {
250
+ return;
251
+ }
252
+ const noised = this.applyNoise(this.value);
253
+ switch (this.type) {
254
+ case "integer":
255
+ this.value = ~~noised;
256
+ break;
257
+ case "boolean":
258
+ this.value = ~~noised > this.defPeriod;
259
+ break;
260
+ case "double":
261
+ this.value = noised;
262
+ break;
263
+ case "string":
264
+ this.value =
265
+ typeof noised == "string" || noised instanceof String
266
+ ? noised
267
+ : JSON.stringify(noised);
268
+ break;
269
+ default:
270
+ throw "Unsupported type " + this.type;
271
+ }
272
+ this.value = this.nullify(this.value);
273
+ }
274
+ break;
275
+ case types_1.SimulationType.CONST:
276
+ {
277
+ const props = this.desc;
278
+ const noised = this.applyNoise(props.value);
279
+ switch (this.type) {
280
+ case "integer":
281
+ this.value = ~~noised;
282
+ break;
283
+ case "boolean":
284
+ this.value = ~~noised > this.defPeriod;
285
+ break;
286
+ case "double":
287
+ this.value = noised;
288
+ break;
289
+ case "string":
290
+ this.value =
291
+ typeof noised == "string" || noised instanceof String
292
+ ? noised
293
+ : JSON.stringify(noised);
294
+ break;
295
+ default:
296
+ throw "Unsupported type " + this.type;
297
+ }
298
+ this.value = this.nullify(this.value);
299
+ }
300
+ break;
301
+ case types_1.SimulationType.SINE:
302
+ {
303
+ const props = this.desc;
304
+ const v = this.applyNoise(props.offset +
305
+ props.amplitude *
306
+ Math.sin(props.phase +
307
+ (ts * 2 * Math.PI) / (BaseSimulator.simulationMs * props.period)));
308
+ switch (this.type) {
309
+ case "integer":
310
+ this.value = ~~v;
311
+ this.value = this.nullify(this.value);
312
+ break;
313
+ case "boolean":
314
+ this.value = Math.random() > this.defPeriod;
315
+ break;
316
+ case "double":
317
+ this.value = v;
318
+ break;
319
+ case "string":
320
+ this.value =
321
+ typeof v == "string" || v instanceof String ? v : JSON.stringify(v);
322
+ break;
323
+ default:
324
+ throw "Unsupported type " + this.type;
325
+ }
326
+ this.value = this.nullify(this.value);
327
+ }
328
+ break;
329
+ case types_1.SimulationType.STEP:
330
+ {
331
+ const props = this.desc;
332
+ const f = ease[props.easing];
333
+ if (props.easingProps) {
334
+ Object.assign(f, props.easingProps);
335
+ }
336
+ const fun = f;
337
+ const computeNewTarget = () => {
338
+ props.state.state = StepSimulationState.TRANSITION;
339
+ props.state.origin = props.state.current;
340
+ const rand = Math.random() - 0.5;
341
+ props.state.target = props.state.origin + rand * props.amplitude;
342
+ if (props.state.target > props.offset + props.amplitude) {
343
+ props.state.target = props.state.origin - rand * props.amplitude;
344
+ }
345
+ if (props.state.target < props.offset) {
346
+ props.state.target = props.state.origin - rand * props.amplitude;
347
+ }
348
+ const rand2 = Math.random();
349
+ props.state.duration =
350
+ BaseSimulator.simulationMs * (props.dt_min + rand2 * (props.dt_max - props.dt_min));
351
+ props.state.start = ts;
352
+ };
353
+ if (!props.state) {
354
+ props.state = {};
355
+ props.state.current = props.offset + props.amplitude / 2;
356
+ computeNewTarget();
357
+ }
358
+ const jumpRand = Math.random();
359
+ if (jumpRand < props.jump_probability) {
360
+ computeNewTarget();
361
+ }
362
+ let v = props.offset;
363
+ if (props.state.state == StepSimulationState.TRANSITION) {
364
+ const dt = ts - props.state.start;
365
+ if (dt > props.state.duration) {
366
+ props.state.state = StepSimulationState.STABLE;
367
+ v = props.state.target;
368
+ }
369
+ else {
370
+ props.state.current =
371
+ props.state.origin +
372
+ (props.state.target - props.state.origin) * fun(dt / props.state.duration);
373
+ v = props.state.current;
374
+ }
375
+ }
376
+ else {
377
+ v = props.state.current;
378
+ }
379
+ const noised = this.applyNoise(v, props.offset, props.offset + props.amplitude);
380
+ switch (this.type) {
381
+ case "integer":
382
+ this.value = ~~noised;
383
+ break;
384
+ case "boolean":
385
+ this.value = ~~noised > this.defPeriod;
386
+ break;
387
+ case "double":
388
+ this.value = noised;
389
+ break;
390
+ case "string":
391
+ this.value =
392
+ typeof noised == "string" || noised instanceof String
393
+ ? noised
394
+ : JSON.stringify(noised);
395
+ break;
396
+ default:
397
+ throw "Unsupported type " + this.type;
398
+ }
399
+ this.nullify(this.value, (o, n) => {
400
+ if (n == true) {
401
+ this.value = 0;
402
+ }
403
+ if (o == true && n == false) {
404
+ this.value = props.offset;
405
+ props.state.current = props.offset;
406
+ computeNewTarget();
407
+ }
408
+ });
409
+ }
410
+ break;
411
+ }
412
+ }
413
+ }
414
+ if (!BaseSimulator.filterDuplications || JSON.stringify(this.value) != JSON.stringify(this.lastSentValue)) {
415
+ try {
416
+ if (this.callback && (await this.callback(this.tag, this.value, ts))) {
417
+ this.lastSentValue = this.value;
418
+ }
419
+ }
420
+ catch (e) { }
421
+ }
422
+ }
423
+ static clear() {
424
+ DataSimulator.sorted = false;
425
+ BaseSimulator.inited = false;
426
+ BaseSimulator.simulatorsByTagName && BaseSimulator.simulatorsByTagName.clear();
427
+ (0, timers_1.clearInterval)(BaseSimulator.intervalID);
428
+ }
429
+ }
430
+ exports.DataSimulator = DataSimulator;
431
+ class AlarmSimulator extends BaseSimulator {
432
+ callback;
433
+ alarm;
434
+ alarmData;
435
+ tagRefs;
436
+ static alarmSimulatorMapkey(alarmName) {
437
+ return `Alarm.${alarmName}`;
438
+ }
439
+ constructor(alarm, callback) {
440
+ super(alarm.source);
441
+ this.alarm = alarm;
442
+ this.alarm.enabled = true;
443
+ this.callback = callback;
444
+ this.alarmData = {
445
+ sev: this.alarm.severity,
446
+ tag: this.alarm.source,
447
+ name: this.alarm.name,
448
+ state: this.alarm.enabled ? types_1.AlarmState.ALARM_ENABLED : types_1.AlarmState.ALARM_NONE,
449
+ };
450
+ if (this.alarm.desc && this.alarm.desc["en"]) {
451
+ this.tagRefs = {};
452
+ const tokens = mustache_1.default.parse(this.alarm.desc["en"], ["[", "]"]);
453
+ for (const t of tokens) {
454
+ if (t[0] == "name") {
455
+ this.tagRefs[t[1]] = null;
456
+ }
457
+ }
458
+ }
459
+ BaseSimulator.simulatorsByTagName.set(AlarmSimulator.alarmSimulatorMapkey(alarm.name), this);
460
+ }
461
+ acknoledge(evTs, user, comment) {
462
+ if (evTs != this.alarmData.evTs.valueOf()) {
463
+ logger_service_1.l.warn(`Trying to reset alarm ${this.alarmData.name}:${evTs} but current active event timestamp is ${this.alarmData.evTs}`);
464
+ const fakeAck = {
465
+ name: this.alarmData.name,
466
+ desc: this.alarmData.desc,
467
+ ts: new Date(),
468
+ evTs: new Date(evTs),
469
+ sev: this.alarmData.sev,
470
+ tag: this.alarmData.tag,
471
+ state: types_1.AlarmState.ALARM_ENABLED,
472
+ };
473
+ this.callback(fakeAck);
474
+ }
475
+ else {
476
+ if (this.alarmData.state & types_1.AlarmState.ALARM_REQUIRES_ACK) {
477
+ this.alarmData.state &= ~types_1.AlarmState.ALARM_REQUIRES_ACK;
478
+ this.alarmData.state |= types_1.AlarmState.ALARM_ACKED;
479
+ if (this.alarm.reset_required) {
480
+ this.alarmData.state |= types_1.AlarmState.ALARM_REQUIRES_RESET;
481
+ }
482
+ logger_service_1.l.log(`Alarm ${this.alarmData.name} acknowledged by ${user} : ${comment}`);
483
+ this.propagate();
484
+ }
485
+ else {
486
+ logger_service_1.l.warn(`Alarm ${this.alarmData.name} does not require ack`);
487
+ }
488
+ }
489
+ }
490
+ reset(evTs, user, comment) {
491
+ if (evTs != this.alarmData.evTs.valueOf()) {
492
+ logger_service_1.l.warn(`Trying to reset alarm ${this.alarmData.name}:${evTs} but current active event timestamp is ${this.alarmData.evTs}`);
493
+ const fakeReset = {
494
+ name: this.alarmData.name,
495
+ desc: this.alarmData.desc,
496
+ ts: new Date(),
497
+ evTs: new Date(evTs),
498
+ sev: this.alarmData.sev,
499
+ tag: this.alarmData.tag,
500
+ state: types_1.AlarmState.ALARM_ENABLED,
501
+ };
502
+ this.callback(fakeReset);
503
+ }
504
+ else {
505
+ if (this.alarmData.state & types_1.AlarmState.ALARM_REQUIRES_RESET) {
506
+ if (!(this.alarmData.state & types_1.AlarmState.ALARM_ACTIVE)) {
507
+ this.alarmData.state &= ~(types_1.AlarmState.ALARM_ACKED | types_1.AlarmState.ALARM_REQUIRES_RESET);
508
+ logger_service_1.l.log(`Alarm ${this.alarmData.name} reset by ${user} : ${comment}`);
509
+ this.propagate();
510
+ }
511
+ else {
512
+ logger_service_1.l.warn(`Cannot reset active alarm ${this.alarmData.name}`);
513
+ }
514
+ }
515
+ else {
516
+ logger_service_1.l.warn(`Alarm ${this.alarmData.name} does not require reset`);
517
+ }
518
+ }
519
+ }
520
+ disable() {
521
+ this.alarmData.state &= ~(types_1.AlarmState.ALARM_ENABLED |
522
+ types_1.AlarmState.ALARM_ACKED |
523
+ types_1.AlarmState.ALARM_REQUIRES_ACK |
524
+ types_1.AlarmState.ALARM_REQUIRES_RESET);
525
+ }
526
+ enable() {
527
+ this.alarmData.state |= types_1.AlarmState.ALARM_ENABLED;
528
+ this.loop();
529
+ }
530
+ async propagate() {
531
+ try {
532
+ const tagValue = BaseSimulator.$(this, this.alarm.source);
533
+ switch (typeof tagValue) {
534
+ case "number":
535
+ this.alarmData.v_d = tagValue;
536
+ break;
537
+ case "string":
538
+ this.alarmData.v_s = tagValue;
539
+ break;
540
+ case "boolean":
541
+ this.alarmData.v_b = tagValue;
542
+ break;
543
+ default:
544
+ throw "Unsupported type " + typeof tagValue;
545
+ }
546
+ if (this.tagRefs) {
547
+ for (const r in this.tagRefs) {
548
+ this.tagRefs[r] = BaseSimulator.$(this, r);
549
+ }
550
+ this.alarmData.desc = mustache_1.default.render(this.alarm.desc["en"], this.tagRefs, {}, ["[", "]"]);
551
+ }
552
+ this.alarmData.ts = new Date();
553
+ if (await this.callback(this.alarmData)) {
554
+ logger_service_1.l.debug("Updated alarm value ", this.lastSentValue, this.value, this.alarmData);
555
+ }
556
+ }
557
+ catch (e) {
558
+ logger_service_1.l.error(e);
559
+ }
560
+ }
561
+ async loop() {
562
+ if (!this.alarm.simulation) {
563
+ return;
564
+ }
565
+ const ts = Date.now();
566
+ this.value = null;
567
+ {
568
+ const props = this.alarm.simulation;
569
+ try {
570
+ if (!props._f) {
571
+ props._f = new Function("$", "$src", props.f);
572
+ }
573
+ this.value = props._f.call(this, (t) => {
574
+ return BaseSimulator.$(this, t), BaseSimulator.$(this, this.alarm.source);
575
+ });
576
+ }
577
+ catch (e) {
578
+ logger_service_1.l.error("Error evaluating", e);
579
+ }
580
+ if (this.value == null || this.value == undefined) {
581
+ return;
582
+ }
583
+ }
584
+ const changedValue = JSON.stringify(this.value) != JSON.stringify(this.lastSentValue);
585
+ if (changedValue) {
586
+ if (this.value) {
587
+ this.alarmData.state |= types_1.AlarmState.ALARM_ACTIVE;
588
+ }
589
+ else {
590
+ this.alarmData.state &= ~types_1.AlarmState.ALARM_ACTIVE;
591
+ }
592
+ if (this.alarmData.state & types_1.AlarmState.ALARM_ACTIVE &&
593
+ !(this.alarmData.state & (types_1.AlarmState.ALARM_REQUIRES_ACK | types_1.AlarmState.ALARM_REQUIRES_RESET))) {
594
+ this.alarmData.evTs = new Date();
595
+ }
596
+ if (this.alarm.ack_required && this.value && !(this.alarmData.state & types_1.AlarmState.ALARM_ACKED)) {
597
+ this.alarmData.state |= types_1.AlarmState.ALARM_REQUIRES_ACK;
598
+ }
599
+ if (!this.alarm.enabled && !this.value) {
600
+ this.alarmData.state &= ~types_1.AlarmState.ALARM_REQUIRES_ACK;
601
+ }
602
+ if (this.alarm.enabled && this.alarmData.evTs) {
603
+ await this.propagate();
604
+ }
605
+ this.lastSentValue = this.value;
606
+ }
607
+ }
608
+ }
609
+ exports.AlarmSimulator = AlarmSimulator;
610
+ //# sourceMappingURL=simulation.js.map