node-red-contrib-uos-nats 0.1.0

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/README.md +92 -0
  2. package/icons/white/datahub-input.svg +4 -0
  3. package/icons/white/datahub-output.svg +4 -0
  4. package/lib/auth.js +27 -0
  5. package/lib/config.js +23 -0
  6. package/lib/consumer.js +41 -0
  7. package/lib/fbs/weidmueller/ucontrol/hub/duration.js +67 -0
  8. package/lib/fbs/weidmueller/ucontrol/hub/provider-definition-changed-event.js +69 -0
  9. package/lib/fbs/weidmueller/ucontrol/hub/provider-definition-state.js +20 -0
  10. package/lib/fbs/weidmueller/ucontrol/hub/provider-definition.js +118 -0
  11. package/lib/fbs/weidmueller/ucontrol/hub/provider-list.js +76 -0
  12. package/lib/fbs/weidmueller/ucontrol/hub/provider.js +59 -0
  13. package/lib/fbs/weidmueller/ucontrol/hub/providers-changed-event.js +69 -0
  14. package/lib/fbs/weidmueller/ucontrol/hub/read-provider-definition-query-request.js +51 -0
  15. package/lib/fbs/weidmueller/ucontrol/hub/read-provider-definition-query-response.js +68 -0
  16. package/lib/fbs/weidmueller/ucontrol/hub/read-providers-query-request.js +51 -0
  17. package/lib/fbs/weidmueller/ucontrol/hub/read-providers-query-response.js +69 -0
  18. package/lib/fbs/weidmueller/ucontrol/hub/read-variables-query-request.js +88 -0
  19. package/lib/fbs/weidmueller/ucontrol/hub/read-variables-query-response.js +69 -0
  20. package/lib/fbs/weidmueller/ucontrol/hub/state-changed-event.js +67 -0
  21. package/lib/fbs/weidmueller/ucontrol/hub/state.js +14 -0
  22. package/lib/fbs/weidmueller/ucontrol/hub/timestamp.js +62 -0
  23. package/lib/fbs/weidmueller/ucontrol/hub/uuid.js +43 -0
  24. package/lib/fbs/weidmueller/ucontrol/hub/variable-access-type.js +17 -0
  25. package/lib/fbs/weidmueller/ucontrol/hub/variable-data-type.js +15 -0
  26. package/lib/fbs/weidmueller/ucontrol/hub/variable-definition.js +115 -0
  27. package/lib/fbs/weidmueller/ucontrol/hub/variable-list.js +106 -0
  28. package/lib/fbs/weidmueller/ucontrol/hub/variable-quality.js +31 -0
  29. package/lib/fbs/weidmueller/ucontrol/hub/variable-value-boolean.js +57 -0
  30. package/lib/fbs/weidmueller/ucontrol/hub/variable-value-duration.js +58 -0
  31. package/lib/fbs/weidmueller/ucontrol/hub/variable-value-float64.js +57 -0
  32. package/lib/fbs/weidmueller/ucontrol/hub/variable-value-int64.js +57 -0
  33. package/lib/fbs/weidmueller/ucontrol/hub/variable-value-string.js +58 -0
  34. package/lib/fbs/weidmueller/ucontrol/hub/variable-value-timestamp.js +58 -0
  35. package/lib/fbs/weidmueller/ucontrol/hub/variable-value.js +45 -0
  36. package/lib/fbs/weidmueller/ucontrol/hub/variable.js +131 -0
  37. package/lib/fbs/weidmueller/ucontrol/hub/variables-changed-event.js +71 -0
  38. package/lib/fbs/weidmueller/ucontrol/hub/write-variables-command.js +69 -0
  39. package/lib/fbs/weidmueller/ucontrol/hub.js +17 -0
  40. package/lib/models.js +1 -0
  41. package/lib/payloads.js +182 -0
  42. package/lib/provider.js +51 -0
  43. package/lib/simulation.js +54 -0
  44. package/lib/subjects.js +11 -0
  45. package/nodes/datahub-input.html +157 -0
  46. package/nodes/datahub-input.js +129 -0
  47. package/nodes/datahub-output.html +36 -0
  48. package/nodes/datahub-output.js +189 -0
  49. package/nodes/uos-config.html +48 -0
  50. package/nodes/uos-config.js +173 -0
  51. package/package.json +25 -0
