@vitormnm/node-red-simple-opcua 1.4.2 → 1.4.3

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.
@@ -1,341 +1,341 @@
1
- const {
2
- StatusCodes,
3
- Variant,
4
- DataType
5
- } = require("./opcua-constants");
6
-
7
- class OpcUaAddressSpaceAlarm {
8
-
9
- constructor(options) {
10
- this.namespace = options.namespace;
11
- this.node = options.node;
12
- this.serverName = options.registry;
13
- this.registry = options.registry;
14
- this.alarmTypesByNamespace = new Map();
15
- }
16
-
17
- emitTagAccess(operation, details) {
18
- this.registry.emitTagAccess({
19
- operation,
20
- serverId: this.node.id,
21
- serverNodeName: this.node.name || "",
22
- serverName: this.serverName,
23
- timestamp: new Date().toISOString(),
24
- path: details.path,
25
- nodeID: details.nodeID,
26
- browseName: details.browseName,
27
- dataType: details.dataType,
28
- value: details.value
29
- });
30
- }
31
-
32
- createAlarm(namespace, browseName, parentNode, inputNode, conditionName, nodeId, sourceName, alarmConfig) {
33
- try {
34
- const type = alarmConfig.type;
35
- let alarmNode = null;
36
- const alarmTypes = this.ensureNamespaceTypes(namespace);
37
-
38
- const config = {
39
- browseName: browseName,
40
- componentOf: parentNode,
41
- inputNode: inputNode,
42
- conditionSource: parentNode,
43
- conditionName: conditionName,
44
- normalState: false,
45
- nodeId: nodeId,
46
- description: alarmConfig.description || "",
47
- namespace: namespace,
48
- optionals: [
49
- "ConfirmedState",
50
- "Confirm"
51
- ]
52
- };
53
-
54
- if (type === "digitalAlarm") {
55
- alarmNode = namespace.instantiateAlarmCondition(alarmTypes.digitalAlarmType, config);
56
- }
57
-
58
- if (type === "levelAlarm") {
59
- alarmNode = namespace.instantiateAlarmCondition(alarmTypes.levelAlarmType, config);
60
-
61
- alarmNode.getPropertyByName("lowLowLimit")
62
- .setValueFromSource({
63
- dataType: DataType.Int32,
64
- value: alarmConfig.lowLowLimit
65
- });
66
-
67
- alarmNode.getPropertyByName("lowLimit")
68
- .setValueFromSource({
69
- dataType: DataType.Int32,
70
- value: alarmConfig.lowLimit
71
- });
72
-
73
- alarmNode.getPropertyByName("highHighLimit")
74
- .setValueFromSource({
75
- dataType: DataType.Int32,
76
- value: alarmConfig.highHighLimit
77
- });
78
-
79
- alarmNode.getPropertyByName("highLimit")
80
- .setValueFromSource({
81
- dataType: DataType.Int32,
82
- value: alarmConfig.highLimit
83
- });
84
- }
85
-
86
- alarmNode.getPropertyByName("enabled")
87
- .setValueFromSource({
88
- dataType: DataType.Boolean,
89
- value: alarmConfig.enabled
90
- });
91
-
92
- alarmNode.sourceName.setValueFromSource({
93
- dataType: DataType.String,
94
- value: sourceName
95
- });
96
-
97
- return alarmNode;
98
- } catch (error) {
99
- console.error("createAlarm");
100
- console.error(error);
101
- }
102
- }
103
-
104
- checkAlarm(alarm, variableValue) {
105
- if (alarm) {
106
- const alarmConfig = alarm.alarmConfig;
107
- const type = alarmConfig.type;
108
-
109
- if (type === "levelAlarm") {
110
- this.levelAlarm(alarm, variableValue);
111
- }
112
- if (type === "digitalAlarm") {
113
- this.digitalAlarm(alarm, variableValue);
114
- }
115
- }
116
- }
117
-
118
- levelAlarm(alarm, variableValue) {
119
- const alarmNode = alarm.node;
120
- const alarmConfig = alarm.alarmConfig;
121
-
122
- const isActive = alarmNode.activeState.id.readValue().value.value;
123
- const highHighSp = alarmNode.getPropertyByName("highHighLimit").readValue().value.value;
124
- const highSp = alarmNode.getPropertyByName("highLimit").readValue().value.value;
125
- const lowSp = alarmNode.getPropertyByName("lowLimit").readValue().value.value;
126
- const lowLowSp = alarmNode.getPropertyByName("lowLowLimit").readValue().value.value;
127
- const enabled = alarmNode.getPropertyByName("enabled").readValue().value.value;
128
- let lastMessage = null;
129
- let message = null;
130
-
131
- if (variableValue >= highHighSp && enabled) {
132
- message = alarmConfig.highHighMessage + ": " + variableValue;
133
- this.raiseAlarm(alarmNode, message, alarmConfig.severity);
134
- lastMessage = message;
135
- } else if (variableValue >= highSp && enabled) {
136
- message = alarmConfig.highMessage + ": " + variableValue;
137
- this.raiseAlarm(alarmNode, message, alarmConfig.severity);
138
- lastMessage = message;
139
- } else if (variableValue <= lowLowSp && enabled) {
140
- message = alarmConfig.lowLowMessage + ": " + variableValue;
141
- this.raiseAlarm(alarmNode, message, alarmConfig.severity);
142
- lastMessage = message;
143
- } else if (variableValue <= lowSp && enabled) {
144
- message = alarmConfig.lowMessage + ": " + variableValue;
145
- this.raiseAlarm(alarmNode, message, alarmConfig.severity);
146
- lastMessage = message;
147
- } else if (isActive) {
148
- this.clearAlarm(alarmNode, lastMessage, alarmConfig.severity);
149
- }
150
-
151
- this.alarmMethods(alarmNode);
152
- }
153
-
154
- digitalAlarm(alarm, variableValue) {
155
- const alarmNode = alarm.node;
156
- const alarmConfig = alarm.alarmConfig;
157
- const enabled = alarmNode.getPropertyByName("enabled").readValue().value.value;
158
-
159
- if (variableValue && enabled) {
160
- this.raiseAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
161
- } else {
162
- this.clearAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
163
- }
164
-
165
- this.alarmMethods(alarmNode);
166
- }
167
-
168
- alarmMethods(alarmNode) {
169
- alarmNode.confirm.bindMethod((inputArguments, context, callback) => {
170
- const alarm = context.object;
171
- const severity = alarm.severity.readValue().value.value;
172
- const message = alarm.message.readValue().value.value.text;
173
- alarm.confirmedState.setValue(true);
174
-
175
- const isAcked = alarm.ackedState.id.readValue().value.value;
176
-
177
- if (isAcked) {
178
- alarm.raiseNewCondition({
179
- message: message,
180
- severity: severity,
181
- retain: false
182
- });
183
-
184
- this.raiseNewConditionAlarm(alarm, message, severity, false);
185
- } else {
186
- this.raiseNewConditionAlarm(alarm, message, severity, true);
187
- }
188
-
189
- callback(null, {
190
- statusCode: StatusCodes.Good,
191
- outputArguments: []
192
- });
193
- });
194
-
195
- alarmNode.acknowledge.bindMethod((inputArguments, context, callback) => {
196
- const alarm = context.object;
197
- const severity = alarm.severity.readValue().value.value;
198
- const message = alarm.message.readValue().value.value.text;
199
- alarm.ackedState.setValue(true);
200
- alarm.confirmedState.setValue(false);
201
-
202
- this.raiseNewConditionAlarm(alarm, message, severity, true);
203
-
204
- callback(null, {
205
- statusCode: StatusCodes.Good,
206
- outputArguments: []
207
- });
208
- });
209
-
210
- alarmNode.addComment.bindMethod((inputArguments, context, callback) => {
211
- const comment = inputArguments[1].value;
212
- const alarm = context.object;
213
-
214
- alarm.comment.setValueFromSource({
215
- value: comment,
216
- dataType: DataType.LocalizedText
217
- });
218
- callback(null, {
219
- statusCode: StatusCodes.Good,
220
- outputArguments: []
221
- });
222
- });
223
- }
224
-
225
- clearAlarm(alarmNode, message, severity) {
226
- const isAcked = !alarmNode.ackedState.id.readValue().value.value;
227
-
228
- alarmNode.activeState.setValue(false);
229
- alarmNode.raiseNewCondition({ message, severity: severity, isAcked });
230
-
231
- this.raiseNewConditionAlarm(alarmNode, message, severity, isAcked);
232
- }
233
-
234
- raiseAlarm(alarmNode, message, severity, retain = true) {
235
- const isActive = alarmNode.activeState.id.readValue().value.value;
236
- const isAcked = alarmNode.ackedState.id.readValue().value.value;
237
- if (isActive && isAcked) {
238
- alarmNode.activeState.setValue(false);
239
- alarmNode.ackedState.setValue(true);
240
- alarmNode.confirmedState.setValue(true);
241
- } else {
242
- alarmNode.ackedState.setValue(false);
243
- alarmNode.confirmedState.setValue(true);
244
- }
245
-
246
- alarmNode.activeState.setValue(true);
247
- this.raiseNewConditionAlarm(alarmNode, message, severity, retain);
248
- }
249
-
250
- raiseNewConditionAlarm(alarmNode, message, severity, retain) {
251
- alarmNode.raiseNewCondition({ message, severity, retain });
252
-
253
- this.registry.registerActiveAlarms(alarmNode, message, severity, retain, this.node);
254
-
255
- this.emitTagAccess("alarm", {
256
- message: message,
257
- severity: severity,
258
- retain: retain,
259
- dataType: "alarm",
260
- value: "highHighSp"
261
- });
262
- }
263
-
264
- ensureNamespaceTypes(namespace) {
265
- const namespaceKey = namespace.index;
266
- if (this.alarmTypesByNamespace.has(namespaceKey)) {
267
- return this.alarmTypesByNamespace.get(namespaceKey);
268
- }
269
-
270
- const types = this.createObjectType(namespace);
271
- this.alarmTypesByNamespace.set(namespaceKey, types);
272
- return types;
273
- }
274
-
275
- createObjectType(namespace) {
276
- const digitalAlarm = namespace.addObjectType({
277
- browseName: "digitalAlarm",
278
- subtypeOf: "OffNormalAlarmType"
279
- });
280
-
281
- const levelAlarm = namespace.addObjectType({
282
- browseName: "levelAlarm",
283
- subtypeOf: "OffNormalAlarmType"
284
- });
285
-
286
- namespace.addVariable({
287
- propertyOf: digitalAlarm,
288
- browseName: "enabled",
289
- dataType: "Boolean",
290
- modellingRule: "Mandatory",
291
- value: new Variant({ dataType: DataType.Boolean, value: true })
292
- });
293
-
294
- namespace.addVariable({
295
- propertyOf: levelAlarm,
296
- browseName: "enabled",
297
- dataType: "Boolean",
298
- modellingRule: "Mandatory",
299
- value: new Variant({ dataType: DataType.Boolean, value: true })
300
- });
301
-
302
- namespace.addVariable({
303
- propertyOf: levelAlarm,
304
- browseName: "highHighLimit",
305
- dataType: "Int32",
306
- modellingRule: "Mandatory",
307
- value: new Variant({ dataType: DataType.Int32, value: 0 })
308
- });
309
-
310
- namespace.addVariable({
311
- propertyOf: levelAlarm,
312
- browseName: "highLimit",
313
- dataType: "Int32",
314
- modellingRule: "Mandatory",
315
- value: new Variant({ dataType: DataType.Int32, value: 0 })
316
- });
317
-
318
- namespace.addVariable({
319
- propertyOf: levelAlarm,
320
- browseName: "lowLimit",
321
- dataType: "Int32",
322
- modellingRule: "Mandatory",
323
- value: new Variant({ dataType: DataType.Int32, value: 0 })
324
- });
325
-
326
- namespace.addVariable({
327
- propertyOf: levelAlarm,
328
- browseName: "lowLowLimit",
329
- dataType: "Int32",
330
- modellingRule: "Mandatory",
331
- value: new Variant({ dataType: DataType.Int32, value: 0 })
332
- });
333
-
334
- return {
335
- digitalAlarmType: digitalAlarm,
336
- levelAlarmType: levelAlarm
337
- };
338
- }
339
- }
340
-
341
- module.exports = { OpcUaAddressSpaceAlarm };
1
+ const {
2
+ StatusCodes,
3
+ Variant,
4
+ DataType
5
+ } = require("./opcua-constants");
6
+
7
+ class OpcUaAddressSpaceAlarm {
8
+
9
+ constructor(options) {
10
+ this.namespace = options.namespace;
11
+ this.node = options.node;
12
+ this.serverName = options.registry;
13
+ this.registry = options.registry;
14
+ this.alarmTypesByNamespace = new Map();
15
+ }
16
+
17
+ emitTagAccess(operation, details) {
18
+ this.registry.emitTagAccess({
19
+ operation,
20
+ serverId: this.node.id,
21
+ serverNodeName: this.node.name || "",
22
+ serverName: this.serverName,
23
+ timestamp: new Date().toISOString(),
24
+ path: details.path,
25
+ nodeID: details.nodeID,
26
+ browseName: details.browseName,
27
+ dataType: details.dataType,
28
+ value: details.value
29
+ });
30
+ }
31
+
32
+ createAlarm(namespace, browseName, parentNode, inputNode, conditionName, nodeId, sourceName, alarmConfig) {
33
+ try {
34
+ const type = alarmConfig.type;
35
+ let alarmNode = null;
36
+ const alarmTypes = this.ensureNamespaceTypes(namespace);
37
+
38
+ const config = {
39
+ browseName: browseName,
40
+ componentOf: parentNode,
41
+ inputNode: inputNode,
42
+ conditionSource: parentNode,
43
+ conditionName: conditionName,
44
+ normalState: false,
45
+ nodeId: nodeId,
46
+ description: alarmConfig.description || "",
47
+ namespace: namespace,
48
+ optionals: [
49
+ "ConfirmedState",
50
+ "Confirm"
51
+ ]
52
+ };
53
+
54
+ if (type === "digitalAlarm") {
55
+ alarmNode = namespace.instantiateAlarmCondition(alarmTypes.digitalAlarmType, config);
56
+ }
57
+
58
+ if (type === "levelAlarm") {
59
+ alarmNode = namespace.instantiateAlarmCondition(alarmTypes.levelAlarmType, config);
60
+
61
+ alarmNode.getPropertyByName("lowLowLimit")
62
+ .setValueFromSource({
63
+ dataType: DataType.Int32,
64
+ value: alarmConfig.lowLowLimit
65
+ });
66
+
67
+ alarmNode.getPropertyByName("lowLimit")
68
+ .setValueFromSource({
69
+ dataType: DataType.Int32,
70
+ value: alarmConfig.lowLimit
71
+ });
72
+
73
+ alarmNode.getPropertyByName("highHighLimit")
74
+ .setValueFromSource({
75
+ dataType: DataType.Int32,
76
+ value: alarmConfig.highHighLimit
77
+ });
78
+
79
+ alarmNode.getPropertyByName("highLimit")
80
+ .setValueFromSource({
81
+ dataType: DataType.Int32,
82
+ value: alarmConfig.highLimit
83
+ });
84
+ }
85
+
86
+ alarmNode.getPropertyByName("enabled")
87
+ .setValueFromSource({
88
+ dataType: DataType.Boolean,
89
+ value: alarmConfig.enabled
90
+ });
91
+
92
+ alarmNode.sourceName.setValueFromSource({
93
+ dataType: DataType.String,
94
+ value: sourceName
95
+ });
96
+
97
+ return alarmNode;
98
+ } catch (error) {
99
+ console.error("createAlarm");
100
+ console.error(error);
101
+ }
102
+ }
103
+
104
+ checkAlarm(alarm, variableValue) {
105
+ if (alarm) {
106
+ const alarmConfig = alarm.alarmConfig;
107
+ const type = alarmConfig.type;
108
+
109
+ if (type === "levelAlarm") {
110
+ this.levelAlarm(alarm, variableValue);
111
+ }
112
+ if (type === "digitalAlarm") {
113
+ this.digitalAlarm(alarm, variableValue);
114
+ }
115
+ }
116
+ }
117
+
118
+ levelAlarm(alarm, variableValue) {
119
+ const alarmNode = alarm.node;
120
+ const alarmConfig = alarm.alarmConfig;
121
+
122
+ const isActive = alarmNode.activeState.id.readValue().value.value;
123
+ const highHighSp = alarmNode.getPropertyByName("highHighLimit").readValue().value.value;
124
+ const highSp = alarmNode.getPropertyByName("highLimit").readValue().value.value;
125
+ const lowSp = alarmNode.getPropertyByName("lowLimit").readValue().value.value;
126
+ const lowLowSp = alarmNode.getPropertyByName("lowLowLimit").readValue().value.value;
127
+ const enabled = alarmNode.getPropertyByName("enabled").readValue().value.value;
128
+ let lastMessage = null;
129
+ let message = null;
130
+
131
+ if (variableValue >= highHighSp && enabled) {
132
+ message = alarmConfig.highHighMessage + ": " + variableValue;
133
+ this.raiseAlarm(alarmNode, message, alarmConfig.severity);
134
+ lastMessage = message;
135
+ } else if (variableValue >= highSp && enabled) {
136
+ message = alarmConfig.highMessage + ": " + variableValue;
137
+ this.raiseAlarm(alarmNode, message, alarmConfig.severity);
138
+ lastMessage = message;
139
+ } else if (variableValue <= lowLowSp && enabled) {
140
+ message = alarmConfig.lowLowMessage + ": " + variableValue;
141
+ this.raiseAlarm(alarmNode, message, alarmConfig.severity);
142
+ lastMessage = message;
143
+ } else if (variableValue <= lowSp && enabled) {
144
+ message = alarmConfig.lowMessage + ": " + variableValue;
145
+ this.raiseAlarm(alarmNode, message, alarmConfig.severity);
146
+ lastMessage = message;
147
+ } else if (isActive) {
148
+ this.clearAlarm(alarmNode, lastMessage, alarmConfig.severity);
149
+ }
150
+
151
+ this.alarmMethods(alarmNode);
152
+ }
153
+
154
+ digitalAlarm(alarm, variableValue) {
155
+ const alarmNode = alarm.node;
156
+ const alarmConfig = alarm.alarmConfig;
157
+ const enabled = alarmNode.getPropertyByName("enabled").readValue().value.value;
158
+
159
+ if (variableValue && enabled) {
160
+ this.raiseAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
161
+ } else {
162
+ this.clearAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
163
+ }
164
+
165
+ this.alarmMethods(alarmNode);
166
+ }
167
+
168
+ alarmMethods(alarmNode) {
169
+ alarmNode.confirm.bindMethod((inputArguments, context, callback) => {
170
+ const alarm = context.object;
171
+ const severity = alarm.severity.readValue().value.value;
172
+ const message = alarm.message.readValue().value.value.text;
173
+ alarm.confirmedState.setValue(true);
174
+
175
+ const isAcked = alarm.ackedState.id.readValue().value.value;
176
+
177
+ if (isAcked) {
178
+ alarm.raiseNewCondition({
179
+ message: message,
180
+ severity: severity,
181
+ retain: false
182
+ });
183
+
184
+ this.raiseNewConditionAlarm(alarm, message, severity, false);
185
+ } else {
186
+ this.raiseNewConditionAlarm(alarm, message, severity, true);
187
+ }
188
+
189
+ callback(null, {
190
+ statusCode: StatusCodes.Good,
191
+ outputArguments: []
192
+ });
193
+ });
194
+
195
+ alarmNode.acknowledge.bindMethod((inputArguments, context, callback) => {
196
+ const alarm = context.object;
197
+ const severity = alarm.severity.readValue().value.value;
198
+ const message = alarm.message.readValue().value.value.text;
199
+ alarm.ackedState.setValue(true);
200
+ alarm.confirmedState.setValue(false);
201
+
202
+ this.raiseNewConditionAlarm(alarm, message, severity, true);
203
+
204
+ callback(null, {
205
+ statusCode: StatusCodes.Good,
206
+ outputArguments: []
207
+ });
208
+ });
209
+
210
+ alarmNode.addComment.bindMethod((inputArguments, context, callback) => {
211
+ const comment = inputArguments[1].value;
212
+ const alarm = context.object;
213
+
214
+ alarm.comment.setValueFromSource({
215
+ value: comment,
216
+ dataType: DataType.LocalizedText
217
+ });
218
+ callback(null, {
219
+ statusCode: StatusCodes.Good,
220
+ outputArguments: []
221
+ });
222
+ });
223
+ }
224
+
225
+ clearAlarm(alarmNode, message, severity) {
226
+ const isAcked = !alarmNode.ackedState.id.readValue().value.value;
227
+
228
+ alarmNode.activeState.setValue(false);
229
+ alarmNode.raiseNewCondition({ message, severity: severity, isAcked });
230
+
231
+ this.raiseNewConditionAlarm(alarmNode, message, severity, isAcked);
232
+ }
233
+
234
+ raiseAlarm(alarmNode, message, severity, retain = true) {
235
+ const isActive = alarmNode.activeState.id.readValue().value.value;
236
+ const isAcked = alarmNode.ackedState.id.readValue().value.value;
237
+ if (isActive && isAcked) {
238
+ alarmNode.activeState.setValue(false);
239
+ alarmNode.ackedState.setValue(true);
240
+ alarmNode.confirmedState.setValue(true);
241
+ } else {
242
+ alarmNode.ackedState.setValue(false);
243
+ alarmNode.confirmedState.setValue(true);
244
+ }
245
+
246
+ alarmNode.activeState.setValue(true);
247
+ this.raiseNewConditionAlarm(alarmNode, message, severity, retain);
248
+ }
249
+
250
+ raiseNewConditionAlarm(alarmNode, message, severity, retain) {
251
+ alarmNode.raiseNewCondition({ message, severity, retain });
252
+
253
+ this.registry.registerActiveAlarms(alarmNode, message, severity, retain, this.node);
254
+
255
+ this.emitTagAccess("alarm", {
256
+ message: message,
257
+ severity: severity,
258
+ retain: retain,
259
+ dataType: "alarm",
260
+ value: "highHighSp"
261
+ });
262
+ }
263
+
264
+ ensureNamespaceTypes(namespace) {
265
+ const namespaceKey = namespace.index;
266
+ if (this.alarmTypesByNamespace.has(namespaceKey)) {
267
+ return this.alarmTypesByNamespace.get(namespaceKey);
268
+ }
269
+
270
+ const types = this.createObjectType(namespace);
271
+ this.alarmTypesByNamespace.set(namespaceKey, types);
272
+ return types;
273
+ }
274
+
275
+ createObjectType(namespace) {
276
+ const digitalAlarm = namespace.addObjectType({
277
+ browseName: "digitalAlarm",
278
+ subtypeOf: "OffNormalAlarmType"
279
+ });
280
+
281
+ const levelAlarm = namespace.addObjectType({
282
+ browseName: "levelAlarm",
283
+ subtypeOf: "OffNormalAlarmType"
284
+ });
285
+
286
+ namespace.addVariable({
287
+ propertyOf: digitalAlarm,
288
+ browseName: "enabled",
289
+ dataType: "Boolean",
290
+ modellingRule: "Mandatory",
291
+ value: new Variant({ dataType: DataType.Boolean, value: true })
292
+ });
293
+
294
+ namespace.addVariable({
295
+ propertyOf: levelAlarm,
296
+ browseName: "enabled",
297
+ dataType: "Boolean",
298
+ modellingRule: "Mandatory",
299
+ value: new Variant({ dataType: DataType.Boolean, value: true })
300
+ });
301
+
302
+ namespace.addVariable({
303
+ propertyOf: levelAlarm,
304
+ browseName: "highHighLimit",
305
+ dataType: "Int32",
306
+ modellingRule: "Mandatory",
307
+ value: new Variant({ dataType: DataType.Int32, value: 0 })
308
+ });
309
+
310
+ namespace.addVariable({
311
+ propertyOf: levelAlarm,
312
+ browseName: "highLimit",
313
+ dataType: "Int32",
314
+ modellingRule: "Mandatory",
315
+ value: new Variant({ dataType: DataType.Int32, value: 0 })
316
+ });
317
+
318
+ namespace.addVariable({
319
+ propertyOf: levelAlarm,
320
+ browseName: "lowLimit",
321
+ dataType: "Int32",
322
+ modellingRule: "Mandatory",
323
+ value: new Variant({ dataType: DataType.Int32, value: 0 })
324
+ });
325
+
326
+ namespace.addVariable({
327
+ propertyOf: levelAlarm,
328
+ browseName: "lowLowLimit",
329
+ dataType: "Int32",
330
+ modellingRule: "Mandatory",
331
+ value: new Variant({ dataType: DataType.Int32, value: 0 })
332
+ });
333
+
334
+ return {
335
+ digitalAlarmType: digitalAlarm,
336
+ levelAlarmType: levelAlarm
337
+ };
338
+ }
339
+ }
340
+
341
+ module.exports = { OpcUaAddressSpaceAlarm };