loupedeck-commander 1.3.0 → 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 +11 -4
- package/common/button.mjs +223 -181
- package/common/utils.mjs +28 -7
- package/config.yaml +6 -0
- package/interfaces/baseif.mjs +1 -1
- package/interfaces/opcuaif.mjs +59 -34
- package/package.json +3 -2
- package/profile-1.yaml +185 -0
- package/profile-2.yaml +210 -0
- package/test.mjs +15 -1
- package/config.json +0 -13
- package/profile-1.json +0 -268
- package/profile-2.json +0 -290
package/common/utils.mjs
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import YAML from 'yaml'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* Read a JSON
|
|
5
|
+
* Read a Config file in either JSON or YAML Fileformat
|
|
6
|
+
* @param {string} fileName - The name of the file to read
|
|
7
|
+
* @returns {object} - The parsed object from the file
|
|
5
8
|
*/
|
|
6
|
-
export function
|
|
7
|
-
let
|
|
9
|
+
export function readConfigFile (fileName) {
|
|
10
|
+
let obj = undefined
|
|
8
11
|
try {
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
//console.log("Reading File:", fileName)
|
|
13
|
+
let data = readFileSync(fileName, 'utf8')
|
|
14
|
+
// If the file is a YAML file, parse it
|
|
15
|
+
if (fileName.endsWith('.yaml') || fileName.endsWith('.yml')) {
|
|
16
|
+
obj = YAML.parse(data)
|
|
17
|
+
} else if (fileName.endsWith('.json')) {
|
|
18
|
+
// If the file is a JSON file, parse it
|
|
19
|
+
obj = JSON.parse(data)
|
|
20
|
+
// automatically convert all json to yaml
|
|
21
|
+
writeYAMLFile(fileName.replace(".json",".yaml"), obj)
|
|
22
|
+
}
|
|
11
23
|
} catch (error) {
|
|
12
|
-
console.info(`Error reading File: ${fileName}
|
|
13
|
-
return data
|
|
24
|
+
console.info(`Error reading File: ${fileName}`, error)
|
|
14
25
|
}
|
|
26
|
+
return obj
|
|
15
27
|
}
|
|
16
28
|
|
|
17
29
|
/**
|
|
@@ -22,6 +34,15 @@ export function writeJSONFile (fileName, jsonObj) {
|
|
|
22
34
|
writeFileSync(fileName, data)
|
|
23
35
|
}
|
|
24
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Write a JSON File
|
|
39
|
+
*/
|
|
40
|
+
export function writeYAMLFile (fileName, jsonObj) {
|
|
41
|
+
const data = YAML.stringify(jsonObj)
|
|
42
|
+
writeFileSync(fileName, data)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
25
46
|
/**
|
|
26
47
|
* Calculate the delta of a value within a range between min and max with overflow
|
|
27
48
|
* @param {*} data
|
package/config.yaml
ADDED
package/interfaces/baseif.mjs
CHANGED
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 = {}
|
|
@@ -89,7 +76,11 @@ export class OPCUAIf extends BaseIf {
|
|
|
89
76
|
if (elem.params && elem.params.nodeid) {
|
|
90
77
|
let formattedNodeId = this.formatString(elem.params.nodeid, options)
|
|
91
78
|
let monitoredItemId = await this.Subscribe(formattedNodeId)
|
|
92
|
-
|
|
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)
|
|
93
84
|
this.buttons[monitoredItemId] = i
|
|
94
85
|
}
|
|
95
86
|
await this.monitorStates(elem, options)
|
|
@@ -101,7 +92,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
101
92
|
}
|
|
102
93
|
|
|
103
94
|
/**
|
|
104
|
-
*
|
|
95
|
+
* Monitor the state OPC/UA node of the given element
|
|
105
96
|
* @param {*} elem : Elem Object
|
|
106
97
|
* @param {*} options
|
|
107
98
|
*/
|
|
@@ -113,7 +104,11 @@ export class OPCUAIf extends BaseIf {
|
|
|
113
104
|
if (state.opcua) {
|
|
114
105
|
let formattedNodeId = this.formatString(state.opcua, options)
|
|
115
106
|
let monitoredItemId = await this.Subscribe(formattedNodeId)
|
|
116
|
-
|
|
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)
|
|
117
112
|
this.buttons[monitoredItemId] = i
|
|
118
113
|
}
|
|
119
114
|
}
|
|
@@ -164,6 +159,13 @@ export class OPCUAIf extends BaseIf {
|
|
|
164
159
|
}
|
|
165
160
|
}
|
|
166
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
|
+
*/
|
|
167
169
|
async call(opcuaNode, options = {}) {
|
|
168
170
|
var res = this.Check(options)
|
|
169
171
|
if (res < 0) {
|
|
@@ -171,7 +173,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
171
173
|
return false
|
|
172
174
|
}
|
|
173
175
|
|
|
174
|
-
var nodeId = super.
|
|
176
|
+
var nodeId = super.call(opcuaNode, options)
|
|
175
177
|
|
|
176
178
|
var type = this.types[nodeId]
|
|
177
179
|
var value = options.value
|
|
@@ -211,6 +213,21 @@ export class OPCUAIf extends BaseIf {
|
|
|
211
213
|
return 0
|
|
212
214
|
}
|
|
213
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
|
+
*/
|
|
214
231
|
async Disconnect() {
|
|
215
232
|
if (this.#client) {
|
|
216
233
|
if (this.#session)
|
|
@@ -220,6 +237,10 @@ export class OPCUAIf extends BaseIf {
|
|
|
220
237
|
this.LogInfo(`OPCUAIf: Disconnected\n`);
|
|
221
238
|
}
|
|
222
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
|
+
*/
|
|
223
244
|
async Connect(url) {
|
|
224
245
|
let self = this
|
|
225
246
|
if (this.#client){
|
|
@@ -267,9 +288,9 @@ export class OPCUAIf extends BaseIf {
|
|
|
267
288
|
this.#client.on("after_reconnection", (err) => {
|
|
268
289
|
self.LogInfo(`OPCUAIf: After Reconnection event => ${err}\n`);
|
|
269
290
|
});
|
|
270
|
-
this.#client.on("security_token_renewed", () => {
|
|
291
|
+
/*this.#client.on("security_token_renewed", () => {
|
|
271
292
|
self.LogDebug(`OPCUAIf: security_token_renewed\n`);
|
|
272
|
-
})
|
|
293
|
+
})*/
|
|
273
294
|
this.#client.on("lifetime_75", (token) => { })
|
|
274
295
|
|
|
275
296
|
this.LogInfo(`OPCUAIf: connecting client to ${url}\n`);//, this.#session.toString());
|
|
@@ -299,16 +320,22 @@ export class OPCUAIf extends BaseIf {
|
|
|
299
320
|
requestedPublishingInterval: this.#publishingInterval
|
|
300
321
|
});
|
|
301
322
|
|
|
302
|
-
this.LogInfo(`OPCUAIf: session created\n`)
|
|
303
|
-
this.LogInfo(`OPCUAIf: client\n`);
|
|
304
|
-
this.LogInfo(`OPCUAIf: subscription\n`);
|
|
323
|
+
this.LogInfo(`OPCUAIf: session created\n`);
|
|
324
|
+
// this.LogInfo(`OPCUAIf: client\n`);
|
|
325
|
+
// this.LogInfo(`OPCUAIf: subscription\n`);
|
|
305
326
|
this.#connected = true
|
|
306
327
|
this.#endpointurl = url
|
|
307
328
|
}
|
|
308
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
|
+
*/
|
|
309
337
|
async Subscribe(nodeID) {
|
|
310
338
|
// install monitored item
|
|
311
|
-
|
|
312
339
|
const keys = Object.keys(this.monitoreditems)
|
|
313
340
|
for (let i = 0; i < keys.length; i++) {
|
|
314
341
|
const key = keys[i]
|
|
@@ -324,7 +351,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
324
351
|
attributeId: AttributeIds.Value
|
|
325
352
|
};
|
|
326
353
|
const monitoringParameters = {
|
|
327
|
-
samplingInterval:
|
|
354
|
+
samplingInterval: this.#samplingInterval,
|
|
328
355
|
discardOldest: true,
|
|
329
356
|
queueSize: 10
|
|
330
357
|
};
|
|
@@ -390,12 +417,10 @@ export class OPCUAIf extends BaseIf {
|
|
|
390
417
|
}
|
|
391
418
|
} else {
|
|
392
419
|
self.LogError("OPCUAIf: write NOT ok", nodeID, value, "\n");
|
|
393
|
-
self.LogError(err)
|
|
394
420
|
}
|
|
395
421
|
});
|
|
396
422
|
} catch (err) {
|
|
397
423
|
self.LogError("OPCUAIf: write NOT ok", nodeID, value, "\n");
|
|
398
|
-
self.LogError(err)
|
|
399
424
|
}
|
|
400
425
|
}
|
|
401
426
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loupedeck-commander",
|
|
3
|
-
"version": "1.3.
|
|
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
|