loupedeck-commander 1.2.5 → 1.2.7
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/common/ApplicationConfig.mjs +35 -18
- package/common/BaseLoupeDeckHandler.mjs +9 -2
- package/common/touchbuttons.mjs +20 -15
- package/config.json +4 -0
- package/interfaces/baseif.mjs +3 -1
- package/interfaces/opcuaif.mjs +90 -17
- package/numbers/README.md +5 -0
- package/numbers/five_9278222.png +0 -0
- package/numbers/four_9278183.png +0 -0
- package/numbers/one_9278045.png +0 -0
- package/numbers/six_9278279.png +0 -0
- package/numbers/three_9278150.png +0 -0
- package/numbers/two_9278103.png +0 -0
- package/package.json +5 -5
- package/profile-1.json +5 -110
- package/profile-2.json +290 -0
- package/profile-profile-1-sav.json +373 -0
|
@@ -19,7 +19,7 @@ export class ApplicationConfig {
|
|
|
19
19
|
else{
|
|
20
20
|
this.application = config.application
|
|
21
21
|
for (let i = 0; i < config.profiles.length; i++) {
|
|
22
|
-
const profile = new Profile(config.profiles[i])
|
|
22
|
+
const profile = new Profile(config.profiles[i],config.profiles.length,i)
|
|
23
23
|
if (profile.loaded){
|
|
24
24
|
this.profiles.push(profile)
|
|
25
25
|
}else{
|
|
@@ -45,10 +45,14 @@ class Profile {
|
|
|
45
45
|
#file = ''
|
|
46
46
|
loaded = false
|
|
47
47
|
#error = true
|
|
48
|
+
#profileCount = 0
|
|
49
|
+
#index = 0
|
|
48
50
|
|
|
49
|
-
constructor (data) {
|
|
51
|
+
constructor (data,profileCount,index) {
|
|
50
52
|
this.name = data.name
|
|
51
53
|
this.#file = data.file
|
|
54
|
+
this.#profileCount = profileCount
|
|
55
|
+
this.#index = index
|
|
52
56
|
this.touch = new TouchConfig({})
|
|
53
57
|
this.buttons = new ButtonConfig().buttons
|
|
54
58
|
this.knobs = new KnobsConfig().knobs
|
|
@@ -59,7 +63,7 @@ class Profile {
|
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
loadFromFile (fileName) {
|
|
62
|
-
console.info(`ProfileConfig: Loading Profile File ${fileName}`)
|
|
66
|
+
console.info(`ProfileConfig: Loading Profile File ${fileName}, Index ${this.#index}`)
|
|
63
67
|
const config = readJSONFile(fileName)
|
|
64
68
|
if (config === undefined) {
|
|
65
69
|
console.warn(`ProfileConfig: Cannot parse/load Profile File ${fileName}`)
|
|
@@ -70,12 +74,12 @@ class Profile {
|
|
|
70
74
|
}else if (!config.touch){
|
|
71
75
|
console.warn(`ProfileConfig: File ${fileName} is missing a touch attribute`)
|
|
72
76
|
return false
|
|
73
|
-
}else if (!config.buttons){
|
|
74
|
-
console.warn(`ProfileConfig: File ${fileName} is missing a buttons attribute`)
|
|
75
|
-
return false
|
|
76
77
|
}else if (!config.parameters){
|
|
77
78
|
console.warn(`ProfileConfig: File ${fileName} is missing a parameters attribute`)
|
|
78
79
|
return false
|
|
80
|
+
}else if (!config.buttons){
|
|
81
|
+
console.info(`ProfileConfig: File ${fileName} is missing a buttons attribute - will be used to switch profiles by default`)
|
|
82
|
+
// return false
|
|
79
83
|
}
|
|
80
84
|
this.profile = config.profile
|
|
81
85
|
this.description = config.description
|
|
@@ -84,7 +88,7 @@ class Profile {
|
|
|
84
88
|
this.touch = new TouchConfig(config.touch)
|
|
85
89
|
// Load the Configurations for Button-Areas
|
|
86
90
|
|
|
87
|
-
this.buttons = new ButtonConfig(config.buttons).buttons
|
|
91
|
+
this.buttons = new ButtonConfig(config.buttons,this.#profileCount,this.#index).buttons
|
|
88
92
|
this.knobs = new KnobsConfig(config.knobs).knobs
|
|
89
93
|
// Load Parameters.parameters = config.parameters
|
|
90
94
|
this.parameters = new ParametersConfig(config.parameters).parameters
|
|
@@ -154,19 +158,32 @@ class TouchConfig {
|
|
|
154
158
|
* Class that handles the different configs for the touch displays of the device covering Loupedeck Live (without knob) and also CT (with knob)
|
|
155
159
|
*/
|
|
156
160
|
class ButtonConfig {
|
|
157
|
-
buttons = {
|
|
158
|
-
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
161
|
+
buttons = {}
|
|
162
|
+
defaultButtons = {
|
|
163
|
+
"0" : {"states" : { "off" : { "filter": "pressed", "color": "#000000", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed","color": "#ff0000", "cmd": "echo \"{id} {state}\"" } }, group : "onoff" },
|
|
164
|
+
"1" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 0, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
165
|
+
"2" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 1, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
166
|
+
"3" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 2, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
167
|
+
"4" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 3, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
168
|
+
"5" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 4, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
169
|
+
"6" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 5, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
170
|
+
"7" : {"states" : { "off" : { "filter": "pressed", "color": "#000055", "cmd": "echo \"{id} {state}\"" }, "on" : { "filter": "pressed", "profile": 6, "color": "#00ff00", "cmd": "echo \"{id} {state}\"" } }, group : "profiles" },
|
|
166
171
|
}
|
|
167
172
|
|
|
168
|
-
constructor (data) {
|
|
169
|
-
|
|
173
|
+
constructor (data,profileCount,index) {
|
|
174
|
+
if (data)
|
|
175
|
+
return this.loadFromJSON(data)
|
|
176
|
+
// Default to profile switching buttons
|
|
177
|
+
var keys = Object.keys(this.defaultButtons)
|
|
178
|
+
for (let i = 0; i <= profileCount; i++) {
|
|
179
|
+
var key = keys[i]
|
|
180
|
+
this.buttons[key] = this.defaultButtons[key]
|
|
181
|
+
if (i==(index+1)){
|
|
182
|
+
this.buttons[key].default = "on"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
170
187
|
}
|
|
171
188
|
|
|
172
189
|
loadFromJSON (data) {
|
|
@@ -134,6 +134,13 @@ export class BaseLoupeDeckHandler {
|
|
|
134
134
|
const dLeft = this.device.displays.left
|
|
135
135
|
const dRight = this.device.displays.right
|
|
136
136
|
const dCenter = this.device.displays.center
|
|
137
|
+
|
|
138
|
+
this.screens.center = undefined
|
|
139
|
+
this.screens.left = undefined
|
|
140
|
+
this.screens.right = undefined
|
|
141
|
+
this.buttons = undefined
|
|
142
|
+
this.knobs = undefined
|
|
143
|
+
|
|
137
144
|
|
|
138
145
|
this.screens.center = new ButtonField('center', this.device.rows, this.device.columns, dCenter.width, dCenter.height, profile.touch.center,profile)
|
|
139
146
|
this.screens.left = new ButtonField('left', 1, 1, dLeft.width, dLeft.height, profile.touch.left,profile)
|
|
@@ -222,7 +229,7 @@ export class BaseLoupeDeckHandler {
|
|
|
222
229
|
const id = event.id
|
|
223
230
|
if (Number.isInteger(id)){
|
|
224
231
|
ok = await this.buttons.pressed(id)
|
|
225
|
-
await this.buttons.draw(this.device)
|
|
232
|
+
//await this.buttons.draw(this.device)
|
|
226
233
|
}else{
|
|
227
234
|
ok = await this.knobs.pressed(id)
|
|
228
235
|
}
|
|
@@ -237,7 +244,7 @@ export class BaseLoupeDeckHandler {
|
|
|
237
244
|
const id = event.id
|
|
238
245
|
if (Number.isInteger(id) && this.buttons){
|
|
239
246
|
ok = await this.buttons.released(id)
|
|
240
|
-
await this.buttons.draw(this.device)
|
|
247
|
+
//await this.buttons.draw(this.device)
|
|
241
248
|
}else{
|
|
242
249
|
if(this.knobs)
|
|
243
250
|
ok = await this.knobs.released(id)
|
package/common/touchbuttons.mjs
CHANGED
|
@@ -64,9 +64,9 @@ export class ButtonField {
|
|
|
64
64
|
#keys = []
|
|
65
65
|
#type
|
|
66
66
|
#name
|
|
67
|
-
#
|
|
67
|
+
#profile
|
|
68
68
|
|
|
69
|
-
constructor (name, rows, columns, width, height, data,
|
|
69
|
+
constructor (name, rows, columns, width, height, data, profile) {
|
|
70
70
|
console.info(`ButtonField ${name.padEnd(10, ' ')} Buttons: ${rows} x ${columns} , Pixels ${width} x ${height}`)
|
|
71
71
|
this.#name = name
|
|
72
72
|
this.width = width
|
|
@@ -75,17 +75,17 @@ export class ButtonField {
|
|
|
75
75
|
this.#columns = columns
|
|
76
76
|
this.#screen = this.width > 0 && this.height > 0
|
|
77
77
|
this.#type = 'button'
|
|
78
|
+
this.#profile = profile
|
|
78
79
|
if (this.#screen) { this.#type = 'touch' }
|
|
79
80
|
|
|
80
81
|
const keys = Object.keys(data)
|
|
81
82
|
for (let i = 0; i < keys.length; i++) {
|
|
82
83
|
const key = keys[i]
|
|
83
|
-
const tb = new Button(`${this.#type}-${key}`, width / columns, height / rows, data[key],key,
|
|
84
|
+
const tb = new Button(`${this.#type}-${key}`, width / columns, height / rows, data[key],key,this.#profile.parameters)
|
|
84
85
|
this.#buttons[key] = tb
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
this.#keys = keys
|
|
88
|
-
this.#config = config
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
|
|
@@ -124,10 +124,10 @@ export class ButtonField {
|
|
|
124
124
|
for (let i = 0; i < this.#keys.length; i++) {
|
|
125
125
|
const key = this.#keys[i]
|
|
126
126
|
if (isNaN(key)) {
|
|
127
|
-
await this.#buttons[key].load(this.#
|
|
127
|
+
await this.#buttons[key].load(this.#profile)
|
|
128
128
|
} else {
|
|
129
129
|
const iVal = parseInt(key, 10)
|
|
130
|
-
await this.#buttons[iVal].load(this.#
|
|
130
|
+
await this.#buttons[iVal].load(this.#profile)
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -190,7 +190,7 @@ export class ButtonField {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
export class Button {
|
|
193
|
-
#
|
|
193
|
+
#profile
|
|
194
194
|
width = 0
|
|
195
195
|
height = 0
|
|
196
196
|
|
|
@@ -212,8 +212,8 @@ export class Button {
|
|
|
212
212
|
text = ''
|
|
213
213
|
font = '16px Arial'
|
|
214
214
|
|
|
215
|
-
#x
|
|
216
|
-
#y
|
|
215
|
+
#x = 0
|
|
216
|
+
#y = 0
|
|
217
217
|
#moveLeft
|
|
218
218
|
#moveRight
|
|
219
219
|
#moveUp
|
|
@@ -260,7 +260,10 @@ export class Button {
|
|
|
260
260
|
if (data.nodeid){
|
|
261
261
|
this.#nodeid = format(data.nodeid, params)
|
|
262
262
|
}
|
|
263
|
-
|
|
263
|
+
if (data.default) {
|
|
264
|
+
this.#index = this.#keys.indexOf(data.default)
|
|
265
|
+
}
|
|
266
|
+
|
|
264
267
|
}
|
|
265
268
|
|
|
266
269
|
setState (index = 0) {
|
|
@@ -282,7 +285,7 @@ export class Button {
|
|
|
282
285
|
id:idx,
|
|
283
286
|
color: `rgba(${r}, ${g}, ${b})`
|
|
284
287
|
}
|
|
285
|
-
// console.log(' Set Button Color',val.id,elem.color, val.color)
|
|
288
|
+
// console.log(' Set Button Color',id, val.id,elem.color, val.color)
|
|
286
289
|
device.setButtonColor(val)
|
|
287
290
|
} catch (error) {
|
|
288
291
|
console.error(' Error', error)
|
|
@@ -315,7 +318,7 @@ export class Button {
|
|
|
315
318
|
}
|
|
316
319
|
|
|
317
320
|
async load (globalConfig) {
|
|
318
|
-
this.#
|
|
321
|
+
this.#profile = globalConfig
|
|
319
322
|
for (let i = 0; i < this.#keys.length; i++) {
|
|
320
323
|
const key = this.#keys[i]
|
|
321
324
|
const elem = this.#states[key]
|
|
@@ -392,7 +395,7 @@ export class Button {
|
|
|
392
395
|
|
|
393
396
|
updateState(index,eventType){
|
|
394
397
|
this.#index = index
|
|
395
|
-
this.#event = eventType
|
|
398
|
+
this.#event = eventType
|
|
396
399
|
// Update the State according to the correctly pressed state
|
|
397
400
|
if (this.#index < 0) { this.#index = this.#keys.length - 1 }
|
|
398
401
|
this.#index %= this.#keys.length
|
|
@@ -479,7 +482,7 @@ export class Button {
|
|
|
479
482
|
return
|
|
480
483
|
}
|
|
481
484
|
|
|
482
|
-
if (elem.profile){
|
|
485
|
+
if (elem.profile !== undefined) {
|
|
483
486
|
profileEmitter.emit("profileChanged", elem.profile)
|
|
484
487
|
}
|
|
485
488
|
|
|
@@ -492,7 +495,7 @@ export class Button {
|
|
|
492
495
|
// and also all attributes of elem + global config
|
|
493
496
|
const params = {
|
|
494
497
|
text: this.getCurrentText(),
|
|
495
|
-
...this.#
|
|
498
|
+
...this.#profile.parameters,
|
|
496
499
|
...elem,
|
|
497
500
|
id: this.id,
|
|
498
501
|
key: this.key,
|
|
@@ -500,6 +503,8 @@ export class Button {
|
|
|
500
503
|
state: this.#keys[this.#index],
|
|
501
504
|
min: this.#min,
|
|
502
505
|
max: this.#max,
|
|
506
|
+
x: (this.#x %100),
|
|
507
|
+
y: (this.#y %100)
|
|
503
508
|
}
|
|
504
509
|
|
|
505
510
|
if (!params.value)
|
package/config.json
CHANGED
package/interfaces/baseif.mjs
CHANGED
|
@@ -14,7 +14,9 @@ export class BaseIf extends EventEmitter {
|
|
|
14
14
|
|
|
15
15
|
this.cmd = cmd
|
|
16
16
|
this.options = options
|
|
17
|
-
this.formattedCommand = this.formatString(cmd, options)
|
|
17
|
+
this.formattedCommand = this.formatString(cmd, options)
|
|
18
|
+
this.LogDebug("Formatted command: ", this.formattedCommand,"\n")
|
|
19
|
+
this.LogDebug("Options",JSON.stringify(options),"\n" )
|
|
18
20
|
return this.formattedCommand
|
|
19
21
|
}
|
|
20
22
|
|
package/interfaces/opcuaif.mjs
CHANGED
|
@@ -23,7 +23,6 @@ const subscriptionParameters = {
|
|
|
23
23
|
requestedPublishingInterval: 1000
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
/**
|
|
28
27
|
* Our Special-Handler just used the Default - and adds Vibration after triggers through Button-Releases
|
|
29
28
|
*/
|
|
@@ -35,6 +34,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
35
34
|
#connected
|
|
36
35
|
#endpointurl
|
|
37
36
|
monitoreditems
|
|
37
|
+
types
|
|
38
38
|
buttons
|
|
39
39
|
#callback
|
|
40
40
|
constructor() {
|
|
@@ -55,6 +55,12 @@ export class OPCUAIf extends BaseIf {
|
|
|
55
55
|
this.LogInfo(`OPCUAIf Stopped\n`)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Initialize the OPCUA client and subscribe to monitored items.
|
|
60
|
+
* @param {*} options
|
|
61
|
+
* @param {*} config
|
|
62
|
+
* @param {*} callbackFunction
|
|
63
|
+
*/
|
|
58
64
|
async init( options = {},config = {},callbackFunction){
|
|
59
65
|
var res = this.Check(options)
|
|
60
66
|
if (res<0){
|
|
@@ -64,28 +70,87 @@ export class OPCUAIf extends BaseIf {
|
|
|
64
70
|
this.#endpointurl = this.formatString(options.endpointurl,options)
|
|
65
71
|
this.#callback = callbackFunction
|
|
66
72
|
this.monitoreditems = {}
|
|
73
|
+
this.types = {}
|
|
67
74
|
this.buttons = {}
|
|
68
75
|
this.LogInfo(`OPCUAIf init ${this.#endpointurl}\n`);
|
|
69
76
|
|
|
70
77
|
await this.Connect(this.#endpointurl);
|
|
71
78
|
|
|
72
|
-
let
|
|
73
|
-
const
|
|
74
|
-
for (let
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
let fields = [config.touch.center, config.knobs, config.buttons]
|
|
80
|
+
const fieldKeys = Object.keys(fields)
|
|
81
|
+
for (let f = 0; f < fieldKeys.length; f++) {
|
|
82
|
+
let field=fields[f]
|
|
83
|
+
const keys = Object.keys(field)
|
|
84
|
+
for (let i = 0; i < keys.length; i++) {
|
|
85
|
+
const key = keys[i]
|
|
86
|
+
const elem = field[key]
|
|
87
|
+
if (elem.nodeid){
|
|
88
|
+
let format = this.formatString(elem.nodeid,options)
|
|
89
|
+
let monitoredItemId = await this.Subscribe(format)
|
|
90
|
+
this.buttons[monitoredItemId] = i
|
|
91
|
+
}
|
|
92
|
+
await this.monitorStates(elem,options)
|
|
81
93
|
}
|
|
82
|
-
|
|
83
94
|
}
|
|
84
95
|
} catch (error) {
|
|
85
96
|
this.LogError(`OPCUAIf: Error $error\n`)
|
|
86
97
|
}
|
|
87
98
|
}
|
|
88
99
|
|
|
100
|
+
/**
|
|
101
|
+
*
|
|
102
|
+
* @param {*} elem : Elem Object
|
|
103
|
+
* @param {*} options
|
|
104
|
+
*/
|
|
105
|
+
async monitorStates(elem,options){
|
|
106
|
+
const stateKeys = Object.keys(elem.states)
|
|
107
|
+
for (let i = 0; i < stateKeys.length; i++) {
|
|
108
|
+
const key2 = stateKeys[i]
|
|
109
|
+
const state = elem.states[key2]
|
|
110
|
+
if (state.opcua){
|
|
111
|
+
let format = this.formatString(state.opcua,options)
|
|
112
|
+
let monitoredItemId = await this.Subscribe(format)
|
|
113
|
+
this.buttons[monitoredItemId] = i
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Convert the given value to the specified type.
|
|
120
|
+
* @param {*} value : The value to convert.
|
|
121
|
+
* @param {*} type : The type to convert to. Can be one of the following:
|
|
122
|
+
* - DataType.Int16
|
|
123
|
+
* - DataType.Int32
|
|
124
|
+
* - DataType.Float
|
|
125
|
+
* - DataType.String
|
|
126
|
+
* @returns the converted value.
|
|
127
|
+
*/
|
|
128
|
+
convert(value,type){
|
|
129
|
+
switch(type){
|
|
130
|
+
case DataType.Int16:
|
|
131
|
+
case DataType.Int32:
|
|
132
|
+
if (typeof value == "number"){
|
|
133
|
+
if (Number.isInteger(value))
|
|
134
|
+
return value
|
|
135
|
+
else
|
|
136
|
+
return Math.trunc(value)
|
|
137
|
+
}
|
|
138
|
+
return parseInt(value,10)
|
|
139
|
+
break
|
|
140
|
+
case DataType.Float:
|
|
141
|
+
if (typeof value == "number")
|
|
142
|
+
return value
|
|
143
|
+
return parseFloat(value)
|
|
144
|
+
break;
|
|
145
|
+
case DataType.String:
|
|
146
|
+
if (typeof value == "number")
|
|
147
|
+
return value.toString();
|
|
148
|
+
return value
|
|
149
|
+
default:
|
|
150
|
+
return value
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
89
154
|
async call (opcuaNode, options = {}) {
|
|
90
155
|
var res = this.Check(options)
|
|
91
156
|
if (res<0){
|
|
@@ -94,10 +159,15 @@ export class OPCUAIf extends BaseIf {
|
|
|
94
159
|
}
|
|
95
160
|
|
|
96
161
|
var nodeId = super.formatString(opcuaNode, options)
|
|
97
|
-
var value = super.formatString(options.value, options)
|
|
98
162
|
|
|
99
|
-
|
|
100
|
-
|
|
163
|
+
var type = this.types[nodeId]
|
|
164
|
+
var value = options.value
|
|
165
|
+
if (typeof value == "string")
|
|
166
|
+
value = super.formatString(options.value, options)
|
|
167
|
+
|
|
168
|
+
var convertedValue = this.convert(value,type)
|
|
169
|
+
this.LogInfo(`OPCUAIf: write ${nodeId} => ${value}\n`)
|
|
170
|
+
await this.Write(nodeId,convertedValue,type)
|
|
101
171
|
|
|
102
172
|
var NewState = "waiting"
|
|
103
173
|
return NewState
|
|
@@ -109,13 +179,13 @@ export class OPCUAIf extends BaseIf {
|
|
|
109
179
|
this.LogError(`OPCUAIf: mandatory parameter missing\n`)
|
|
110
180
|
return res
|
|
111
181
|
}
|
|
112
|
-
if (!options
|
|
182
|
+
if (!"endpointurl" in options){
|
|
113
183
|
this.LogError(`OPCUAIf: mandatory parameter endpointurl missing\n`)
|
|
114
184
|
return -11}
|
|
115
|
-
if (!options
|
|
185
|
+
if (!"nodeid" in options){
|
|
116
186
|
this.LogError(`OPCUAIf: mandatory parameter nodeid missing\n`)
|
|
117
187
|
return -12}
|
|
118
|
-
if (!options
|
|
188
|
+
if (!"value" in options){
|
|
119
189
|
this.LogError(`OPCUAIf: mandatory parameter value missing\n`)
|
|
120
190
|
return -13}
|
|
121
191
|
return 0
|
|
@@ -242,6 +312,9 @@ export class OPCUAIf extends BaseIf {
|
|
|
242
312
|
monitoredItem.on("changed", function (dataValue) {
|
|
243
313
|
var nodeId = self.monitoreditems[this.monitoredItemId]
|
|
244
314
|
var buttonID = self.buttons[this.monitoredItemId]
|
|
315
|
+
// store the type of a nodeid in local dictionary
|
|
316
|
+
self.types[nodeId] = dataValue.value.dataType
|
|
317
|
+
// publish the value to subscribers:
|
|
245
318
|
self.LogInfo(`OPCUAIf: monitored item changed: ${nodeId} => ${dataValue.value.value}\n`);
|
|
246
319
|
self.emit('monitored item changed',buttonID,nodeId, dataValue.value.value)
|
|
247
320
|
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loupedeck-commander",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
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": {
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "node test.mjs",
|
|
8
8
|
"lint": "echo \"INFO: no linter specified\" && exit 0",
|
|
9
9
|
"format": "echo \"INFO: no format rule specified\" && exit 0",
|
|
10
10
|
"start": "node index.mjs"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"canvas": "^
|
|
14
|
-
"loupedeck": "^
|
|
13
|
+
"canvas": "^3.1.0",
|
|
14
|
+
"loupedeck": "^7.0.0",
|
|
15
15
|
"mkdirp": "^3.0.1",
|
|
16
|
-
"node-opcua": "^2.
|
|
16
|
+
"node-opcua": "^2.153.0",
|
|
17
17
|
"string-template": "^1.0.0"
|
|
18
18
|
},
|
|
19
19
|
"author": "Thomas Schneider",
|
package/profile-1.json
CHANGED
|
@@ -228,7 +228,8 @@
|
|
|
228
228
|
"knobBL": {
|
|
229
229
|
"states": {
|
|
230
230
|
"on": {
|
|
231
|
-
"cmd": "echo \"{id} {state}\""
|
|
231
|
+
"cmd": "echo \"{id} {state}\"",
|
|
232
|
+
"opcua": "ns=2;s=Is{simnbr}.Audio.in.VolumeAccustic"
|
|
232
233
|
}
|
|
233
234
|
},
|
|
234
235
|
"group": ""
|
|
@@ -258,117 +259,11 @@
|
|
|
258
259
|
"group": ""
|
|
259
260
|
}
|
|
260
261
|
},
|
|
261
|
-
"buttons": {
|
|
262
|
-
"0": {
|
|
263
|
-
"states": {
|
|
264
|
-
"off": {
|
|
265
|
-
"color": "#000000",
|
|
266
|
-
"cmd": "echo \"{id} {state}\""
|
|
267
|
-
},
|
|
268
|
-
"on": {
|
|
269
|
-
"color": "#550000",
|
|
270
|
-
"cmd": "echo \"{id} {state}\""
|
|
271
|
-
}
|
|
272
|
-
},
|
|
273
|
-
"group": ""
|
|
274
|
-
},
|
|
275
|
-
"1": {
|
|
276
|
-
"states": {
|
|
277
|
-
"off": {
|
|
278
|
-
"color": "#000000",
|
|
279
|
-
"cmd": "echo \"{id} {state}\""
|
|
280
|
-
},
|
|
281
|
-
"on": {
|
|
282
|
-
"color": "#ff0000",
|
|
283
|
-
"cmd": "echo \"{id} {state}\""
|
|
284
|
-
}
|
|
285
|
-
},
|
|
286
|
-
"group": ""
|
|
287
|
-
},
|
|
288
|
-
"2": {
|
|
289
|
-
"states": {
|
|
290
|
-
"off": {
|
|
291
|
-
"color": "#000000",
|
|
292
|
-
"cmd": "echo \"{id} {state}\""
|
|
293
|
-
},
|
|
294
|
-
"on": {
|
|
295
|
-
"color": "#005500",
|
|
296
|
-
"cmd": "echo \"{id} {state}\""
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
"group": ""
|
|
300
|
-
},
|
|
301
|
-
"3": {
|
|
302
|
-
"states": {
|
|
303
|
-
"off": {
|
|
304
|
-
"color": "#000000",
|
|
305
|
-
"cmd": "echo \"{id} {state}\""
|
|
306
|
-
},
|
|
307
|
-
"on": {
|
|
308
|
-
"color": "#00ff00",
|
|
309
|
-
"cmd": "echo \"{id} {state}\""
|
|
310
|
-
}
|
|
311
|
-
},
|
|
312
|
-
"group": ""
|
|
313
|
-
},
|
|
314
|
-
"4": {
|
|
315
|
-
"states": {
|
|
316
|
-
"off": {
|
|
317
|
-
"color": "#000000",
|
|
318
|
-
"cmd": "echo \"{id} {state}\""
|
|
319
|
-
},
|
|
320
|
-
"on": {
|
|
321
|
-
"color": "#000055",
|
|
322
|
-
"cmd": "echo \"{id} {state}\""
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
"group": ""
|
|
326
|
-
},
|
|
327
|
-
"5": {
|
|
328
|
-
"states": {
|
|
329
|
-
"off": {
|
|
330
|
-
"color": "#000000",
|
|
331
|
-
"cmd": "echo \"{id} {state}\""
|
|
332
|
-
},
|
|
333
|
-
"on": {
|
|
334
|
-
"color": "#0000ff",
|
|
335
|
-
"cmd": "echo \"{id} {state}\""
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
"group": ""
|
|
339
|
-
},
|
|
340
|
-
"6": {
|
|
341
|
-
"states": {
|
|
342
|
-
"off": {
|
|
343
|
-
"color": "#000000",
|
|
344
|
-
"cmd": "echo \"{id} {state}\""
|
|
345
|
-
},
|
|
346
|
-
"on": {
|
|
347
|
-
"color": "#555500",
|
|
348
|
-
"cmd": "echo \"{id} {state}\""
|
|
349
|
-
}
|
|
350
|
-
},
|
|
351
|
-
"group": ""
|
|
352
|
-
},
|
|
353
|
-
"7": {
|
|
354
|
-
"states": {
|
|
355
|
-
"off": {
|
|
356
|
-
"color": "#000000",
|
|
357
|
-
"cmd": "echo \"{id} {state}\""
|
|
358
|
-
},
|
|
359
|
-
"on": {
|
|
360
|
-
"color": "#ffff00",
|
|
361
|
-
"cmd": "echo \"{id} {state}\"",
|
|
362
|
-
"http": "http://{hostname}:7778/control/connections",
|
|
363
|
-
"opcua": "ns=4;s=Is{simnbr}.Kvm.out.Source"
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
"group": ""
|
|
367
|
-
}
|
|
368
|
-
},
|
|
369
262
|
"parameters": {
|
|
370
263
|
"hostname": "127.0.0.1",
|
|
264
|
+
"simnbr": "1",
|
|
371
265
|
"endpointurl": "opc.tcp://{hostname}:4840",
|
|
372
|
-
"nodeid" : "ns=0;s=nodeID"
|
|
266
|
+
"nodeid" : "ns=0;s=nodeID",
|
|
267
|
+
"verbose": true
|
|
373
268
|
}
|
|
374
269
|
}
|
package/profile-2.json
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "profile-1",
|
|
3
|
+
"profile": "example",
|
|
4
|
+
"description": "",
|
|
5
|
+
"touch": {
|
|
6
|
+
"center": {
|
|
7
|
+
"0": {
|
|
8
|
+
"default": "one",
|
|
9
|
+
"states": {
|
|
10
|
+
"off": {
|
|
11
|
+
"color": "#000099",
|
|
12
|
+
"cmd": "echo \"{id} {state}\""
|
|
13
|
+
},
|
|
14
|
+
"one": {
|
|
15
|
+
"color": "#00ff00",
|
|
16
|
+
"image": "numbers/one_9278045.png",
|
|
17
|
+
"cmd": "echo \"{id} {state}\""
|
|
18
|
+
},
|
|
19
|
+
"two": {
|
|
20
|
+
"color": "#00ff00",
|
|
21
|
+
"image": "numbers/two_9278103.png",
|
|
22
|
+
"cmd": "echo \"{id} {state}\""
|
|
23
|
+
},
|
|
24
|
+
"three": {
|
|
25
|
+
"color": "#00ff00",
|
|
26
|
+
"image": "numbers/three_9278150.png",
|
|
27
|
+
"cmd": "echo \"{id} {state}\""
|
|
28
|
+
},
|
|
29
|
+
"four": {
|
|
30
|
+
"color": "#00ff00",
|
|
31
|
+
"image": "numbers/four_9278183.png",
|
|
32
|
+
"cmd": "echo \"{id} {state}\""
|
|
33
|
+
},
|
|
34
|
+
"five": {
|
|
35
|
+
"color": "#00ff00",
|
|
36
|
+
"image": "numbers/five_9278222.png",
|
|
37
|
+
"cmd": "echo \"{id} {state}\""
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"1": {
|
|
42
|
+
"default": "two",
|
|
43
|
+
"states": {
|
|
44
|
+
"off": {
|
|
45
|
+
"color": "#000099",
|
|
46
|
+
"cmd": "echo \"{id} {state}\""
|
|
47
|
+
},
|
|
48
|
+
"one": {
|
|
49
|
+
"color": "#00ff00",
|
|
50
|
+
"image": "numbers/one_9278045.png",
|
|
51
|
+
"cmd": "echo \"{id} {state}\""
|
|
52
|
+
},
|
|
53
|
+
"two": {
|
|
54
|
+
"color": "#00ff00",
|
|
55
|
+
"image": "numbers/two_9278103.png",
|
|
56
|
+
"cmd": "echo \"{id} {state}\""
|
|
57
|
+
},
|
|
58
|
+
"three": {
|
|
59
|
+
"color": "#00ff00",
|
|
60
|
+
"image": "numbers/three_9278150.png",
|
|
61
|
+
"cmd": "echo \"{id} {state}\""
|
|
62
|
+
},
|
|
63
|
+
"four": {
|
|
64
|
+
"color": "#00ff00",
|
|
65
|
+
"image": "numbers/four_9278183.png",
|
|
66
|
+
"cmd": "echo \"{id} {state}\""
|
|
67
|
+
},
|
|
68
|
+
"five": {
|
|
69
|
+
"color": "#00ff00",
|
|
70
|
+
"image": "numbers/five_9278222.png",
|
|
71
|
+
"cmd": "echo \"{id} {state}\""
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"2": {
|
|
76
|
+
"default": "three",
|
|
77
|
+
"states": {
|
|
78
|
+
"off": {
|
|
79
|
+
"color": "#000099",
|
|
80
|
+
"cmd": "echo \"{id} {state}\""
|
|
81
|
+
},
|
|
82
|
+
"one": {
|
|
83
|
+
"color": "#00ff00",
|
|
84
|
+
"image": "numbers/one_9278045.png",
|
|
85
|
+
"cmd": "echo \"{id} {state}\""
|
|
86
|
+
},
|
|
87
|
+
"two": {
|
|
88
|
+
"color": "#00ff00",
|
|
89
|
+
"image": "numbers/two_9278103.png",
|
|
90
|
+
"cmd": "echo \"{id} {state}\""
|
|
91
|
+
},
|
|
92
|
+
"three": {
|
|
93
|
+
"color": "#00ff00",
|
|
94
|
+
"image": "numbers/three_9278150.png",
|
|
95
|
+
"cmd": "echo \"{id} {state}\""
|
|
96
|
+
},
|
|
97
|
+
"four": {
|
|
98
|
+
"color": "#00ff00",
|
|
99
|
+
"image": "numbers/four_9278183.png",
|
|
100
|
+
"cmd": "echo \"{id} {state}\""
|
|
101
|
+
},
|
|
102
|
+
"five": {
|
|
103
|
+
"color": "#00ff00",
|
|
104
|
+
"image": "numbers/five_9278222.png",
|
|
105
|
+
"cmd": "echo \"{id} {state}\""
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"3": {
|
|
110
|
+
"default": "four",
|
|
111
|
+
"states": {
|
|
112
|
+
"off": {
|
|
113
|
+
"color": "#000099",
|
|
114
|
+
"cmd": "echo \"{id} {state}\""
|
|
115
|
+
},
|
|
116
|
+
"one": {
|
|
117
|
+
"color": "#00ff00",
|
|
118
|
+
"image": "numbers/one_9278045.png",
|
|
119
|
+
"cmd": "echo \"{id} {state}\""
|
|
120
|
+
},
|
|
121
|
+
"two": {
|
|
122
|
+
"color": "#00ff00",
|
|
123
|
+
"image": "numbers/two_9278103.png",
|
|
124
|
+
"cmd": "echo \"{id} {state}\""
|
|
125
|
+
},
|
|
126
|
+
"three": {
|
|
127
|
+
"color": "#00ff00",
|
|
128
|
+
"image": "numbers/three_9278150.png",
|
|
129
|
+
"cmd": "echo \"{id} {state}\""
|
|
130
|
+
},
|
|
131
|
+
"four": {
|
|
132
|
+
"color": "#00ff00",
|
|
133
|
+
"image": "numbers/four_9278183.png",
|
|
134
|
+
"cmd": "echo \"{id} {state}\""
|
|
135
|
+
},
|
|
136
|
+
"five": {
|
|
137
|
+
"color": "#00ff00",
|
|
138
|
+
"image": "numbers/five_9278222.png",
|
|
139
|
+
"cmd": "echo \"{id} {state}\""
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"4": {
|
|
144
|
+
"default": "five",
|
|
145
|
+
"states": {
|
|
146
|
+
"off": {
|
|
147
|
+
"color": "#000099",
|
|
148
|
+
"cmd": "echo \"{id} {state}\""
|
|
149
|
+
},
|
|
150
|
+
"one": {
|
|
151
|
+
"color": "#00ff00",
|
|
152
|
+
"image": "numbers/one_9278045.png",
|
|
153
|
+
"cmd": "echo \"{id} {state}\""
|
|
154
|
+
},
|
|
155
|
+
"two": {
|
|
156
|
+
"color": "#00ff00",
|
|
157
|
+
"image": "numbers/two_9278103.png",
|
|
158
|
+
"cmd": "echo \"{id} {state}\""
|
|
159
|
+
},
|
|
160
|
+
"three": {
|
|
161
|
+
"color": "#00ff00",
|
|
162
|
+
"image": "numbers/three_9278150.png",
|
|
163
|
+
"cmd": "echo \"{id} {state}\""
|
|
164
|
+
},
|
|
165
|
+
"four": {
|
|
166
|
+
"color": "#00ff00",
|
|
167
|
+
"image": "numbers/four_9278183.png",
|
|
168
|
+
"cmd": "echo \"{id} {state}\""
|
|
169
|
+
},
|
|
170
|
+
"five": {
|
|
171
|
+
"color": "#00ff00",
|
|
172
|
+
"image": "numbers/five_9278222.png",
|
|
173
|
+
"cmd": "echo \"{id} {state}\""
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
"5": {
|
|
178
|
+
"states": {
|
|
179
|
+
"off": {
|
|
180
|
+
"color": "#000099",
|
|
181
|
+
"cmd": "echo \"{id} {state}\""
|
|
182
|
+
},
|
|
183
|
+
"one": {
|
|
184
|
+
"color": "#00ff00",
|
|
185
|
+
"image": "numbers/one_9278045.png",
|
|
186
|
+
"cmd": "echo \"{id} {state}\""
|
|
187
|
+
},
|
|
188
|
+
"two": {
|
|
189
|
+
"color": "#00ff00",
|
|
190
|
+
"image": "numbers/two_9278103.png",
|
|
191
|
+
"cmd": "echo \"{id} {state}\""
|
|
192
|
+
},
|
|
193
|
+
"three": {
|
|
194
|
+
"color": "#00ff00",
|
|
195
|
+
"image": "numbers/three_9278150.png",
|
|
196
|
+
"cmd": "echo \"{id} {state}\""
|
|
197
|
+
},
|
|
198
|
+
"four": {
|
|
199
|
+
"color": "#00ff00",
|
|
200
|
+
"image": "numbers/four_9278183.png",
|
|
201
|
+
"cmd": "echo \"{id} {state}\""
|
|
202
|
+
},
|
|
203
|
+
"five": {
|
|
204
|
+
"color": "#00ff00",
|
|
205
|
+
"image": "numbers/five_9278222.png",
|
|
206
|
+
"cmd": "echo \"{id} {state}\""
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"left": {
|
|
212
|
+
"0": {
|
|
213
|
+
"states": {
|
|
214
|
+
"on": {
|
|
215
|
+
"color": "#000000",
|
|
216
|
+
"cmd": "echo \"{id} {state}\""
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"right": {
|
|
222
|
+
"0": {
|
|
223
|
+
"states": {
|
|
224
|
+
"on": {
|
|
225
|
+
"color": "#000000",
|
|
226
|
+
"cmd": "echo \"{id} {state}\""
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
"knobs": {
|
|
233
|
+
"knobTL": {
|
|
234
|
+
"states": {
|
|
235
|
+
"on": {
|
|
236
|
+
"cmd": "echo \"{id} {state}\""
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"group": ""
|
|
240
|
+
},
|
|
241
|
+
"knobCL": {
|
|
242
|
+
"states": {
|
|
243
|
+
"on": {
|
|
244
|
+
"cmd": "echo \"{id} {state}\""
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
"group": ""
|
|
248
|
+
},
|
|
249
|
+
"knobBL": {
|
|
250
|
+
"states": {
|
|
251
|
+
"on": {
|
|
252
|
+
"cmd": "echo \"{id} {state}\"",
|
|
253
|
+
"opcua": "ns=2;s=Is{simnbr}.Audio.in.VolumeAccustic"
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
"group": ""
|
|
257
|
+
},
|
|
258
|
+
"knobTR": {
|
|
259
|
+
"states": {
|
|
260
|
+
"on": {
|
|
261
|
+
"cmd": "echo \"{id} {state}\""
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"group": ""
|
|
265
|
+
},
|
|
266
|
+
"knobCR": {
|
|
267
|
+
"states": {
|
|
268
|
+
"on": {
|
|
269
|
+
"cmd": "echo \"{id} {state}\""
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"group": ""
|
|
273
|
+
},
|
|
274
|
+
"knobBR": {
|
|
275
|
+
"states": {
|
|
276
|
+
"on": {
|
|
277
|
+
"cmd": "echo \"{id} {state}\""
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
"group": ""
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"parameters": {
|
|
284
|
+
"hostname": "127.0.0.1",
|
|
285
|
+
"simnbr": "1",
|
|
286
|
+
"endpointurl": "opc.tcp://{hostname}:4840",
|
|
287
|
+
"nodeid" : "ns=0;s=nodeID",
|
|
288
|
+
"verbose": true
|
|
289
|
+
}
|
|
290
|
+
}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "profile-1",
|
|
3
|
+
"profile": "example",
|
|
4
|
+
"description": "",
|
|
5
|
+
"touch": {
|
|
6
|
+
"center": {
|
|
7
|
+
"0": {
|
|
8
|
+
"states": {
|
|
9
|
+
"off": {
|
|
10
|
+
"color": "#000099",
|
|
11
|
+
"image": "icons/home.png",
|
|
12
|
+
"cmd": "echo \"{id} {state}\""
|
|
13
|
+
},
|
|
14
|
+
"on": {
|
|
15
|
+
"color": "#00ff00",
|
|
16
|
+
"image": "icons/home.png",
|
|
17
|
+
"cmd": "echo \"{id} {state}\""
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"group": ""
|
|
21
|
+
},
|
|
22
|
+
"1": {
|
|
23
|
+
"states": {
|
|
24
|
+
"off": {
|
|
25
|
+
"color": "#000099",
|
|
26
|
+
"image": "icons/home.png",
|
|
27
|
+
"cmd": "echo \"{id} {state}\""
|
|
28
|
+
},
|
|
29
|
+
"on": {
|
|
30
|
+
"color": "#00ff00",
|
|
31
|
+
"image": "icons/home.png",
|
|
32
|
+
"cmd": "echo \"{id} {state}\""
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"group": ""
|
|
36
|
+
},
|
|
37
|
+
"2": {
|
|
38
|
+
"states": {
|
|
39
|
+
"off": {
|
|
40
|
+
"color": "#000099",
|
|
41
|
+
"image": "icons/home.png",
|
|
42
|
+
"cmd": "echo \"{id} {state}\""
|
|
43
|
+
},
|
|
44
|
+
"on": {
|
|
45
|
+
"color": "#00ff00",
|
|
46
|
+
"image": "icons/home.png",
|
|
47
|
+
"cmd": "echo \"{id} {state}\""
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"group": ""
|
|
51
|
+
},
|
|
52
|
+
"3": {
|
|
53
|
+
"states": {
|
|
54
|
+
"off": {
|
|
55
|
+
"color": "#000099",
|
|
56
|
+
"image": "icons/home.png",
|
|
57
|
+
"cmd": "echo \"{id} {state}\""
|
|
58
|
+
},
|
|
59
|
+
"on": {
|
|
60
|
+
"color": "#00ff00",
|
|
61
|
+
"image": "icons/home.png",
|
|
62
|
+
"cmd": "echo \"{id} {state}\""
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"group": ""
|
|
66
|
+
},
|
|
67
|
+
"4": {
|
|
68
|
+
"states": {
|
|
69
|
+
"off": {
|
|
70
|
+
"color": "#000099",
|
|
71
|
+
"image": "icons/home.png",
|
|
72
|
+
"cmd": "echo \"{id} {state}\""
|
|
73
|
+
},
|
|
74
|
+
"on": {
|
|
75
|
+
"color": "#00ff00",
|
|
76
|
+
"image": "icons/home.png",
|
|
77
|
+
"cmd": "echo \"{id} {state}\""
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"group": ""
|
|
81
|
+
},
|
|
82
|
+
"5": {
|
|
83
|
+
"states": {
|
|
84
|
+
"off": {
|
|
85
|
+
"color": "#000099",
|
|
86
|
+
"image": "icons/home.png",
|
|
87
|
+
"cmd": "echo \"{id} {state}\""
|
|
88
|
+
},
|
|
89
|
+
"on": {
|
|
90
|
+
"color": "#00ff00",
|
|
91
|
+
"image": "icons/home.png",
|
|
92
|
+
"cmd": "echo \"{id} {state}\""
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"group": ""
|
|
96
|
+
},
|
|
97
|
+
"6": {
|
|
98
|
+
"states": {
|
|
99
|
+
"off": {
|
|
100
|
+
"color": "#000099",
|
|
101
|
+
"image": "icons/home.png",
|
|
102
|
+
"cmd": "echo \"{id} {state}\""
|
|
103
|
+
},
|
|
104
|
+
"on": {
|
|
105
|
+
"color": "#00ff00",
|
|
106
|
+
"image": "icons/home.png",
|
|
107
|
+
"cmd": "echo \"{id} {state}\""
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"group": ""
|
|
111
|
+
},
|
|
112
|
+
"7": {
|
|
113
|
+
"states": {
|
|
114
|
+
"off": {
|
|
115
|
+
"color": "#000099",
|
|
116
|
+
"image": "icons/home.png",
|
|
117
|
+
"cmd": "echo \"{id} {state}\""
|
|
118
|
+
},
|
|
119
|
+
"on": {
|
|
120
|
+
"color": "#00ff00",
|
|
121
|
+
"image": "icons/home.png",
|
|
122
|
+
"cmd": "echo \"{id} {state}\""
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"group": ""
|
|
126
|
+
},
|
|
127
|
+
"8": {
|
|
128
|
+
"states": {
|
|
129
|
+
"off": {
|
|
130
|
+
"color": "#000099",
|
|
131
|
+
"image": "icons/home.png",
|
|
132
|
+
"cmd": "echo \"{id} {state}\""
|
|
133
|
+
},
|
|
134
|
+
"on": {
|
|
135
|
+
"color": "#00ff00",
|
|
136
|
+
"image": "icons/home.png",
|
|
137
|
+
"cmd": "echo \"{id} {state}\""
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"group": ""
|
|
141
|
+
},
|
|
142
|
+
"9": {
|
|
143
|
+
"states": {
|
|
144
|
+
"off": {
|
|
145
|
+
"color": "#000099",
|
|
146
|
+
"image": "icons/home.png",
|
|
147
|
+
"cmd": "echo \"{id} {state}\""
|
|
148
|
+
},
|
|
149
|
+
"on": {
|
|
150
|
+
"color": "#00ff00",
|
|
151
|
+
"image": "icons/home.png",
|
|
152
|
+
"cmd": "echo \"{id} {state}\""
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"group": ""
|
|
156
|
+
},
|
|
157
|
+
"10": {
|
|
158
|
+
"states": {
|
|
159
|
+
"off": {
|
|
160
|
+
"color": "#000099",
|
|
161
|
+
"image": "icons/home.png",
|
|
162
|
+
"cmd": "echo \"{id} {state}\""
|
|
163
|
+
},
|
|
164
|
+
"on": {
|
|
165
|
+
"color": "#00ff00",
|
|
166
|
+
"image": "icons/home.png",
|
|
167
|
+
"cmd": "echo \"{id} {state}\""
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"group": ""
|
|
171
|
+
},
|
|
172
|
+
"11": {
|
|
173
|
+
"states": {
|
|
174
|
+
"off": {
|
|
175
|
+
"color": "#000099",
|
|
176
|
+
"image": "icons/home.png",
|
|
177
|
+
"cmd": "echo \"{id} {state}\""
|
|
178
|
+
},
|
|
179
|
+
"on": {
|
|
180
|
+
"color": "#00ff00",
|
|
181
|
+
"image": "icons/home.png",
|
|
182
|
+
"cmd": "echo \"{id} {state}\""
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"group": ""
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"left": {
|
|
189
|
+
"0": {
|
|
190
|
+
"states": {
|
|
191
|
+
"on": {
|
|
192
|
+
"color": "#000000",
|
|
193
|
+
"cmd": "echo \"{id} {state}\""
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"group": ""
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"right": {
|
|
200
|
+
"0": {
|
|
201
|
+
"states": {
|
|
202
|
+
"on": {
|
|
203
|
+
"color": "#000000",
|
|
204
|
+
"cmd": "echo \"{id} {state}\""
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"group": ""
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"knobs": {
|
|
212
|
+
"knobTL": {
|
|
213
|
+
"states": {
|
|
214
|
+
"on": {
|
|
215
|
+
"cmd": "echo \"{id} {state}\""
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"group": ""
|
|
219
|
+
},
|
|
220
|
+
"knobCL": {
|
|
221
|
+
"states": {
|
|
222
|
+
"on": {
|
|
223
|
+
"cmd": "echo \"{id} {state}\""
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"group": ""
|
|
227
|
+
},
|
|
228
|
+
"knobBL": {
|
|
229
|
+
"states": {
|
|
230
|
+
"on": {
|
|
231
|
+
"cmd": "echo \"{id} {state}\""
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"group": ""
|
|
235
|
+
},
|
|
236
|
+
"knobTR": {
|
|
237
|
+
"states": {
|
|
238
|
+
"on": {
|
|
239
|
+
"cmd": "echo \"{id} {state}\""
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
"group": ""
|
|
243
|
+
},
|
|
244
|
+
"knobCR": {
|
|
245
|
+
"states": {
|
|
246
|
+
"on": {
|
|
247
|
+
"cmd": "echo \"{id} {state}\""
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"group": ""
|
|
251
|
+
},
|
|
252
|
+
"knobBR": {
|
|
253
|
+
"states": {
|
|
254
|
+
"on": {
|
|
255
|
+
"cmd": "echo \"{id} {state}\""
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
"group": ""
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
"buttons": {
|
|
262
|
+
"0": {
|
|
263
|
+
"states": {
|
|
264
|
+
"off": {
|
|
265
|
+
"color": "#000000",
|
|
266
|
+
"cmd": "echo \"{id} {state}\""
|
|
267
|
+
},
|
|
268
|
+
"on": {
|
|
269
|
+
"color": "#550000",
|
|
270
|
+
"cmd": "echo \"{id} {state}\""
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"group": ""
|
|
274
|
+
},
|
|
275
|
+
"1": {
|
|
276
|
+
"states": {
|
|
277
|
+
"off": {
|
|
278
|
+
"color": "#000000",
|
|
279
|
+
"cmd": "echo \"{id} {state}\""
|
|
280
|
+
},
|
|
281
|
+
"on": {
|
|
282
|
+
"color": "#ff0000",
|
|
283
|
+
"cmd": "echo \"{id} {state}\""
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"group": ""
|
|
287
|
+
},
|
|
288
|
+
"2": {
|
|
289
|
+
"states": {
|
|
290
|
+
"off": {
|
|
291
|
+
"color": "#000000",
|
|
292
|
+
"cmd": "echo \"{id} {state}\""
|
|
293
|
+
},
|
|
294
|
+
"on": {
|
|
295
|
+
"color": "#005500",
|
|
296
|
+
"cmd": "echo \"{id} {state}\""
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
"group": ""
|
|
300
|
+
},
|
|
301
|
+
"3": {
|
|
302
|
+
"states": {
|
|
303
|
+
"off": {
|
|
304
|
+
"color": "#000000",
|
|
305
|
+
"cmd": "echo \"{id} {state}\""
|
|
306
|
+
},
|
|
307
|
+
"on": {
|
|
308
|
+
"color": "#00ff00",
|
|
309
|
+
"cmd": "echo \"{id} {state}\""
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
"group": ""
|
|
313
|
+
},
|
|
314
|
+
"4": {
|
|
315
|
+
"states": {
|
|
316
|
+
"off": {
|
|
317
|
+
"color": "#000000",
|
|
318
|
+
"cmd": "echo \"{id} {state}\""
|
|
319
|
+
},
|
|
320
|
+
"on": {
|
|
321
|
+
"color": "#000055",
|
|
322
|
+
"cmd": "echo \"{id} {state}\""
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"group": ""
|
|
326
|
+
},
|
|
327
|
+
"5": {
|
|
328
|
+
"states": {
|
|
329
|
+
"off": {
|
|
330
|
+
"color": "#000000",
|
|
331
|
+
"cmd": "echo \"{id} {state}\""
|
|
332
|
+
},
|
|
333
|
+
"on": {
|
|
334
|
+
"color": "#0000ff",
|
|
335
|
+
"cmd": "echo \"{id} {state}\""
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
"group": ""
|
|
339
|
+
},
|
|
340
|
+
"6": {
|
|
341
|
+
"states": {
|
|
342
|
+
"off": {
|
|
343
|
+
"color": "#000000",
|
|
344
|
+
"cmd": "echo \"{id} {state}\""
|
|
345
|
+
},
|
|
346
|
+
"on": {
|
|
347
|
+
"color": "#555500",
|
|
348
|
+
"cmd": "echo \"{id} {state}\""
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
"group": ""
|
|
352
|
+
},
|
|
353
|
+
"7": {
|
|
354
|
+
"states": {
|
|
355
|
+
"off": {
|
|
356
|
+
"color": "#000000",
|
|
357
|
+
"cmd": "echo \"{id} {state}\""
|
|
358
|
+
},
|
|
359
|
+
"on": {
|
|
360
|
+
"color": "#ffff00",
|
|
361
|
+
"cmd": "echo \"{id} {state}\""
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
"group": ""
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
"parameters": {
|
|
368
|
+
"hostname": "127.0.0.1",
|
|
369
|
+
"endpointurl": "opc.tcp://{hostname}:4840",
|
|
370
|
+
"nodeid": "ns=0;s=nodeID"
|
|
371
|
+
},
|
|
372
|
+
"loaded": false
|
|
373
|
+
}
|