loupedeck-commander 1.5.0 → 1.5.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/common/ApplicationConfig.mjs +0 -0
- package/common/button.mjs +7 -14
- package/common/logger.mjs +19 -0
- package/common/main.cjs +1 -0
- package/interfaces/baseif.mjs +3 -6
- package/interfaces/opcuaif.mjs +42 -41
- package/package.json +3 -3
|
File without changes
|
package/common/button.mjs
CHANGED
|
@@ -40,12 +40,7 @@ export class Button {
|
|
|
40
40
|
this.#keys = []
|
|
41
41
|
|
|
42
42
|
this.id = id
|
|
43
|
-
|
|
44
|
-
//this.#enforcedIndex = -1
|
|
45
|
-
//this.#enforcedBlink = false
|
|
46
|
-
|
|
47
|
-
// console.info(` Button ${id.padEnd(10, ' ')} Size: ${width} x ${height}`)
|
|
48
|
-
|
|
43
|
+
|
|
49
44
|
this.#profile = profile
|
|
50
45
|
this.#params = {
|
|
51
46
|
"key": key,
|
|
@@ -338,7 +333,7 @@ export class Button {
|
|
|
338
333
|
this.#index++
|
|
339
334
|
|
|
340
335
|
if (this.#enforcedIndex >= 0 && this.#index != this.#enforcedIndex) {
|
|
341
|
-
console.log(
|
|
336
|
+
console.log(`${this.id}: Enforced Index Change from ${this.#index} -> ${this.#enforcedIndex}`)
|
|
342
337
|
this.#index = this.#enforcedIndex
|
|
343
338
|
}
|
|
344
339
|
|
|
@@ -382,7 +377,7 @@ export class Button {
|
|
|
382
377
|
|
|
383
378
|
if (this.#enforcedIndex >= 0 && this.#enforcedIndex != this.#index) {
|
|
384
379
|
// If we have an enforced index, we set it to the enforced index:
|
|
385
|
-
console.log(
|
|
380
|
+
console.log(`${this.id}: Enforced Index Change from ${this.#index} -> ${this.#enforcedIndex}`)
|
|
386
381
|
this.#index = this.#enforcedIndex
|
|
387
382
|
}
|
|
388
383
|
|
|
@@ -437,10 +432,10 @@ export class Button {
|
|
|
437
432
|
let valStr = val.toString()
|
|
438
433
|
// check if the state-name is same as the value we get from outside:
|
|
439
434
|
if (valStr == stateStr) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
435
|
+
if (i !== this.#index) {
|
|
436
|
+
console.log(`${this.id} - enforced Index change from ${this.#index} -> ${this.#enforcedIndex} (State Changed) in ${nodeid}`)
|
|
437
|
+
this.#enforcedIndex = i;
|
|
438
|
+
}
|
|
444
439
|
break;
|
|
445
440
|
}
|
|
446
441
|
}
|
|
@@ -448,8 +443,6 @@ export class Button {
|
|
|
448
443
|
this.#index = this.#enforcedIndex;
|
|
449
444
|
this.inversed = false
|
|
450
445
|
this.pressActive = false
|
|
451
|
-
//console.info("enforce State index", this.id, nodeid, val, i)
|
|
452
|
-
//this.#enforcedIndex = this.#index;
|
|
453
446
|
}
|
|
454
447
|
|
|
455
448
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// logger.js
|
|
2
|
+
const originalLog = console.log;
|
|
3
|
+
const originalInfo = console.info;
|
|
4
|
+
const originalError = console.error;
|
|
5
|
+
|
|
6
|
+
console.log = (...args) => {
|
|
7
|
+
const timestamp = new Date().toISOString(); // Format: 2026-05-18T14:55:00.000Z
|
|
8
|
+
originalLog(`${timestamp} [INF]`, ...args);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
console.info = (...args) => {
|
|
12
|
+
const timestamp = new Date().toISOString(); // Format: 2026-05-18T14:55:00.000Z
|
|
13
|
+
originalInfo(`${timestamp} [INF]`, ...args);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
console.error = (...args) => {
|
|
17
|
+
const timestamp = new Date().toISOString(); // Format: 2026-05-18T14:55:00.000Z
|
|
18
|
+
originalError(`${timestamp} [ERR]`, ...args);
|
|
19
|
+
};
|
package/common/main.cjs
CHANGED
package/interfaces/baseif.mjs
CHANGED
|
@@ -51,20 +51,17 @@ export class BaseIf extends EventEmitter {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
LogError(...args){
|
|
54
|
-
|
|
55
|
-
process.stderr.write(str.toString())
|
|
54
|
+
console.error(...args)
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
LogDebug(...args){
|
|
59
58
|
if (this.options && this.options.verbose){
|
|
60
|
-
|
|
61
|
-
process.stdout.write(str.toString())
|
|
59
|
+
console.log(...args)
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
LogInfo(...args){
|
|
66
|
-
|
|
67
|
-
process.stdout.write(str.toString())
|
|
64
|
+
console.info(...args)
|
|
68
65
|
}
|
|
69
66
|
}
|
|
70
67
|
|
package/interfaces/opcuaif.mjs
CHANGED
|
@@ -40,7 +40,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
40
40
|
async init(options = {}, config = {}) {
|
|
41
41
|
var res = this.Check(options)
|
|
42
42
|
if (res < 0) {
|
|
43
|
-
this.LogError(`OPCUAIf: Missing essential options in dictionary => Quitting $res $options
|
|
43
|
+
this.LogError(`OPCUAIf: Missing essential options in dictionary => Quitting $res $options`)
|
|
44
44
|
}
|
|
45
45
|
try {
|
|
46
46
|
this.#endpointurl = this.formatString(options.endpointurl, options)
|
|
@@ -48,19 +48,19 @@ export class OPCUAIf extends BaseIf {
|
|
|
48
48
|
this.#publishingInterval = options.publishingInterval
|
|
49
49
|
else {
|
|
50
50
|
this.#publishingInterval = 250;
|
|
51
|
-
this.LogInfo(`OPCUAIf init using default publishingInterval: ${this.#publishingInterval}ms
|
|
51
|
+
this.LogInfo(`OPCUAIf init using default publishingInterval: ${this.#publishingInterval}ms`);
|
|
52
52
|
}
|
|
53
53
|
if (options.samplingInterval)
|
|
54
54
|
this.#samplingInterval = options.samplingInterval
|
|
55
55
|
else {
|
|
56
56
|
this.#samplingInterval = 100;
|
|
57
|
-
this.LogInfo(`OPCUAIf init using default samplingInterval: ${this.#samplingInterval}ms
|
|
57
|
+
this.LogInfo(`OPCUAIf init using default samplingInterval: ${this.#samplingInterval}ms`);
|
|
58
58
|
}
|
|
59
59
|
this.options = options
|
|
60
60
|
this.monitoreditems = {}
|
|
61
61
|
this.types = {}
|
|
62
62
|
this.buttons = {}
|
|
63
|
-
this.LogInfo(`OPCUAIf init ${this.#endpointurl}
|
|
63
|
+
this.LogInfo(`OPCUAIf init ${this.#endpointurl}`);
|
|
64
64
|
|
|
65
65
|
await this.Connect(this.#endpointurl);
|
|
66
66
|
|
|
@@ -131,7 +131,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
} catch (error) {
|
|
134
|
-
this.LogError(`OPCUAIf: Error
|
|
134
|
+
this.LogError(`OPCUAIf: Error`, error)
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -192,7 +192,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
192
192
|
async call(opcuaNode, options = {}) {
|
|
193
193
|
var res = this.Check(options)
|
|
194
194
|
if (res < 0) {
|
|
195
|
-
// this.LogError(`OPCUAIf call: Missing essential options in dictionary => Quitting $res
|
|
195
|
+
// this.LogError(`OPCUAIf call: Missing essential options in dictionary => Quitting $res`)
|
|
196
196
|
return false
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -213,7 +213,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
213
213
|
value = super.formatString(options.value, options)
|
|
214
214
|
|
|
215
215
|
var convertedValue = this.convert(value, type)
|
|
216
|
-
//this.LogInfo(`OPCUAIf: write ${nodeId} => ${value}
|
|
216
|
+
//this.LogInfo(`OPCUAIf: write ${nodeId} => ${value}`)
|
|
217
217
|
await this.Write(nodeId, convertedValue, type)
|
|
218
218
|
|
|
219
219
|
var NewState = "waiting"
|
|
@@ -223,23 +223,23 @@ export class OPCUAIf extends BaseIf {
|
|
|
223
223
|
Check(options) {
|
|
224
224
|
var res = super.Check(options)
|
|
225
225
|
if (res < 0) {
|
|
226
|
-
this.LogError(`OPCUAIf: mandatory parameter missing
|
|
226
|
+
this.LogError(`OPCUAIf: mandatory parameter missing`)
|
|
227
227
|
return res
|
|
228
228
|
}
|
|
229
229
|
if (!"endpointurl" in options) {
|
|
230
|
-
this.LogError(`OPCUAIf: mandatory parameter endpointurl missing
|
|
230
|
+
this.LogError(`OPCUAIf: mandatory parameter endpointurl missing`)
|
|
231
231
|
return -11
|
|
232
232
|
}
|
|
233
233
|
if (!"publishingInterval" in options) {
|
|
234
|
-
this.LogError(`OPCUAIf: mandatory parameter publishingInterval missing
|
|
234
|
+
this.LogError(`OPCUAIf: mandatory parameter publishingInterval missing`)
|
|
235
235
|
return -11
|
|
236
236
|
}
|
|
237
237
|
if (!"nodeid" in options) {
|
|
238
|
-
this.LogError(`OPCUAIf: mandatory parameter nodeid missing
|
|
238
|
+
this.LogError(`OPCUAIf: mandatory parameter nodeid missing`)
|
|
239
239
|
return -12
|
|
240
240
|
}
|
|
241
241
|
if (!"value" in options) {
|
|
242
|
-
this.LogError(`OPCUAIf: mandatory parameter value missing
|
|
242
|
+
this.LogError(`OPCUAIf: mandatory parameter value missing`)
|
|
243
243
|
return -13
|
|
244
244
|
}
|
|
245
245
|
return 0
|
|
@@ -254,7 +254,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
254
254
|
if (!this.#client)
|
|
255
255
|
return
|
|
256
256
|
await this.Disconnect()
|
|
257
|
-
this.LogInfo(`OPCUAIf Stopped
|
|
257
|
+
this.LogInfo(`OPCUAIf Stopped`)
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
/**
|
|
@@ -292,55 +292,56 @@ export class OPCUAIf extends BaseIf {
|
|
|
292
292
|
initialDelay: 2500
|
|
293
293
|
},
|
|
294
294
|
keepPendingSessionsOnDisconnect: true,
|
|
295
|
-
defaultSecureTokenLifetime:
|
|
296
|
-
tokenRenewalInterval: 1000
|
|
295
|
+
defaultSecureTokenLifetime: 100000,
|
|
296
|
+
// tokenRenewalInterval: 1000
|
|
297
297
|
});
|
|
298
298
|
|
|
299
299
|
|
|
300
300
|
this.#client.on("backoff", (retry, delay) => {
|
|
301
|
+
self.LogInfo(`🔄 OPCUAIf Try Reconnection ${retry} next attempt in ${delay}ms ${self.#endpointurl}`);
|
|
301
302
|
//if ((retry % 10) == 0)
|
|
302
|
-
// self.LogInfo(`OPCUAIf Try Reconnection ${retry} next attempt in ${delay}ms ${self.#endpointurl}
|
|
303
|
+
// self.LogInfo(`OPCUAIf Try Reconnection ${retry} next attempt in ${delay}ms ${self.#endpointurl}`);
|
|
303
304
|
});
|
|
304
305
|
|
|
305
306
|
this.#client.on("connection_lost", () => {
|
|
306
|
-
self.
|
|
307
|
+
self.LogError(`OPCUAIf: Connection lost`);
|
|
307
308
|
});
|
|
308
309
|
|
|
309
310
|
this.#client.on("connection_reestablished", () => {
|
|
310
|
-
self.LogInfo(`OPCUAIf: Connection re-established
|
|
311
|
+
self.LogInfo(`OPCUAIf: Connection re-established`);
|
|
311
312
|
});
|
|
312
313
|
|
|
313
314
|
this.#client.on("connection_failed", () => {
|
|
314
|
-
self.
|
|
315
|
+
self.LogError(`OPCUAIf: Connection failed`);
|
|
315
316
|
});
|
|
316
317
|
this.#client.on("start_reconnection", () => {
|
|
317
|
-
self.LogInfo(`OPCUAIf: Starting reconnection
|
|
318
|
+
self.LogInfo(`OPCUAIf: Starting reconnection`);
|
|
318
319
|
});
|
|
319
320
|
|
|
320
321
|
this.#client.on("after_reconnection", (err) => {
|
|
321
|
-
self.LogInfo(`OPCUAIf: After Reconnection event => ${err}
|
|
322
|
+
self.LogInfo(`OPCUAIf: After Reconnection event => ${err}`);
|
|
322
323
|
});
|
|
323
324
|
/*this.#client.on("security_token_renewed", () => {
|
|
324
|
-
self.LogDebug(`OPCUAIf: security_token_renewed
|
|
325
|
+
self.LogDebug(`OPCUAIf: security_token_renewed`);
|
|
325
326
|
})*/
|
|
326
327
|
this.#client.on("lifetime_75", (token) => { })
|
|
327
328
|
|
|
328
|
-
this.LogInfo(`OPCUAIf: connecting client to ${url}
|
|
329
|
+
this.LogInfo(`OPCUAIf: connecting client to ${url}`);//, this.#session.toString());
|
|
329
330
|
await this.#client.connect(url);
|
|
330
331
|
|
|
331
332
|
this.#session = await this.#client.createSession();
|
|
332
333
|
|
|
333
334
|
this.#session.on("session_closed", (statusCode) => {
|
|
334
|
-
//self.LogInfo(`OPCUAIf: Session has been closed
|
|
335
|
+
//self.LogInfo(`OPCUAIf: Session has been closed`);
|
|
335
336
|
})
|
|
336
337
|
this.#session.on("session_restored", () => {
|
|
337
|
-
//self.LogInfo(`OPCUAIf: Session has been restored
|
|
338
|
+
//self.LogInfo(`OPCUAIf: Session has been restored`);
|
|
338
339
|
});
|
|
339
340
|
this.#session.on("keepalive", (lastKnownServerState) => {
|
|
340
|
-
self.LogInfo(`OPCUAIf: KeepAlive lastKnownServerState ${lastKnownServerState}
|
|
341
|
+
self.LogInfo(`OPCUAIf: KeepAlive lastKnownServerState ${lastKnownServerState}`);
|
|
341
342
|
});
|
|
342
343
|
this.#session.on("keepalive_failure", () => {
|
|
343
|
-
self.
|
|
344
|
+
self.LogError(`OPCUAIf: KeepAlive failure`);
|
|
344
345
|
});
|
|
345
346
|
|
|
346
347
|
// create subscription with a custom publishing interval:
|
|
@@ -352,9 +353,9 @@ export class OPCUAIf extends BaseIf {
|
|
|
352
353
|
requestedPublishingInterval: this.#publishingInterval
|
|
353
354
|
});
|
|
354
355
|
|
|
355
|
-
this.LogInfo(`OPCUAIf: session created
|
|
356
|
-
// this.LogInfo(`OPCUAIf: client
|
|
357
|
-
// this.LogInfo(`OPCUAIf: subscription
|
|
356
|
+
this.LogInfo(`OPCUAIf: session created`);
|
|
357
|
+
// this.LogInfo(`OPCUAIf: client`);
|
|
358
|
+
// this.LogInfo(`OPCUAIf: subscription`);
|
|
358
359
|
this.#connected = true
|
|
359
360
|
this.#endpointurl = url
|
|
360
361
|
}
|
|
@@ -407,15 +408,15 @@ export class OPCUAIf extends BaseIf {
|
|
|
407
408
|
};
|
|
408
409
|
|
|
409
410
|
if (!this.#sub) {
|
|
410
|
-
this.LogError(`OPCUAIf: no subscription - don't register monitored items $itemToMonitor
|
|
411
|
+
this.LogError(`OPCUAIf: no subscription - don't register monitored items $itemToMonitor`);
|
|
411
412
|
return
|
|
412
413
|
}
|
|
413
414
|
const monitoredItem = await this.#sub.monitor(itemToMonitor, monitoringParameters, TimestampsToReturn.Both);
|
|
414
415
|
this.monitoreditems[monitoredItem.monitoredItemId] = nodeID
|
|
415
416
|
if (monitoredItem.monitoredItemId === undefined) {
|
|
416
|
-
this.LogError(`OPCUAIf: Error subscribing to node ${nodeID} (attribute ${attribute})
|
|
417
|
+
this.LogError(`OPCUAIf: Error subscribing to node ${nodeID} (attribute ${attribute})`)
|
|
417
418
|
} else {
|
|
418
|
-
this.LogDebug(`OPCUAIf: Subscribe to ${monitoredItem.monitoredItemId},${nodeID},(attribute ${attribute})
|
|
419
|
+
this.LogDebug(`OPCUAIf: Subscribe to ${monitoredItem.monitoredItemId},${nodeID},(attribute ${attribute})`);
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
var self = this
|
|
@@ -432,7 +433,7 @@ export class OPCUAIf extends BaseIf {
|
|
|
432
433
|
list.push(`${buttonInfo.buttonID}:${buttonInfo.attribute}`)
|
|
433
434
|
self.emit('monitored item changed', buttonInfo.buttonID, buttonInfo.attribute, nodeId, dataValue.value.value)
|
|
434
435
|
}
|
|
435
|
-
self.LogInfo(`OPCUAIf: monitored item ${nodeId} changed value: ${dataValue.value.value} - push to buttons: ${list.join(', ')}
|
|
436
|
+
self.LogInfo(`OPCUAIf: monitored item ${nodeId} changed value: ${dataValue.value.value} - push to buttons: ${list.join(', ')}`);
|
|
436
437
|
});
|
|
437
438
|
|
|
438
439
|
return monitoredItem.monitoredItemId;
|
|
@@ -444,18 +445,18 @@ export class OPCUAIf extends BaseIf {
|
|
|
444
445
|
attributeId: AttributeIds.Value
|
|
445
446
|
};
|
|
446
447
|
if (!this.#connected) {
|
|
447
|
-
this.LogError(`OPCUAIf: not connected, cannot read ${nodeID}
|
|
448
|
+
this.LogError(`OPCUAIf: not connected, cannot read ${nodeID}`);
|
|
448
449
|
return
|
|
449
450
|
}
|
|
450
451
|
const dataValue2 = await this.#session.read(nodeToRead, 0);
|
|
451
|
-
this.
|
|
452
|
+
this.LogDebug("OPCUAIf: read nodeID ", nodeID, dataValue2.toString(), "");
|
|
452
453
|
return dataValue2
|
|
453
454
|
}
|
|
454
455
|
|
|
455
456
|
async Write(nodeID, value, datatype = DataType.String) {
|
|
456
457
|
let self = this
|
|
457
458
|
if (!this.#connected) {
|
|
458
|
-
self.LogError("OPCUAIf: not connected, cannot write", nodeID, value, "
|
|
459
|
+
self.LogError("OPCUAIf: not connected, cannot write", nodeID, value, "");
|
|
459
460
|
return
|
|
460
461
|
}
|
|
461
462
|
var nodesToWrite = [{
|
|
@@ -473,16 +474,16 @@ export class OPCUAIf extends BaseIf {
|
|
|
473
474
|
await this.#session.write(nodesToWrite, function (err, statusCodes) {
|
|
474
475
|
if (!err) {
|
|
475
476
|
if (statusCodes && statusCodes[0].value != 0) {
|
|
476
|
-
self.LogInfo(`OPCUAIf: error with Node: "${nodeID}", status ${statusCodes[0]}
|
|
477
|
+
self.LogInfo(`OPCUAIf: error with Node: "${nodeID}", status ${statusCodes[0]}`);
|
|
477
478
|
} else {
|
|
478
|
-
self.LogInfo(`OPCUAIf: wrote ${nodeID} => ${value}
|
|
479
|
+
self.LogInfo(`OPCUAIf: wrote ${nodeID} => ${value}`);
|
|
479
480
|
}
|
|
480
481
|
} else {
|
|
481
|
-
self.LogError(`OPCUAIf: writing not OK ${nodeID} => ${value}, ${err}
|
|
482
|
+
self.LogError(`OPCUAIf: writing not OK ${nodeID} => ${value}, ${err}`);
|
|
482
483
|
}
|
|
483
484
|
});
|
|
484
485
|
} catch (err) {
|
|
485
|
-
self.LogError(`OPCUAIf: writing not OK ${nodeID} => ${value}, ${err}
|
|
486
|
+
self.LogError(`OPCUAIf: writing not OK ${nodeID} => ${value}, ${err}`);
|
|
486
487
|
}
|
|
487
488
|
}
|
|
488
489
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loupedeck-commander",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "A system to ease working with LoupeDeck devices using CMD-line, OPC/UA or HTTP-client interfaces",
|
|
5
5
|
"main": "common/main.cjs",
|
|
6
6
|
"scripts": {
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"json5": "^2.2.3",
|
|
15
15
|
"loupedeck": "^7.0.3",
|
|
16
16
|
"mkdirp": "^3.0.1",
|
|
17
|
-
"node-opcua": "^2.
|
|
17
|
+
"node-opcua": "^2.171.0",
|
|
18
18
|
"postject": "^1.0.0-alpha.6",
|
|
19
19
|
"string-template": "^1.0.0",
|
|
20
|
-
"yaml": "^2.
|
|
20
|
+
"yaml": "^2.9.0"
|
|
21
21
|
},
|
|
22
22
|
"author": "Thomas Schneider",
|
|
23
23
|
"license": "Apache-2.0",
|