@@ -0,0 +1,131 @@
1
+ // automatically generated by the FlatBuffers compiler, do not modify
2
+ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
3
+ import * as flatbuffers from 'flatbuffers';
4
+ import { Timestamp } from '../../../weidmueller/ucontrol/hub/timestamp.js';
5
+ import { VariableQuality } from '../../../weidmueller/ucontrol/hub/variable-quality.js';
6
+ import { VariableValue, unionToVariableValue } from '../../../weidmueller/ucontrol/hub/variable-value.js';
7
+ /**
8
+ * A variable associated with the provider's definition.
9
+ */
10
+ export class Variable {
11
+ constructor() {
12
+ this.bb = null;
13
+ this.bb_pos = 0;
14
+ }
15
+ __init(i, bb) {
16
+ this.bb_pos = i;
17
+ this.bb = bb;
18
+ return this;
19
+ }
20
+ static getRootAsVariable(bb, obj) {
21
+ return (obj || new Variable()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
22
+ }
23
+ static getSizePrefixedRootAsVariable(bb, obj) {
24
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
25
+ return (obj || new Variable()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
26
+ }
27
+ valueType() {
28
+ const offset = this.bb.__offset(this.bb_pos, 4);
29
+ return offset ? this.bb.readUint8(this.bb_pos + offset) : VariableValue.NONE;
30
+ }
31
+ /**
32
+ * The value of the variable.
33
+ */
34
+ value(obj) {
35
+ const offset = this.bb.__offset(this.bb_pos, 6);
36
+ return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
37
+ }
38
+ /**
39
+ * The ID of the variable associated with the provider's definition.
40
+ */
41
+ id() {
42
+ const offset = this.bb.__offset(this.bb_pos, 8);
43
+ return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
44
+ }
45
+ /**
46
+ * The individual timestamp of the variable.
47
+ *
48
+ * Only set by the provider!
49
+ * Consumers can left this empty. This value is ignored by the provider in
50
+ * a write command.
51
+ */
52
+ timestamp(obj) {
53
+ const offset = this.bb.__offset(this.bb_pos, 10);
54
+ return offset ? (obj || new Timestamp()).__init(this.bb_pos + offset, this.bb) : null;
55
+ }
56
+ /**
57
+ * The quality of the variable.
58
+ *
59
+ * Only set by the provider!
60
+ * Consumers can set it to BAD. This value is ignored by the provider
61
+ * in a write command.
62
+ */
63
+ quality() {
64
+ const offset = this.bb.__offset(this.bb_pos, 12);
65
+ return offset ? this.bb.readUint8(this.bb_pos + offset) : VariableQuality.BAD;
66
+ }
67
+ static startVariable(builder) {
68
+ builder.startObject(5);
69
+ }
70
+ static addValueType(builder, valueType) {
71
+ builder.addFieldInt8(0, valueType, VariableValue.NONE);
72
+ }
73
+ static addValue(builder, valueOffset) {
74
+ builder.addFieldOffset(1, valueOffset, 0);
75
+ }
76
+ static addId(builder, id) {
77
+ builder.addFieldInt32(2, id, 0);
78
+ }
79
+ static addTimestamp(builder, timestampOffset) {
80
+ builder.addFieldStruct(3, timestampOffset, 0);
81
+ }
82
+ static addQuality(builder, quality) {
83
+ builder.addFieldInt8(4, quality, VariableQuality.BAD);
84
+ }
85
+ static endVariable(builder) {
86
+ const offset = builder.endObject();
87
+ builder.requiredField(offset, 6); // value
88
+ return offset;
89
+ }
90
+ unpack() {
91
+ return new VariableT(this.valueType(), (() => {
92
+ const temp = unionToVariableValue(this.valueType(), this.value.bind(this));
93
+ if (temp === null) {
94
+ return null;
95
+ }
96
+ return temp.unpack();
97
+ })(), this.id(), (this.timestamp() !== null ? this.timestamp().unpack() : null), this.quality());
98
+ }
99
+ unpackTo(_o) {
100
+ _o.valueType = this.valueType();
101
+ _o.value = (() => {
102
+ const temp = unionToVariableValue(this.valueType(), this.value.bind(this));
103
+ if (temp === null) {
104
+ return null;
105
+ }
106
+ return temp.unpack();
107
+ })();
108
+ _o.id = this.id();
109
+ _o.timestamp = (this.timestamp() !== null ? this.timestamp().unpack() : null);
110
+ _o.quality = this.quality();
111
+ }
112
+ }
113
+ export class VariableT {
114
+ constructor(valueType = VariableValue.NONE, value = null, id = 0, timestamp = null, quality = VariableQuality.BAD) {
115
+ this.valueType = valueType;
116
+ this.value = value;
117
+ this.id = id;
118
+ this.timestamp = timestamp;
119
+ this.quality = quality;
120
+ }
121
+ pack(builder) {
122
+ const value = builder.createObjectOffset(this.value);
123
+ Variable.startVariable(builder);
124
+ Variable.addValueType(builder, this.valueType);
125
+ Variable.addValue(builder, value);
126
+ Variable.addId(builder, this.id);
127
+ Variable.addTimestamp(builder, (this.timestamp !== null ? this.timestamp.pack(builder) : 0));
128
+ Variable.addQuality(builder, this.quality);
129
+ return Variable.endVariable(builder);
130
+ }
131
+ }
@@ -0,0 +1,71 @@
1
+ // automatically generated by the FlatBuffers compiler, do not modify
2
+ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
3
+ import * as flatbuffers from 'flatbuffers';
4
+ import { VariableList } from '../../../weidmueller/ucontrol/hub/variable-list.js';
5
+ /**
6
+ * An event that describes a provider's list of variables that have just
7
+ * changed.
8
+ */
9
+ export class VariablesChangedEvent {
10
+ constructor() {
11
+ this.bb = null;
12
+ this.bb_pos = 0;
13
+ }
14
+ __init(i, bb) {
15
+ this.bb_pos = i;
16
+ this.bb = bb;
17
+ return this;
18
+ }
19
+ static getRootAsVariablesChangedEvent(bb, obj) {
20
+ return (obj || new VariablesChangedEvent()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
21
+ }
22
+ static getSizePrefixedRootAsVariablesChangedEvent(bb, obj) {
23
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
24
+ return (obj || new VariablesChangedEvent()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
25
+ }
26
+ /**
27
+ * A list of variables that have just been changed.
28
+ * Only contains changed variables!
29
+ */
30
+ changedVariables(obj) {
31
+ const offset = this.bb.__offset(this.bb_pos, 4);
32
+ return offset ? (obj || new VariableList()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
33
+ }
34
+ static startVariablesChangedEvent(builder) {
35
+ builder.startObject(1);
36
+ }
37
+ static addChangedVariables(builder, changedVariablesOffset) {
38
+ builder.addFieldOffset(0, changedVariablesOffset, 0);
39
+ }
40
+ static endVariablesChangedEvent(builder) {
41
+ const offset = builder.endObject();
42
+ builder.requiredField(offset, 4); // changed_variables
43
+ return offset;
44
+ }
45
+ static finishVariablesChangedEventBuffer(builder, offset) {
46
+ builder.finish(offset);
47
+ }
48
+ static finishSizePrefixedVariablesChangedEventBuffer(builder, offset) {
49
+ builder.finish(offset, undefined, true);
50
+ }
51
+ static createVariablesChangedEvent(builder, changedVariablesOffset) {
52
+ VariablesChangedEvent.startVariablesChangedEvent(builder);
53
+ VariablesChangedEvent.addChangedVariables(builder, changedVariablesOffset);
54
+ return VariablesChangedEvent.endVariablesChangedEvent(builder);
55
+ }
56
+ unpack() {
57
+ return new VariablesChangedEventT((this.changedVariables() !== null ? this.changedVariables().unpack() : null));
58
+ }
59
+ unpackTo(_o) {
60
+ _o.changedVariables = (this.changedVariables() !== null ? this.changedVariables().unpack() : null);
61
+ }
62
+ }
63
+ export class VariablesChangedEventT {
64
+ constructor(changedVariables = null) {
65
+ this.changedVariables = changedVariables;
66
+ }
67
+ pack(builder) {
68
+ const changedVariables = (this.changedVariables !== null ? this.changedVariables.pack(builder) : 0);
69
+ return VariablesChangedEvent.createVariablesChangedEvent(builder, changedVariables);
70
+ }
71
+ }
@@ -0,0 +1,69 @@
1
+ // automatically generated by the FlatBuffers compiler, do not modify
2
+ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
3
+ import * as flatbuffers from 'flatbuffers';
4
+ import { VariableList } from '../../../weidmueller/ucontrol/hub/variable-list.js';
5
+ /**
6
+ * A command writing a list of provider variables.
7
+ */
8
+ export class WriteVariablesCommand {
9
+ constructor() {
10
+ this.bb = null;
11
+ this.bb_pos = 0;
12
+ }
13
+ __init(i, bb) {
14
+ this.bb_pos = i;
15
+ this.bb = bb;
16
+ return this;
17
+ }
18
+ static getRootAsWriteVariablesCommand(bb, obj) {
19
+ return (obj || new WriteVariablesCommand()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
20
+ }
21
+ static getSizePrefixedRootAsWriteVariablesCommand(bb, obj) {
22
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
23
+ return (obj || new WriteVariablesCommand()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
24
+ }
25
+ /**
26
+ * A list of variables that have to be written.
27
+ */
28
+ variables(obj) {
29
+ const offset = this.bb.__offset(this.bb_pos, 4);
30
+ return offset ? (obj || new VariableList()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
31
+ }
32
+ static startWriteVariablesCommand(builder) {
33
+ builder.startObject(1);
34
+ }
35
+ static addVariables(builder, variablesOffset) {
36
+ builder.addFieldOffset(0, variablesOffset, 0);
37
+ }
38
+ static endWriteVariablesCommand(builder) {
39
+ const offset = builder.endObject();
40
+ builder.requiredField(offset, 4); // variables
41
+ return offset;
42
+ }
43
+ static finishWriteVariablesCommandBuffer(builder, offset) {
44
+ builder.finish(offset);
45
+ }
46
+ static finishSizePrefixedWriteVariablesCommandBuffer(builder, offset) {
47
+ builder.finish(offset, undefined, true);
48
+ }
49
+ static createWriteVariablesCommand(builder, variablesOffset) {
50
+ WriteVariablesCommand.startWriteVariablesCommand(builder);
51
+ WriteVariablesCommand.addVariables(builder, variablesOffset);
52
+ return WriteVariablesCommand.endWriteVariablesCommand(builder);
53
+ }
54
+ unpack() {
55
+ return new WriteVariablesCommandT((this.variables() !== null ? this.variables().unpack() : null));
56
+ }
57
+ unpackTo(_o) {
58
+ _o.variables = (this.variables() !== null ? this.variables().unpack() : null);
59
+ }
60
+ }
61
+ export class WriteVariablesCommandT {
62
+ constructor(variables = null) {
63
+ this.variables = variables;
64
+ }
65
+ pack(builder) {
66
+ const variables = (this.variables !== null ? this.variables.pack(builder) : 0);
67
+ return WriteVariablesCommand.createWriteVariablesCommand(builder, variables);
68
+ }
69
+ }
@@ -0,0 +1,17 @@
1
+ // automatically generated by the FlatBuffers compiler, do not modify
2
+ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
3
+ export { Duration, DurationT } from './hub/duration.js';
4
+ export { Timestamp, TimestampT } from './hub/timestamp.js';
5
+ export { Variable, VariableT } from './hub/variable.js';
6
+ export { VariableAccessType } from './hub/variable-access-type.js';
7
+ export { VariableDataType } from './hub/variable-data-type.js';
8
+ export { VariableDefinition, VariableDefinitionT } from './hub/variable-definition.js';
9
+ export { VariableList, VariableListT } from './hub/variable-list.js';
10
+ export { VariableQuality } from './hub/variable-quality.js';
11
+ export { VariableValue } from './hub/variable-value.js';
12
+ export { VariableValueBoolean, VariableValueBooleanT } from './hub/variable-value-boolean.js';
13
+ export { VariableValueDuration, VariableValueDurationT } from './hub/variable-value-duration.js';
14
+ export { VariableValueFloat64, VariableValueFloat64T } from './hub/variable-value-float64.js';
15
+ export { VariableValueInt64, VariableValueInt64T } from './hub/variable-value-int64.js';
16
+ export { VariableValueString, VariableValueStringT } from './hub/variable-value-string.js';
17
+ export { VariableValueTimestamp, VariableValueTimestampT } from './hub/variable-value-timestamp.js';
package/lib/models.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,182 @@
1
+ import { createHash } from 'node:crypto';
2
+ import * as flatbuffers from 'flatbuffers';
3
+ import { ProviderDefinitionChangedEventT } from './fbs/weidmueller/ucontrol/hub/provider-definition-changed-event.js';
4
+ import { ProviderDefinitionT } from './fbs/weidmueller/ucontrol/hub/provider-definition.js';
5
+ import { VariableDefinitionT } from './fbs/weidmueller/ucontrol/hub/variable-definition.js';
6
+ import { VariableAccessType } from './fbs/weidmueller/ucontrol/hub/variable-access-type.js';
7
+ import { VariableDataType } from './fbs/weidmueller/ucontrol/hub/variable-data-type.js';
8
+ import { VariablesChangedEventT } from './fbs/weidmueller/ucontrol/hub/variables-changed-event.js';
9
+ import { VariableListT } from './fbs/weidmueller/ucontrol/hub/variable-list.js';
10
+ import { VariableT } from './fbs/weidmueller/ucontrol/hub/variable.js';
11
+ import { VariableQuality } from './fbs/weidmueller/ucontrol/hub/variable-quality.js';
12
+ import { VariableValue } from './fbs/weidmueller/ucontrol/hub/variable-value.js';
13
+ import { VariableValueInt64, VariableValueInt64T } from './fbs/weidmueller/ucontrol/hub/variable-value-int64.js';
14
+ import { VariableValueFloat64, VariableValueFloat64T } from './fbs/weidmueller/ucontrol/hub/variable-value-float64.js';
15
+ import { VariableValueString, VariableValueStringT } from './fbs/weidmueller/ucontrol/hub/variable-value-string.js';
16
+ import { VariableValueBoolean, VariableValueBooleanT } from './fbs/weidmueller/ucontrol/hub/variable-value-boolean.js';
17
+ import { TimestampT } from './fbs/weidmueller/ucontrol/hub/timestamp.js';
18
+ import { ReadVariablesQueryResponseT } from './fbs/weidmueller/ucontrol/hub/read-variables-query-response.js';
19
+ import { ReadVariablesQueryRequestT } from './fbs/weidmueller/ucontrol/hub/read-variables-query-request.js';
20
+ const DEFAULT_QUALITY = 'GOOD';
21
+ export function buildProviderDefinitionEvent(defs) {
22
+ const fingerprint = computeFingerprint(defs);
23
+ const providerDefinition = new ProviderDefinitionT();
24
+ providerDefinition.fingerprint = fingerprint;
25
+ providerDefinition.variableDefinitions = defs.map(toFlatDefinition);
26
+ const event = new ProviderDefinitionChangedEventT(providerDefinition);
27
+ const builder = new flatbuffers.Builder(1024);
28
+ const offset = event.pack(builder);
29
+ builder.finish(offset);
30
+ return { payload: builder.asUint8Array(), fingerprint };
31
+ }
32
+ export function buildVariablesChangedEvent(defs, states, fingerprint) {
33
+ const varList = buildVariableList(defs, states, fingerprint);
34
+ const event = new VariablesChangedEventT(varList);
35
+ const builder = new flatbuffers.Builder(1024);
36
+ builder.finish(event.pack(builder));
37
+ return builder.asUint8Array();
38
+ }
39
+ export function buildReadVariablesResponse(defs, states, fingerprint) {
40
+ const varList = buildVariableList(defs, states, fingerprint);
41
+ const response = new ReadVariablesQueryResponseT(varList);
42
+ const builder = new flatbuffers.Builder(1024);
43
+ builder.finish(response.pack(builder));
44
+ return builder.asUint8Array();
45
+ }
46
+ export function buildReadVariablesQuery(ids) {
47
+ const query = new ReadVariablesQueryRequestT(ids ?? []);
48
+ const builder = new flatbuffers.Builder(128);
49
+ builder.finish(query.pack(builder));
50
+ return builder.asUint8Array();
51
+ }
52
+ export function decodeVariableList(list) {
53
+ if (!list)
54
+ return [];
55
+ const result = [];
56
+ for (let i = 0; i < list.itemsLength(); i += 1) {
57
+ const item = list.items(i);
58
+ if (!item)
59
+ continue;
60
+ let decoded;
61
+ switch (item.valueType()) {
62
+ case VariableValue.Int64: {
63
+ const holder = new VariableValueInt64();
64
+ item.value(holder);
65
+ decoded = Number(holder.value());
66
+ break;
67
+ }
68
+ case VariableValue.Float64: {
69
+ const holder = new VariableValueFloat64();
70
+ item.value(holder);
71
+ decoded = holder.value();
72
+ break;
73
+ }
74
+ case VariableValue.Boolean: {
75
+ const holder = new VariableValueBoolean();
76
+ item.value(holder);
77
+ decoded = !!holder.value();
78
+ break;
79
+ }
80
+ case VariableValue.String:
81
+ default: {
82
+ const holder = new VariableValueString();
83
+ item.value(holder);
84
+ decoded = holder.value()?.toString() ?? '';
85
+ break;
86
+ }
87
+ }
88
+ const ts = item.timestamp();
89
+ const seconds = ts ? Number(ts.seconds()) : 0;
90
+ const nanos = ts ? ts.nanos() : 0;
91
+ result.push({
92
+ id: item.id(),
93
+ value: decoded,
94
+ timestampNs: seconds * 1000000000 + nanos,
95
+ quality: DEFAULT_QUALITY,
96
+ });
97
+ }
98
+ return result;
99
+ }
100
+ function toFlatDefinition(def) {
101
+ const result = new VariableDefinitionT();
102
+ result.id = def.id;
103
+ result.key = def.key;
104
+ result.experimental = Boolean(def.experimental);
105
+ result.dataType = mapDataType(def.dataType);
106
+ result.accessType = def.access === 'READ_WRITE' ? VariableAccessType.READ_WRITE : VariableAccessType.READ_ONLY;
107
+ return result;
108
+ }
109
+ function buildVariableList(defs, states, fingerprint) {
110
+ const statesMap = new Map(states.map((s) => [s.id, s]));
111
+ const items = [];
112
+ for (const def of defs) {
113
+ const state = statesMap.get(def.id);
114
+ if (!state)
115
+ continue;
116
+ const variable = new VariableT();
117
+ variable.id = def.id;
118
+ const [valueType, value] = toValueUnion(def.dataType, state.value);
119
+ variable.valueType = valueType;
120
+ variable.value = value;
121
+ variable.timestamp = toTimestamp(state.timestampNs);
122
+ variable.quality = VariableQuality.GOOD;
123
+ items.push(variable);
124
+ }
125
+ const list = new VariableListT();
126
+ list.providerDefinitionFingerprint = fingerprint;
127
+ list.baseTimestamp = items.length ? (items[0].timestamp ?? toTimestamp(Date.now() * 1000000)) : toTimestamp(Date.now() * 1000000);
128
+ list.items = items;
129
+ return list;
130
+ }
131
+ function toTimestamp(ns) {
132
+ const ts = new TimestampT();
133
+ ts.seconds = BigInt(Math.floor(ns / 1000000000));
134
+ ts.nanos = ns % 1000000000;
135
+ return ts;
136
+ }
137
+ function toValueUnion(type, value) {
138
+ switch (type) {
139
+ case 'INT64': {
140
+ const holder = new VariableValueInt64T();
141
+ holder.value = BigInt(Math.trunc(Number(value)));
142
+ return [VariableValue.Int64, holder];
143
+ }
144
+ case 'FLOAT64': {
145
+ const holder = new VariableValueFloat64T();
146
+ holder.value = Number(value);
147
+ return [VariableValue.Float64, holder];
148
+ }
149
+ case 'BOOLEAN': {
150
+ const holder = new VariableValueBooleanT();
151
+ holder.value = Boolean(value);
152
+ return [VariableValue.Boolean, holder];
153
+ }
154
+ case 'STRING':
155
+ default: {
156
+ const holder = new VariableValueStringT();
157
+ holder.value = String(value);
158
+ return [VariableValue.String, holder];
159
+ }
160
+ }
161
+ }
162
+ function mapDataType(type) {
163
+ switch (type) {
164
+ case 'INT64':
165
+ return VariableDataType.INT64;
166
+ case 'FLOAT64':
167
+ return VariableDataType.FLOAT64;
168
+ case 'BOOLEAN':
169
+ return VariableDataType.BOOLEAN;
170
+ case 'STRING':
171
+ default:
172
+ return VariableDataType.STRING;
173
+ }
174
+ }
175
+ function computeFingerprint(defs) {
176
+ const hash = createHash('sha256');
177
+ for (const def of [...defs].sort((a, b) => a.id - b.id)) {
178
+ hash.update(`${def.id}:${def.key}:${def.dataType}:${def.access}:${def.experimental ?? false}`);
179
+ }
180
+ const digest = hash.digest();
181
+ return digest.readBigUInt64BE(0);
182
+ }
@@ -0,0 +1,51 @@
1
+ import { connect } from 'nats';
2
+ import { requestToken } from './auth.js';
3
+ import { CLIENT_NAME, NATS_SERVER, PROVIDER_ID, PUBLISH_INTERVAL_MS, VARIABLE_DEFINITIONS, } from './config.js';
4
+ import { SimulationEngine } from './simulation.js';
5
+ import { buildProviderDefinitionEvent, buildReadVariablesResponse, buildVariablesChangedEvent, } from './payloads.js';
6
+ import { providerDefinitionChanged, readVariablesQuery, varsChangedEvent } from './subjects.js';
7
+ async function main() {
8
+ console.log(`[provider] Node Provider für ${PROVIDER_ID} wird gestartet…`);
9
+ const token = await requestToken();
10
+ const nc = await connect({
11
+ servers: NATS_SERVER.split(','),
12
+ token,
13
+ name: `${CLIENT_NAME}-node-provider`,
14
+ inboxPrefix: `_INBOX.${CLIENT_NAME}`,
15
+ });
16
+ console.log('[provider] NATS verbunden:', nc.getServer());
17
+ const simulation = new SimulationEngine(VARIABLE_DEFINITIONS);
18
+ const { payload: definitionPayload, fingerprint } = buildProviderDefinitionEvent(VARIABLE_DEFINITIONS);
19
+ await nc.publish(providerDefinitionChanged(PROVIDER_ID), definitionPayload);
20
+ const readSubject = readVariablesQuery(PROVIDER_ID);
21
+ const sub = nc.subscribe(readSubject, {
22
+ callback: async (err, msg) => {
23
+ if (err) {
24
+ console.error('[provider] Fehler beim Read-Subscribe', err);
25
+ return;
26
+ }
27
+ if (!msg.reply)
28
+ return;
29
+ const responsePayload = buildReadVariablesResponse(VARIABLE_DEFINITIONS, simulation.snapshot(), fingerprint);
30
+ await nc.publish(msg.reply, responsePayload);
31
+ },
32
+ });
33
+ const timer = setInterval(async () => {
34
+ const states = simulation.advance();
35
+ const payload = buildVariablesChangedEvent(VARIABLE_DEFINITIONS, states, fingerprint);
36
+ await nc.publish(varsChangedEvent(PROVIDER_ID), payload);
37
+ }, PUBLISH_INTERVAL_MS);
38
+ const shutdown = async () => {
39
+ clearInterval(timer);
40
+ sub.drain();
41
+ await nc.drain();
42
+ console.log('[provider] Verbindung geschlossen');
43
+ process.exit(0);
44
+ };
45
+ process.on('SIGINT', shutdown);
46
+ process.on('SIGTERM', shutdown);
47
+ }
48
+ main().catch((err) => {
49
+ console.error('[provider] Fehler:', err);
50
+ process.exit(1);
51
+ });
@@ -0,0 +1,54 @@
1
+ export class SimulationEngine {
2
+ constructor(definitions) {
3
+ this.definitions = definitions;
4
+ this.tick = 0;
5
+ this.states = new Map(definitions.map((def) => [def.id, {
6
+ id: def.id,
7
+ value: this.initialValue(def),
8
+ timestampNs: Date.now() * 1000000,
9
+ quality: 'GOOD',
10
+ }]));
11
+ }
12
+ initialValue(def) {
13
+ switch (def.dataType) {
14
+ case 'INT64':
15
+ return 0;
16
+ case 'FLOAT64':
17
+ return 0;
18
+ case 'BOOLEAN':
19
+ return false;
20
+ case 'STRING':
21
+ default:
22
+ return def.key.includes('status') ? 'ready' : '';
23
+ }
24
+ }
25
+ advance() {
26
+ this.tick += 1;
27
+ const nowNs = Date.now() * 1000000;
28
+ for (const def of this.definitions) {
29
+ const state = this.states.get(def.id);
30
+ state.timestampNs = nowNs;
31
+ switch (def.dataType) {
32
+ case 'INT64':
33
+ state.value = Number(state.value) + 1;
34
+ break;
35
+ case 'FLOAT64':
36
+ state.value = Number((20 + Math.sin(this.tick / 5) * 5).toFixed(3));
37
+ break;
38
+ case 'STRING':
39
+ if (def.key.includes('status')) {
40
+ const values = ['ready', 'running', 'idle'];
41
+ state.value = values[this.tick % values.length];
42
+ }
43
+ break;
44
+ case 'BOOLEAN':
45
+ state.value = !Boolean(state.value);
46
+ break;
47
+ }
48
+ }
49
+ return Array.from(this.states.values());
50
+ }
51
+ snapshot() {
52
+ return Array.from(this.states.values());
53
+ }
54
+ }
@@ -0,0 +1,11 @@
1
+ const VERSION_PREFIX = 'v1';
2
+ const LOCATION_PREFIX = 'loc';
3
+ export function varsChangedEvent(providerId) {
4
+ return `${VERSION_PREFIX}.${LOCATION_PREFIX}.${providerId}.vars.evt.changed`;
5
+ }
6
+ export function readVariablesQuery(providerId) {
7
+ return `${VERSION_PREFIX}.${LOCATION_PREFIX}.${providerId}.vars.qry.read`;
8
+ }
9
+ export function providerDefinitionChanged(providerId) {
10
+ return `${VERSION_PREFIX}.${LOCATION_PREFIX}.${providerId}.def.evt.changed`;
11
+ }