loupedeck-commander 1.2.12 → 1.3.1
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.
- package/README.md +3 -3
- package/common/ApplicationConfig.mjs +31 -24
- package/common/BaseLoupeDeckHandler.mjs +30 -11
- package/common/ButtonField.mjs +159 -0
- package/common/button.mjs +499 -0
- package/common/utils.mjs +28 -7
- package/config.yaml +6 -0
- package/interfaces/baseif.mjs +1 -1
- package/interfaces/interfaces.mjs +34 -0
- package/interfaces/opcuaif.mjs +67 -45
- package/package.json +3 -2
- package/profile-1.yaml +185 -0
- package/profile-2.yaml +210 -0
- package/test.mjs +15 -1
- package/common/touchbuttons.mjs +0 -597
- package/config.json +0 -13
- package/profile-1.json +0 -272
- package/profile-2.json +0 -290
package/interfaces/opcuaif.mjs
CHANGED
|
@@ -2,27 +2,14 @@ import {
|
|
|
2
2
|
OPCUAClient,
|
|
3
3
|
MessageSecurityMode,
|
|
4
4
|
SecurityPolicy,
|
|
5
|
-
BrowseDirection,
|
|
6
5
|
AttributeIds,
|
|
7
|
-
NodeClassMask,
|
|
8
|
-
makeBrowsePath,
|
|
9
6
|
resolveNodeId,
|
|
10
7
|
TimestampsToReturn,
|
|
11
|
-
coerceInt32,
|
|
12
|
-
coerceByteString,
|
|
13
8
|
DataType
|
|
14
9
|
} from "node-opcua";
|
|
15
10
|
|
|
16
11
|
import { BaseIf } from './baseif.mjs'
|
|
17
12
|
|
|
18
|
-
const subscriptionParameters = {
|
|
19
|
-
maxNotificationsPerPublish: 1000,
|
|
20
|
-
publishingEnabled: true,
|
|
21
|
-
requestedLifetimeCount: 100,
|
|
22
|
-
requestedMaxKeepAliveCount: 10,
|
|
23
|
-
requestedPublishingInterval: 1000
|
|
24
|
-
};
|
|
25
|
-
|
|
26
13
|
/**
|
|
27
14
|
* Our Special-Handler just used the Default - and adds Vibration after triggers through Button-Releases
|
|
28
15
|
*/
|
|
@@ -34,19 +21,13 @@ export class OPCUAIf extends BaseIf {
|
|
|
34
21
|
#connected
|
|
35
22
|
#endpointurl
|
|
36
23
|
#publishingInterval
|
|
24
|
+
#samplingInterval
|
|
37
25
|
monitoreditems
|
|
38
26
|
types
|
|
39
27
|
buttons
|
|
40
28
|
constructor() {
|
|
41
29
|
super()
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async stop() {
|
|
45
|
-
if (!this.#client)
|
|
46
|
-
return
|
|
47
|
-
await this.Disconnect()
|
|
48
|
-
this.LogInfo(`OPCUAIf Stopped\n`)
|
|
49
|
-
}
|
|
30
|
+
}
|
|
50
31
|
|
|
51
32
|
/**
|
|
52
33
|
* Initialize the OPCUA client and subscribe to monitored items.
|
|
@@ -67,6 +48,12 @@ export class OPCUAIf extends BaseIf {
|
|
|
67
48
|
this.#publishingInterval = 250;
|
|
68
49
|
this.LogInfo(`OPCUAIf init using default publishingInterval: ${this.#publishingInterval}ms\n`);
|
|
69
50
|
}
|
|
51
|
+
if (options.samplingInterval)
|
|
52
|
+
this.#samplingInterval = options.samplingInterval
|
|
53
|
+
else{
|
|
54
|
+
this.#samplingInterval = 100;
|
|
55
|
+
this.LogInfo(`OPCUAIf init using default samplingInterval: ${this.#samplingInterval}ms\n`);
|
|
56
|
+
}
|
|
70
57
|
this.monitoreditems = {}
|
|
71
58
|
this.types = {}
|
|
72
59
|
this.buttons = {}
|
|
@@ -79,33 +66,33 @@ export class OPCUAIf extends BaseIf {
|
|
|
79
66
|
for (let f = 0; f < fieldKeys.length; f++) {
|
|
80
67
|
let field = fields[f]
|
|
81
68
|
const keys = Object.keys(field)
|
|
69
|
+
|
|
70
|
+
// Iterate over buttons:
|
|
82
71
|
for (let i = 0; i < keys.length; i++) {
|
|
83
72
|
const key = keys[i]
|
|
84
73
|
const elem = field[key]
|
|
74
|
+
options["key"] = key // we have to know the key of the button
|
|
85
75
|
// groupnode
|
|
86
|
-
if (elem.nodeid) {
|
|
87
|
-
|
|
88
|
-
let formattedNodeId = this.formatString(elem.nodeid, options)
|
|
76
|
+
if (elem.params && elem.params.nodeid) {
|
|
77
|
+
let formattedNodeId = this.formatString(elem.params.nodeid, options)
|
|
89
78
|
let monitoredItemId = await this.Subscribe(formattedNodeId)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let format = this.formatString(elem.statenodeid, options)
|
|
96
|
-
let monitoredItemId = await this.Subscribe(format)
|
|
79
|
+
if (monitoredItemId === undefined) {
|
|
80
|
+
this.LogError(`OPCUAIf: Error subscribing to node ${formattedNodeId}\n`)
|
|
81
|
+
continue
|
|
82
|
+
}
|
|
83
|
+
console.log("OPCUAIf: Subscribe to",monitoredItemId,formattedNodeId)
|
|
97
84
|
this.buttons[monitoredItemId] = i
|
|
98
85
|
}
|
|
99
86
|
await this.monitorStates(elem, options)
|
|
100
87
|
}
|
|
101
88
|
}
|
|
102
89
|
} catch (error) {
|
|
103
|
-
this.LogError(`OPCUAIf: Error
|
|
90
|
+
this.LogError(`OPCUAIf: Error\n`,error)
|
|
104
91
|
}
|
|
105
92
|
}
|
|
106
93
|
|
|
107
94
|
/**
|
|
108
|
-
*
|
|
95
|
+
* Monitor the state OPC/UA node of the given element
|
|
109
96
|
* @param {*} elem : Elem Object
|
|
110
97
|
* @param {*} options
|
|
111
98
|
*/
|
|
@@ -115,8 +102,13 @@ export class OPCUAIf extends BaseIf {
|
|
|
115
102
|
const key2 = stateKeys[i]
|
|
116
103
|
const state = elem.states[key2]
|
|
117
104
|
if (state.opcua) {
|
|
118
|
-
let
|
|
119
|
-
let monitoredItemId = await this.Subscribe(
|
|
105
|
+
let formattedNodeId = this.formatString(state.opcua, options)
|
|
106
|
+
let monitoredItemId = await this.Subscribe(formattedNodeId)
|
|
107
|
+
if (monitoredItemId === undefined) {
|
|
108
|
+
this.LogError(`OPCUAIf: Error subscribing State to node ${formattedNodeId}\n`)
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
console.log("OPCUAIf: Subscribe to",monitoredItemId,formattedNodeId)
|
|
120
112
|
this.buttons[monitoredItemId] = i
|
|
121
113
|
}
|
|
122
114
|
}
|
|
@@ -167,6 +159,13 @@ export class OPCUAIf extends BaseIf {
|
|
|
167
159
|
}
|
|
168
160
|
}
|
|
169
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Call the OPCUA node with the given options.
|
|
164
|
+
* This method will write the value to the node and return the new state.
|
|
165
|
+
* @param {*} opcuaNode
|
|
166
|
+
* @param {*} options
|
|
167
|
+
* @returns
|
|
168
|
+
*/
|
|
170
169
|
async call(opcuaNode, options = {}) {
|
|
171
170
|
var res = this.Check(options)
|
|
172
171
|
if (res < 0) {
|
|
@@ -174,7 +173,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
174
173
|
return false
|
|
175
174
|
}
|
|
176
175
|
|
|
177
|
-
var nodeId = super.
|
|
176
|
+
var nodeId = super.call(opcuaNode, options)
|
|
178
177
|
|
|
179
178
|
var type = this.types[nodeId]
|
|
180
179
|
var value = options.value
|
|
@@ -214,6 +213,21 @@ export class OPCUAIf extends BaseIf {
|
|
|
214
213
|
return 0
|
|
215
214
|
}
|
|
216
215
|
|
|
216
|
+
/**
|
|
217
|
+
* This method is called when the interface is stopped.
|
|
218
|
+
* It will disconnect the client and stop the subscription.
|
|
219
|
+
* @returns
|
|
220
|
+
*/
|
|
221
|
+
async stop() {
|
|
222
|
+
if (!this.#client)
|
|
223
|
+
return
|
|
224
|
+
await this.Disconnect()
|
|
225
|
+
this.LogInfo(`OPCUAIf Stopped\n`)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Disconnect the OPCUA client and close the session.
|
|
230
|
+
*/
|
|
217
231
|
async Disconnect() {
|
|
218
232
|
if (this.#client) {
|
|
219
233
|
if (this.#session)
|
|
@@ -223,6 +237,10 @@ export class OPCUAIf extends BaseIf {
|
|
|
223
237
|
this.LogInfo(`OPCUAIf: Disconnected\n`);
|
|
224
238
|
}
|
|
225
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Connect to the OPCUA server with the given URL.
|
|
242
|
+
* @param {string} url - The URL of the OPCUA server, typical format: opc.tcp://ip-address:4840 .
|
|
243
|
+
*/
|
|
226
244
|
async Connect(url) {
|
|
227
245
|
let self = this
|
|
228
246
|
if (this.#client){
|
|
@@ -270,9 +288,9 @@ export class OPCUAIf extends BaseIf {
|
|
|
270
288
|
this.#client.on("after_reconnection", (err) => {
|
|
271
289
|
self.LogInfo(`OPCUAIf: After Reconnection event => ${err}\n`);
|
|
272
290
|
});
|
|
273
|
-
this.#client.on("security_token_renewed", () => {
|
|
291
|
+
/*this.#client.on("security_token_renewed", () => {
|
|
274
292
|
self.LogDebug(`OPCUAIf: security_token_renewed\n`);
|
|
275
|
-
})
|
|
293
|
+
})*/
|
|
276
294
|
this.#client.on("lifetime_75", (token) => { })
|
|
277
295
|
|
|
278
296
|
this.LogInfo(`OPCUAIf: connecting client to ${url}\n`);//, this.#session.toString());
|
|
@@ -302,16 +320,22 @@ export class OPCUAIf extends BaseIf {
|
|
|
302
320
|
requestedPublishingInterval: this.#publishingInterval
|
|
303
321
|
});
|
|
304
322
|
|
|
305
|
-
this.LogInfo(`OPCUAIf: session created\n`)
|
|
306
|
-
this.LogInfo(`OPCUAIf: client\n`);
|
|
307
|
-
this.LogInfo(`OPCUAIf: subscription\n`);
|
|
323
|
+
this.LogInfo(`OPCUAIf: session created\n`);
|
|
324
|
+
// this.LogInfo(`OPCUAIf: client\n`);
|
|
325
|
+
// this.LogInfo(`OPCUAIf: subscription\n`);
|
|
308
326
|
this.#connected = true
|
|
309
327
|
this.#endpointurl = url
|
|
310
328
|
}
|
|
311
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Register a subscription for a nodeID.
|
|
332
|
+
* This method will create a monitored item for the given nodeID and return the monitored item ID.
|
|
333
|
+
* If the nodeID is already registered, it will return the existing monitored item ID.
|
|
334
|
+
* @param {*} nodeID
|
|
335
|
+
* @returns
|
|
336
|
+
*/
|
|
312
337
|
async Subscribe(nodeID) {
|
|
313
338
|
// install monitored item
|
|
314
|
-
|
|
315
339
|
const keys = Object.keys(this.monitoreditems)
|
|
316
340
|
for (let i = 0; i < keys.length; i++) {
|
|
317
341
|
const key = keys[i]
|
|
@@ -327,7 +351,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
327
351
|
attributeId: AttributeIds.Value
|
|
328
352
|
};
|
|
329
353
|
const monitoringParameters = {
|
|
330
|
-
samplingInterval:
|
|
354
|
+
samplingInterval: this.#samplingInterval,
|
|
331
355
|
discardOldest: true,
|
|
332
356
|
queueSize: 10
|
|
333
357
|
};
|
|
@@ -393,12 +417,10 @@ export class OPCUAIf extends BaseIf {
|
|
|
393
417
|
}
|
|
394
418
|
} else {
|
|
395
419
|
self.LogError("OPCUAIf: write NOT ok", nodeID, value, "\n");
|
|
396
|
-
self.LogError(err)
|
|
397
420
|
}
|
|
398
421
|
});
|
|
399
422
|
} catch (err) {
|
|
400
423
|
self.LogError("OPCUAIf: write NOT ok", nodeID, value, "\n");
|
|
401
|
-
self.LogError(err)
|
|
402
424
|
}
|
|
403
425
|
}
|
|
404
426
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loupedeck-commander",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "A system to ease working with LoupeDeck devices using CMD-line, OPC/UA or HTTP-client interfaces",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"scripts": {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"loupedeck": "^7.0.0",
|
|
15
15
|
"mkdirp": "^3.0.1",
|
|
16
16
|
"node-opcua": "^2.153.0",
|
|
17
|
-
"string-template": "^1.0.0"
|
|
17
|
+
"string-template": "^1.0.0",
|
|
18
|
+
"yaml": "^2.8.0"
|
|
18
19
|
},
|
|
19
20
|
"author": "Thomas Schneider",
|
|
20
21
|
"license": "Apache-2.0",
|
package/profile-1.yaml
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
name: profile-1
|
|
2
|
+
profile: example
|
|
3
|
+
description: ""
|
|
4
|
+
touch:
|
|
5
|
+
center:
|
|
6
|
+
"0":
|
|
7
|
+
states:
|
|
8
|
+
off:
|
|
9
|
+
color: "#000055"
|
|
10
|
+
textColor: "#FFFFFF"
|
|
11
|
+
image: icons/home.png
|
|
12
|
+
cmd: echo "{id} {state}"
|
|
13
|
+
font: 20px Arial
|
|
14
|
+
blink: true
|
|
15
|
+
on:
|
|
16
|
+
color: "#00ff00"
|
|
17
|
+
image: icons/home.png
|
|
18
|
+
cmd: echo "{id} {state}"
|
|
19
|
+
font: 10px Arial
|
|
20
|
+
blink: false
|
|
21
|
+
params:
|
|
22
|
+
text: "{key}"
|
|
23
|
+
"1":
|
|
24
|
+
states:
|
|
25
|
+
off:
|
|
26
|
+
color: "#000099"
|
|
27
|
+
image: icons/home.png
|
|
28
|
+
cmd: echo "{id} {state} {pressed}"
|
|
29
|
+
on:
|
|
30
|
+
color: "#00ff00"
|
|
31
|
+
image: icons/home.png
|
|
32
|
+
cmd: echo "{id} {state} {pressed}"
|
|
33
|
+
blink: true
|
|
34
|
+
params:
|
|
35
|
+
minPressed: 100
|
|
36
|
+
text: "{released}"
|
|
37
|
+
"2":
|
|
38
|
+
states:
|
|
39
|
+
off:
|
|
40
|
+
color: "#000099"
|
|
41
|
+
image: icons/home.png
|
|
42
|
+
cmd: echo "{id} {state}"
|
|
43
|
+
on:
|
|
44
|
+
color: "#00ff00"
|
|
45
|
+
image: icons/home.png
|
|
46
|
+
cmd: echo "{id} {state}"
|
|
47
|
+
"3":
|
|
48
|
+
states:
|
|
49
|
+
off:
|
|
50
|
+
color: "#000099"
|
|
51
|
+
image: icons/home.png
|
|
52
|
+
cmd: echo "{id} {state}"
|
|
53
|
+
on:
|
|
54
|
+
color: "#00ff00"
|
|
55
|
+
image: icons/home.png
|
|
56
|
+
cmd: echo "{id} {state}"
|
|
57
|
+
"4":
|
|
58
|
+
states:
|
|
59
|
+
off:
|
|
60
|
+
color: "#000099"
|
|
61
|
+
image: icons/home.png
|
|
62
|
+
cmd: echo "{id} {state}"
|
|
63
|
+
on:
|
|
64
|
+
color: "#00ff00"
|
|
65
|
+
image: icons/home.png
|
|
66
|
+
cmd: echo "{id} {state}"
|
|
67
|
+
"5":
|
|
68
|
+
states:
|
|
69
|
+
off:
|
|
70
|
+
color: "#000099"
|
|
71
|
+
image: icons/home.png
|
|
72
|
+
cmd: echo "{id} {state}"
|
|
73
|
+
on:
|
|
74
|
+
color: "#00ff00"
|
|
75
|
+
image: icons/home.png
|
|
76
|
+
cmd: echo "{id} {state}"
|
|
77
|
+
"6":
|
|
78
|
+
states:
|
|
79
|
+
off:
|
|
80
|
+
color: "#000099"
|
|
81
|
+
image: icons/home.png
|
|
82
|
+
cmd: echo "{id} {state}"
|
|
83
|
+
on:
|
|
84
|
+
color: "#00ff00"
|
|
85
|
+
image: icons/home.png
|
|
86
|
+
cmd: echo "{id} {state}"
|
|
87
|
+
"7":
|
|
88
|
+
states:
|
|
89
|
+
off:
|
|
90
|
+
color: "#000099"
|
|
91
|
+
image: icons/home.png
|
|
92
|
+
cmd: echo "{id} {state}"
|
|
93
|
+
on:
|
|
94
|
+
color: "#00ff00"
|
|
95
|
+
image: icons/home.png
|
|
96
|
+
cmd: echo "{id} {state}"
|
|
97
|
+
"8":
|
|
98
|
+
states:
|
|
99
|
+
off:
|
|
100
|
+
color: "#000099"
|
|
101
|
+
image: icons/home.png
|
|
102
|
+
cmd: echo "{id} {state}"
|
|
103
|
+
on:
|
|
104
|
+
color: "#00ff00"
|
|
105
|
+
image: icons/home.png
|
|
106
|
+
cmd: echo "{id} {state}"
|
|
107
|
+
"9":
|
|
108
|
+
states:
|
|
109
|
+
off:
|
|
110
|
+
color: "#000099"
|
|
111
|
+
image: icons/home.png
|
|
112
|
+
cmd: echo "{id} {state}"
|
|
113
|
+
on:
|
|
114
|
+
color: "#00ff00"
|
|
115
|
+
image: icons/home.png
|
|
116
|
+
cmd: echo "{id} {state}"
|
|
117
|
+
"10":
|
|
118
|
+
states:
|
|
119
|
+
off:
|
|
120
|
+
color: "#000099"
|
|
121
|
+
image: icons/home.png
|
|
122
|
+
cmd: echo "{id} {state}"
|
|
123
|
+
on:
|
|
124
|
+
color: "#00ff00"
|
|
125
|
+
image: icons/home.png
|
|
126
|
+
cmd: echo "{id} {state}"
|
|
127
|
+
"11":
|
|
128
|
+
states:
|
|
129
|
+
off:
|
|
130
|
+
color: "#000099"
|
|
131
|
+
image: icons/home.png
|
|
132
|
+
cmd: echo "{id} {state}"
|
|
133
|
+
on:
|
|
134
|
+
color: "#00ff00"
|
|
135
|
+
image: icons/home.png
|
|
136
|
+
cmd: echo "{id} {state}"
|
|
137
|
+
left:
|
|
138
|
+
"0":
|
|
139
|
+
states:
|
|
140
|
+
on:
|
|
141
|
+
color: "#000000"
|
|
142
|
+
cmd: echo "{id} {state}"
|
|
143
|
+
right:
|
|
144
|
+
"0":
|
|
145
|
+
states:
|
|
146
|
+
on:
|
|
147
|
+
color: "#000000"
|
|
148
|
+
cmd: echo "{id} {state}"
|
|
149
|
+
knobs:
|
|
150
|
+
knobTL:
|
|
151
|
+
states:
|
|
152
|
+
on:
|
|
153
|
+
cmd: echo "{id} {state}"
|
|
154
|
+
knobCL:
|
|
155
|
+
states:
|
|
156
|
+
on:
|
|
157
|
+
cmd: echo "{id} {state}"
|
|
158
|
+
knobBL:
|
|
159
|
+
states:
|
|
160
|
+
on:
|
|
161
|
+
cmd: echo "{id} {state}"
|
|
162
|
+
opcua: ns=1;s={simnbr}.Function1
|
|
163
|
+
knobTR:
|
|
164
|
+
states:
|
|
165
|
+
on:
|
|
166
|
+
cmd: echo "{id} {state}"
|
|
167
|
+
knobCR:
|
|
168
|
+
states:
|
|
169
|
+
on:
|
|
170
|
+
cmd: echo "{id} {state}"
|
|
171
|
+
knobBR:
|
|
172
|
+
states:
|
|
173
|
+
on:
|
|
174
|
+
cmd: echo "{id} {state}"
|
|
175
|
+
parameters:
|
|
176
|
+
hostname: 127.0.0.1
|
|
177
|
+
simnbr: "1"
|
|
178
|
+
endpointurl: opc.tcp://{hostname}:4840
|
|
179
|
+
publishingInterval: 200
|
|
180
|
+
nodeid: ns=0;s=nodeID
|
|
181
|
+
textColor: "#abcdff"
|
|
182
|
+
textBaseLine: top
|
|
183
|
+
textAlign: left
|
|
184
|
+
font: 14px Arial
|
|
185
|
+
verbose: true
|
package/profile-2.yaml
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
name: profile-1
|
|
2
|
+
profile: example
|
|
3
|
+
description: ""
|
|
4
|
+
touch:
|
|
5
|
+
center:
|
|
6
|
+
"0":
|
|
7
|
+
default: one
|
|
8
|
+
states:
|
|
9
|
+
off:
|
|
10
|
+
color: "#000099"
|
|
11
|
+
cmd: echo "{id} {state}"
|
|
12
|
+
one:
|
|
13
|
+
color: "#00ff00"
|
|
14
|
+
image: numbers/one_9278045.png
|
|
15
|
+
cmd: echo "{id} {state}"
|
|
16
|
+
two:
|
|
17
|
+
color: "#00ff00"
|
|
18
|
+
image: numbers/two_9278103.png
|
|
19
|
+
cmd: echo "{id} {state}"
|
|
20
|
+
three:
|
|
21
|
+
color: "#00ff00"
|
|
22
|
+
image: numbers/three_9278150.png
|
|
23
|
+
cmd: echo "{id} {state}"
|
|
24
|
+
four:
|
|
25
|
+
color: "#00ff00"
|
|
26
|
+
image: numbers/four_9278183.png
|
|
27
|
+
cmd: echo "{id} {state}"
|
|
28
|
+
five:
|
|
29
|
+
color: "#00ff00"
|
|
30
|
+
image: numbers/five_9278222.png
|
|
31
|
+
cmd: echo "{id} {state}"
|
|
32
|
+
"1":
|
|
33
|
+
default: two
|
|
34
|
+
states:
|
|
35
|
+
off:
|
|
36
|
+
color: "#000099"
|
|
37
|
+
cmd: echo "{id} {state}"
|
|
38
|
+
one:
|
|
39
|
+
color: "#00ff00"
|
|
40
|
+
image: numbers/one_9278045.png
|
|
41
|
+
cmd: echo "{id} {state}"
|
|
42
|
+
two:
|
|
43
|
+
color: "#00ff00"
|
|
44
|
+
image: numbers/two_9278103.png
|
|
45
|
+
cmd: echo "{id} {state}"
|
|
46
|
+
three:
|
|
47
|
+
color: "#00ff00"
|
|
48
|
+
image: numbers/three_9278150.png
|
|
49
|
+
cmd: echo "{id} {state}"
|
|
50
|
+
four:
|
|
51
|
+
color: "#00ff00"
|
|
52
|
+
image: numbers/four_9278183.png
|
|
53
|
+
cmd: echo "{id} {state}"
|
|
54
|
+
five:
|
|
55
|
+
color: "#00ff00"
|
|
56
|
+
image: numbers/five_9278222.png
|
|
57
|
+
cmd: echo "{id} {state}"
|
|
58
|
+
"2":
|
|
59
|
+
default: three
|
|
60
|
+
states:
|
|
61
|
+
off:
|
|
62
|
+
color: "#000099"
|
|
63
|
+
cmd: echo "{id} {state}"
|
|
64
|
+
one:
|
|
65
|
+
color: "#00ff00"
|
|
66
|
+
image: numbers/one_9278045.png
|
|
67
|
+
cmd: echo "{id} {state}"
|
|
68
|
+
two:
|
|
69
|
+
color: "#00ff00"
|
|
70
|
+
image: numbers/two_9278103.png
|
|
71
|
+
cmd: echo "{id} {state}"
|
|
72
|
+
three:
|
|
73
|
+
color: "#00ff00"
|
|
74
|
+
image: numbers/three_9278150.png
|
|
75
|
+
cmd: echo "{id} {state}"
|
|
76
|
+
four:
|
|
77
|
+
color: "#00ff00"
|
|
78
|
+
image: numbers/four_9278183.png
|
|
79
|
+
cmd: echo "{id} {state}"
|
|
80
|
+
five:
|
|
81
|
+
color: "#00ff00"
|
|
82
|
+
image: numbers/five_9278222.png
|
|
83
|
+
cmd: echo "{id} {state}"
|
|
84
|
+
"3":
|
|
85
|
+
default: four
|
|
86
|
+
states:
|
|
87
|
+
off:
|
|
88
|
+
color: "#000099"
|
|
89
|
+
cmd: echo "{id} {state}"
|
|
90
|
+
one:
|
|
91
|
+
color: "#00ff00"
|
|
92
|
+
image: numbers/one_9278045.png
|
|
93
|
+
cmd: echo "{id} {state}"
|
|
94
|
+
two:
|
|
95
|
+
color: "#00ff00"
|
|
96
|
+
image: numbers/two_9278103.png
|
|
97
|
+
cmd: echo "{id} {state}"
|
|
98
|
+
three:
|
|
99
|
+
color: "#00ff00"
|
|
100
|
+
image: numbers/three_9278150.png
|
|
101
|
+
cmd: echo "{id} {state}"
|
|
102
|
+
four:
|
|
103
|
+
color: "#00ff00"
|
|
104
|
+
image: numbers/four_9278183.png
|
|
105
|
+
cmd: echo "{id} {state}"
|
|
106
|
+
five:
|
|
107
|
+
color: "#00ff00"
|
|
108
|
+
image: numbers/five_9278222.png
|
|
109
|
+
cmd: echo "{id} {state}"
|
|
110
|
+
"4":
|
|
111
|
+
default: five
|
|
112
|
+
states:
|
|
113
|
+
off:
|
|
114
|
+
color: "#000099"
|
|
115
|
+
cmd: echo "{id} {state}"
|
|
116
|
+
one:
|
|
117
|
+
color: "#00ff00"
|
|
118
|
+
image: numbers/one_9278045.png
|
|
119
|
+
cmd: echo "{id} {state}"
|
|
120
|
+
two:
|
|
121
|
+
color: "#00ff00"
|
|
122
|
+
image: numbers/two_9278103.png
|
|
123
|
+
cmd: echo "{id} {state}"
|
|
124
|
+
three:
|
|
125
|
+
color: "#00ff00"
|
|
126
|
+
image: numbers/three_9278150.png
|
|
127
|
+
cmd: echo "{id} {state}"
|
|
128
|
+
four:
|
|
129
|
+
color: "#00ff00"
|
|
130
|
+
image: numbers/four_9278183.png
|
|
131
|
+
cmd: echo "{id} {state}"
|
|
132
|
+
five:
|
|
133
|
+
color: "#00ff00"
|
|
134
|
+
image: numbers/five_9278222.png
|
|
135
|
+
cmd: echo "{id} {state}"
|
|
136
|
+
"5":
|
|
137
|
+
states:
|
|
138
|
+
off:
|
|
139
|
+
color: "#000099"
|
|
140
|
+
cmd: echo "{id} {state}"
|
|
141
|
+
one:
|
|
142
|
+
color: "#00ff00"
|
|
143
|
+
image: numbers/one_9278045.png
|
|
144
|
+
cmd: echo "{id} {state}"
|
|
145
|
+
two:
|
|
146
|
+
color: "#00ff00"
|
|
147
|
+
image: numbers/two_9278103.png
|
|
148
|
+
cmd: echo "{id} {state}"
|
|
149
|
+
three:
|
|
150
|
+
color: "#00ff00"
|
|
151
|
+
image: numbers/three_9278150.png
|
|
152
|
+
cmd: echo "{id} {state}"
|
|
153
|
+
four:
|
|
154
|
+
color: "#00ff00"
|
|
155
|
+
image: numbers/four_9278183.png
|
|
156
|
+
cmd: echo "{id} {state}"
|
|
157
|
+
five:
|
|
158
|
+
color: "#00ff00"
|
|
159
|
+
image: numbers/five_9278222.png
|
|
160
|
+
cmd: echo "{id} {state}"
|
|
161
|
+
left:
|
|
162
|
+
"0":
|
|
163
|
+
states:
|
|
164
|
+
on:
|
|
165
|
+
color: "#000000"
|
|
166
|
+
cmd: echo "{id} {state}"
|
|
167
|
+
right:
|
|
168
|
+
"0":
|
|
169
|
+
states:
|
|
170
|
+
on:
|
|
171
|
+
color: "#000000"
|
|
172
|
+
cmd: echo "{id} {state}"
|
|
173
|
+
knobs:
|
|
174
|
+
knobTL:
|
|
175
|
+
states:
|
|
176
|
+
on:
|
|
177
|
+
cmd: echo "{id} {state}"
|
|
178
|
+
group: ""
|
|
179
|
+
knobCL:
|
|
180
|
+
states:
|
|
181
|
+
on:
|
|
182
|
+
cmd: echo "{id} {state}"
|
|
183
|
+
group: ""
|
|
184
|
+
knobBL:
|
|
185
|
+
states:
|
|
186
|
+
on:
|
|
187
|
+
cmd: echo "{id} {state}"
|
|
188
|
+
opcua: ns=2;s=Is{simnbr}.Audio.in.VolumeAccustic
|
|
189
|
+
group: ""
|
|
190
|
+
knobTR:
|
|
191
|
+
states:
|
|
192
|
+
on:
|
|
193
|
+
cmd: echo "{id} {state}"
|
|
194
|
+
group: ""
|
|
195
|
+
knobCR:
|
|
196
|
+
states:
|
|
197
|
+
on:
|
|
198
|
+
cmd: echo "{id} {state}"
|
|
199
|
+
group: ""
|
|
200
|
+
knobBR:
|
|
201
|
+
states:
|
|
202
|
+
on:
|
|
203
|
+
cmd: echo "{id} {state}"
|
|
204
|
+
group: ""
|
|
205
|
+
parameters:
|
|
206
|
+
hostname: 127.0.0.1
|
|
207
|
+
simnbr: "1"
|
|
208
|
+
endpointurl: opc.tcp://{hostname}:4840
|
|
209
|
+
nodeid: ns=0;s=nodeID
|
|
210
|
+
verbose: true
|
package/test.mjs
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { BaseLoupeDeckHandler } from './common/BaseLoupeDeckHandler.mjs'
|
|
2
2
|
|
|
3
|
-
var config='config.
|
|
3
|
+
var config='config.yaml'
|
|
4
|
+
|
|
5
|
+
// Check if a config file exists
|
|
6
|
+
import { existsSync } from 'fs'
|
|
7
|
+
if (existsSync(config)) {
|
|
8
|
+
console.log(`Using config file: ${config}`)
|
|
9
|
+
} else if (existsSync(config.replace('.yaml', '.json'))) {
|
|
10
|
+
// If a JSON config file exists, use it instead
|
|
11
|
+
config = config.replace('.yaml', '.json')
|
|
12
|
+
console.log(`Using config file: ${config}`)
|
|
13
|
+
} else {
|
|
14
|
+
// If no config file exists, exit with an error message
|
|
15
|
+
console.error(`Config file ${config} does not exist. Please create it.`)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
4
18
|
|
|
5
19
|
/**
|
|
6
20
|
* Initialize the Handler using a default config-File
|