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.
@@ -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 >= id) {
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.myEmitter.on("monitored item changed",(buttonID,nodeid,val) => { self.buttonStateChanged(buttonID,nodeid,val) })
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
 
@@ -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
- //setProfileConfig (config) {
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, that contains some kind of command:
474
- if (!elem || (!elem.cmd && !elem.http && !elem.opcua)) {
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){
@@ -1,6 +1,7 @@
1
1
  import format from 'string-template'
2
+ import { EventEmitter } from 'node:events'
2
3
 
3
- export class BaseIf {
4
+ export class BaseIf extends EventEmitter {
4
5
  formattedCommand
5
6
  cmd
6
7
  options
@@ -12,7 +12,7 @@ import {
12
12
  coerceByteString,
13
13
  DataType
14
14
  } from "node-opcua";
15
- import { EventEmitter } from 'node:events'
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
- this.LogInfo(`OPCUAIf Try Reconnection ${retry} next attempt in ${delay}ms ${self.#endpointurl}\n`);
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
- this.LogInfo(`OPCUAIf: Connection lost\n`);
152
+ self.LogInfo(`OPCUAIf: Connection lost\n`);
155
153
  });
156
154
 
157
155
  this.#client.on("connection_reestablished", () => {
158
- this.LogInfo(`OPCUAIf: Connection re-established\n`);
156
+ self.LogInfo(`OPCUAIf: Connection re-established\n`);
159
157
  });
160
158
 
161
159
  this.#client.on("connection_failed", () => {
162
- this.LogInfo(`OPCUAIf: Connection failed\n`);
160
+ self.LogInfo(`OPCUAIf: Connection failed\n`);
163
161
  });
164
162
  this.#client.on("start_reconnection", () => {
165
- this.LogInfo(`OPCUAIf: Starting reconnection\n`);
163
+ self.LogInfo(`OPCUAIf: Starting reconnection\n`);
166
164
  });
167
165
 
168
166
  this.#client.on("after_reconnection", (err) => {
169
- this.LogInfo(`OPCUAIf: After Reconnection event => ${err}\n`);
167
+ self.LogInfo(`OPCUAIf: After Reconnection event => ${err}\n`);
170
168
  });
171
169
  this.#client.on("security_token_renewed", () => {
172
- this.LogInfo(`OPCUAIf: security_token_renewed\n`);
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
- this.LogInfo(`OPCUAIf: Session has been closed\n`);
180
+ self.LogInfo(`OPCUAIf: Session has been closed\n`);
183
181
  })
184
182
  this.#session.on("session_restored", () => {
185
- this.LogInfo(`OPCUAIf: Session has been restored\n`);
183
+ self.LogInfo(`OPCUAIf: Session has been restored\n`);
186
184
  });
187
185
  this.#session.on("keepalive", (lastKnownServerState) => {
188
- this.LogInfo(`OPCUAIf: KeepAlive lastKnownServerState ${lastKnownServerState}\n`);
186
+ self.LogInfo(`OPCUAIf: KeepAlive lastKnownServerState ${lastKnownServerState}\n`);
189
187
  });
190
188
  this.#session.on("keepalive_failure", () => {
191
- this.LogInfo(`OPCUAIf: KeepAlive failure\n`);
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
- this.LogDebug("OPCUAIf: monitored item changed: ", this.monitoredItemId,nodeId, dataValue.value.value,"\n");
232
- self.myEmitter.emit('monitored item changed',buttonID,nodeId, dataValue.value.value)
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");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loupedeck-commander",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
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": {