loupedeck-commander 1.2.2 → 1.2.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.
- package/common/BaseLoupeDeckHandler.mjs +18 -5
- package/common/touchbuttons.mjs +21 -8
- package/interfaces/baseif.mjs +2 -1
- package/interfaces/opcuaif.mjs +28 -19
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {discover, HAPTIC,LoupedeckDevice } from 'loupedeck'
|
|
2
2
|
import { ApplicationConfig } from './ApplicationConfig.mjs'
|
|
3
|
-
import { ButtonField, StopInterfaces, InitializeInterfaces,opcuainterface} from './touchbuttons.mjs'
|
|
3
|
+
import { ButtonField, StopInterfaces, InitializeInterfaces,opcuainterface,profileEmitter} from './touchbuttons.mjs'
|
|
4
4
|
|
|
5
5
|
export class BaseLoupeDeckHandler {
|
|
6
6
|
device = undefined
|
|
@@ -118,19 +118,20 @@ export class BaseLoupeDeckHandler {
|
|
|
118
118
|
*/
|
|
119
119
|
async activateProfile (id) {
|
|
120
120
|
// todo Profile-change implementation
|
|
121
|
+
id = Number(id)
|
|
121
122
|
var oldProfile = this.currentProfile
|
|
122
|
-
if (this.appConfig.profiles.length
|
|
123
|
+
if (this.appConfig.profiles.length > id) {
|
|
123
124
|
this.currentProfile = id
|
|
124
125
|
}else{
|
|
125
126
|
return
|
|
126
127
|
}
|
|
127
|
-
|
|
128
|
+
const profile = this.getCurrentProfile()
|
|
129
|
+
console.info("ACTIVATE PROFILE",id,profile.name)
|
|
128
130
|
const dLeft = this.device.displays.left
|
|
129
131
|
const dRight = this.device.displays.right
|
|
130
132
|
const dCenter = this.device.displays.center
|
|
131
133
|
const dKnob = this.device.displays.knob
|
|
132
134
|
|
|
133
|
-
const profile = this.getCurrentProfile()
|
|
134
135
|
this.screens.center = new ButtonField('center', this.device.rows, this.device.columns, dCenter.width, dCenter.height, profile.touch.center,profile)
|
|
135
136
|
this.screens.left = new ButtonField('left', 1, 1, dLeft.width, dLeft.height, profile.touch.left,profile)
|
|
136
137
|
this.screens.right = new ButtonField('right', 1, 1, dRight.width, dRight.height, profile.touch.right,profile)
|
|
@@ -158,6 +159,7 @@ export class BaseLoupeDeckHandler {
|
|
|
158
159
|
this.buttons.setState(oldProfile+1,1)
|
|
159
160
|
|
|
160
161
|
await this.buttons.draw(this.device)
|
|
162
|
+
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
/**
|
|
@@ -183,11 +185,20 @@ export class BaseLoupeDeckHandler {
|
|
|
183
185
|
const self = this
|
|
184
186
|
|
|
185
187
|
// Register callback on monitored item change:
|
|
186
|
-
opcuainterface.
|
|
188
|
+
opcuainterface.on("monitored item changed",(buttonID,nodeid,val) => { self.buttonStateChanged(buttonID,nodeid,val) })
|
|
189
|
+
profileEmitter.on("profileChanged",(profileID) => { self.activateProfile(profileID) })
|
|
190
|
+
|
|
187
191
|
|
|
188
192
|
this.device.setBrightness(1)
|
|
189
193
|
this.device.vibrate(HAPTIC.ASCEND_MED)
|
|
190
194
|
|
|
195
|
+
// Fore update of all screens
|
|
196
|
+
console.info('✅ Force Screen update')
|
|
197
|
+
this.screenUpdate["center"] = true
|
|
198
|
+
this.screenUpdate["left"] = true
|
|
199
|
+
this.screenUpdate["right"] = true
|
|
200
|
+
await this.updateScreens()
|
|
201
|
+
|
|
191
202
|
console.info('✅ Done initializing')
|
|
192
203
|
}
|
|
193
204
|
|
|
@@ -302,6 +313,8 @@ export class BaseLoupeDeckHandler {
|
|
|
302
313
|
async buttonStateChanged(buttonID,nodeid,val) {
|
|
303
314
|
let ok = false
|
|
304
315
|
this.screenUpdate["center"] = true
|
|
316
|
+
this.screenUpdate["left"] = true
|
|
317
|
+
this.screenUpdate["right"] = true
|
|
305
318
|
|
|
306
319
|
ok = await this.screens.center.changed(buttonID,nodeid,val)
|
|
307
320
|
|
package/common/touchbuttons.mjs
CHANGED
|
@@ -6,11 +6,13 @@ import * as httpif from '../interfaces/httpif.mjs'
|
|
|
6
6
|
import * as opcuaif from '../interfaces/opcuaif.mjs'
|
|
7
7
|
import format from 'string-template'
|
|
8
8
|
import { calcDelta } from './utils.mjs'
|
|
9
|
+
import { EventEmitter } from 'node:events'
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
export var opcuainterface = undefined
|
|
11
13
|
var httpinterface = undefined
|
|
12
14
|
var shellinterface = undefined
|
|
13
|
-
|
|
15
|
+
export var profileEmitter = undefined
|
|
14
16
|
export async function InitializeInterfaces(appConfig,callbackFunction){
|
|
15
17
|
if (opcuainterface === undefined ){
|
|
16
18
|
opcuainterface = new opcuaif.OPCUAIf()
|
|
@@ -21,6 +23,7 @@ export async function InitializeInterfaces(appConfig,callbackFunction){
|
|
|
21
23
|
if (shellinterface === undefined)
|
|
22
24
|
shellinterface = new shellif.SHELLif()
|
|
23
25
|
|
|
26
|
+
profileEmitter = new EventEmitter()
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export async function StopInterfaces(){
|
|
@@ -85,10 +88,7 @@ export class ButtonField {
|
|
|
85
88
|
this.#config = config
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
// this.#config = config
|
|
90
|
-
// }
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
async draw (device) {
|
|
93
93
|
if (!this.#screen) {
|
|
94
94
|
// physical buttons:
|
|
@@ -470,14 +470,24 @@ export class Button {
|
|
|
470
470
|
|
|
471
471
|
async runCommand () {
|
|
472
472
|
const elem = this.getCurrentElement()
|
|
473
|
-
// Only continue, if we have an element
|
|
474
|
-
if (!elem
|
|
473
|
+
// Only continue, if we have an element:
|
|
474
|
+
if (!elem) {
|
|
475
475
|
return
|
|
476
476
|
}
|
|
477
477
|
// Filter for Event Type:
|
|
478
478
|
if (elem.filter && elem.filter != this.#event){
|
|
479
479
|
return
|
|
480
480
|
}
|
|
481
|
+
|
|
482
|
+
if (elem.profile){
|
|
483
|
+
profileEmitter.emit("profileChanged", elem.profile)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Only continue, if we have an element, that contains some kind of command:
|
|
487
|
+
if (!elem.cmd && !elem.http && !elem.opcua) {
|
|
488
|
+
return
|
|
489
|
+
}
|
|
490
|
+
|
|
481
491
|
// Call an action - include dynamic parameters
|
|
482
492
|
// and also all attributes of elem + global config
|
|
483
493
|
const params = {
|
|
@@ -490,9 +500,12 @@ export class Button {
|
|
|
490
500
|
state: this.#keys[this.#index],
|
|
491
501
|
min: this.#min,
|
|
492
502
|
max: this.#max,
|
|
493
|
-
value: this.#value
|
|
494
503
|
}
|
|
495
504
|
|
|
505
|
+
if (!params.value)
|
|
506
|
+
params.value = this.#value
|
|
507
|
+
|
|
508
|
+
|
|
496
509
|
let res = ''
|
|
497
510
|
if ('cmd' in elem) {
|
|
498
511
|
if (shellinterface){
|
package/interfaces/baseif.mjs
CHANGED
package/interfaces/opcuaif.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
coerceByteString,
|
|
13
13
|
DataType
|
|
14
14
|
} from "node-opcua";
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
import { BaseIf } from './baseif.mjs'
|
|
17
17
|
|
|
18
18
|
const subscriptionParameters = {
|
|
@@ -37,10 +37,8 @@ export class OPCUAIf extends BaseIf {
|
|
|
37
37
|
monitoreditems
|
|
38
38
|
buttons
|
|
39
39
|
#callback
|
|
40
|
-
myEmitter
|
|
41
40
|
constructor() {
|
|
42
41
|
super()
|
|
43
|
-
this.myEmitter = new EventEmitter();
|
|
44
42
|
|
|
45
43
|
this.LogInfo(`OPCUAIf Constructed`);
|
|
46
44
|
}
|
|
@@ -98,7 +96,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
98
96
|
var nodeId = super.formatString(opcuaNode, options)
|
|
99
97
|
var value = super.formatString(options.value, options)
|
|
100
98
|
|
|
101
|
-
this.LogInfo(`OPCUAIf: write ${nodeId} => ${value}\n`)
|
|
99
|
+
//this.LogInfo(`OPCUAIf: write ${nodeId} => ${value}\n`)
|
|
102
100
|
await this.Write(nodeId,value)
|
|
103
101
|
|
|
104
102
|
var NewState = "waiting"
|
|
@@ -147,29 +145,29 @@ export class OPCUAIf extends BaseIf {
|
|
|
147
145
|
|
|
148
146
|
this.#client.on("backoff", (retry, delay) => {
|
|
149
147
|
if((retry%10) == 0)
|
|
150
|
-
|
|
148
|
+
self.LogInfo(`OPCUAIf Try Reconnection ${retry} next attempt in ${delay}ms ${self.#endpointurl}\n`);
|
|
151
149
|
});
|
|
152
150
|
|
|
153
151
|
this.#client.on("connection_lost", () => {
|
|
154
|
-
|
|
152
|
+
self.LogInfo(`OPCUAIf: Connection lost\n`);
|
|
155
153
|
});
|
|
156
154
|
|
|
157
155
|
this.#client.on("connection_reestablished", () => {
|
|
158
|
-
|
|
156
|
+
self.LogInfo(`OPCUAIf: Connection re-established\n`);
|
|
159
157
|
});
|
|
160
158
|
|
|
161
159
|
this.#client.on("connection_failed", () => {
|
|
162
|
-
|
|
160
|
+
self.LogInfo(`OPCUAIf: Connection failed\n`);
|
|
163
161
|
});
|
|
164
162
|
this.#client.on("start_reconnection", () => {
|
|
165
|
-
|
|
163
|
+
self.LogInfo(`OPCUAIf: Starting reconnection\n`);
|
|
166
164
|
});
|
|
167
165
|
|
|
168
166
|
this.#client.on("after_reconnection", (err) => {
|
|
169
|
-
|
|
167
|
+
self.LogInfo(`OPCUAIf: After Reconnection event => ${err}\n`);
|
|
170
168
|
});
|
|
171
169
|
this.#client.on("security_token_renewed", () => {
|
|
172
|
-
|
|
170
|
+
self.LogDebug(`OPCUAIf: security_token_renewed\n`);
|
|
173
171
|
})
|
|
174
172
|
this.#client.on("lifetime_75", (token) => {})
|
|
175
173
|
|
|
@@ -179,16 +177,16 @@ export class OPCUAIf extends BaseIf {
|
|
|
179
177
|
this.#session = await this.#client.createSession();
|
|
180
178
|
|
|
181
179
|
this.#session.on("session_closed", (statusCode) => {
|
|
182
|
-
|
|
180
|
+
self.LogInfo(`OPCUAIf: Session has been closed\n`);
|
|
183
181
|
})
|
|
184
182
|
this.#session.on("session_restored", () => {
|
|
185
|
-
|
|
183
|
+
self.LogInfo(`OPCUAIf: Session has been restored\n`);
|
|
186
184
|
});
|
|
187
185
|
this.#session.on("keepalive", (lastKnownServerState) => {
|
|
188
|
-
|
|
186
|
+
self.LogInfo(`OPCUAIf: KeepAlive lastKnownServerState ${lastKnownServerState}\n`);
|
|
189
187
|
});
|
|
190
188
|
this.#session.on("keepalive_failure", () => {
|
|
191
|
-
|
|
189
|
+
self.LogInfo(`OPCUAIf: KeepAlive failure\n`);
|
|
192
190
|
});
|
|
193
191
|
|
|
194
192
|
this.#sub = await this.#session.createSubscription2({
|
|
@@ -208,6 +206,17 @@ export class OPCUAIf extends BaseIf {
|
|
|
208
206
|
|
|
209
207
|
async Subscribe(nodeID) {
|
|
210
208
|
// install monitored item
|
|
209
|
+
|
|
210
|
+
const keys = Object.keys(this.monitoreditems)
|
|
211
|
+
for (let i = 0; i < keys.length; i++) {
|
|
212
|
+
const key = keys[i]
|
|
213
|
+
const elem = this.monitoreditems[key]
|
|
214
|
+
if (elem == nodeID){
|
|
215
|
+
// already registered => return itemid
|
|
216
|
+
return key
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
211
220
|
const itemToMonitor = {
|
|
212
221
|
nodeId: resolveNodeId(nodeID),
|
|
213
222
|
attributeId: AttributeIds.Value
|
|
@@ -228,8 +237,8 @@ export class OPCUAIf extends BaseIf {
|
|
|
228
237
|
monitoredItem.on("changed", function (dataValue) {
|
|
229
238
|
var nodeId = self.monitoreditems[this.monitoredItemId]
|
|
230
239
|
var buttonID = self.buttons[this.monitoredItemId]
|
|
231
|
-
|
|
232
|
-
self.
|
|
240
|
+
self.LogInfo(`OPCUAIf: monitored item changed: ${nodeId} => ${dataValue.value.value}\n`);
|
|
241
|
+
self.emit('monitored item changed',buttonID,nodeId, dataValue.value.value)
|
|
233
242
|
});
|
|
234
243
|
|
|
235
244
|
return monitoredItem.monitoredItemId;
|
|
@@ -269,9 +278,9 @@ export class OPCUAIf extends BaseIf {
|
|
|
269
278
|
await this.#session.write(nodesToWrite, function(err,statusCodes) {
|
|
270
279
|
if (!err) {
|
|
271
280
|
if (statusCodes && statusCodes[0].value != 0){
|
|
272
|
-
self.LogInfo(`OPCUAIf: status $statusCodes\n`);
|
|
281
|
+
self.LogInfo(`OPCUAIf: status ${statusCodes}\n`);
|
|
273
282
|
}else{
|
|
274
|
-
self.LogInfo(`OPCUAIf: wrote $nodeID => $value\n`);
|
|
283
|
+
self.LogInfo(`OPCUAIf: wrote ${nodeID} => ${value}\n`);
|
|
275
284
|
}
|
|
276
285
|
}else{
|
|
277
286
|
self.LogError("OPCUAIf: write NOT ok",nodeID, value,"\n");
|