loupedeck-commander 1.2.1 → 1.2.2

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,313 +1,313 @@
1
- import {discover, HAPTIC,LoupedeckDevice } from 'loupedeck'
2
- import { ApplicationConfig } from './ApplicationConfig.mjs'
3
- import { ButtonField, StopInterfaces, InitializeInterfaces,opcuainterface} from './touchbuttons.mjs'
4
-
5
- export class BaseLoupeDeckHandler {
6
- device = undefined
7
- appConfig = undefined
8
- profileConfigs = []
9
- currentProfile = 0
10
- screens = {}
11
- buttons = {}
12
- screenUpdate = {}
13
- stopping = false
14
-
15
- constructor (config) {
16
- console.log(`INIT with config ${config}`)
17
- this.loadConfig(config)
18
- }
19
-
20
- /**
21
- * event handler - start
22
- */
23
- async start () {
24
- console.info('Start')
25
- while (!this.device && !this.stopping) {
26
- try {
27
- var list = await LoupedeckDevice.list()
28
- if (list.length>0){
29
- var element = list[0]
30
- console.log("Connecting to device")
31
- console.log("Path: ", element.path)
32
- console.log("vendorId: ", element.vendorId, element.productId)
33
- console.log("serialNumber: ", element.serialNumber)
34
- }
35
-
36
- this.device = await discover()
37
-
38
-
39
-
40
- } catch (e) {
41
- console.error(`${e}. Reattempting in 3 seconds...`)
42
- await new Promise(resolve => setTimeout(resolve, 3000))
43
- }
44
-
45
- if (this.stopping){
46
- return
47
- }
48
- }
49
- console.info(`✅ Discovered Device ${this.device.type}`)
50
-
51
- const self = this
52
-
53
- this.device.on('connect', (address) => { self.onConnected(address) })
54
- this.device.on('down', (event) => { self.onButtonDown(event) })
55
- this.device.on('up', (event) => { self.onButtonUp(event) })
56
- this.device.on('rotate', (event) => { self.onRotate(event) })
57
- this.device.on('touchstart', (event) => { self.onTouchStart(event) })
58
- this.device.on('touchmove', (event) => { self.onTouchMove(event) })
59
- this.device.on('touchend', (event) => { self.onTouchEnd(event) })
60
- this.device.on('disconnect', (event) => { self.disconnectDevice(event) })
61
-
62
- console.info(`✅ Registered callbacks`)
63
- }
64
-
65
- /**
66
- * event handler - loupedeck device disconnected
67
- */
68
- async disconnectDevice (event) {
69
- console.info("Device Disconnected")
70
- this.device=undefined
71
- }
72
-
73
- /**
74
- * stop handler - close the dipslay-connection and also stop all interface handlers
75
- */
76
- async stop () {
77
- console.info('Stopping Handler')
78
-
79
- try {
80
- console.info(`Closing Device`)
81
- this.stopping = true
82
- if (this.device){
83
- this.device.vibrate(HAPTIC.DESCEND_MED)
84
- await new Promise(resolve => setTimeout(resolve, 250))
85
- }
86
- if (this.device){
87
- this.device.setBrightness(0)
88
- await new Promise(resolve => setTimeout(resolve, 250))
89
- }
90
- if (this.device){
91
- this.device.reconnectInterval = 0
92
- await this.device.close()
93
- await new Promise(resolve => setTimeout(resolve, 2000))
94
- console.info(`Device Closed`)
95
- }
96
-
97
- console.info(`Stopping interfaces`)
98
- await StopInterfaces()
99
- await new Promise(resolve => setTimeout(resolve, 500))
100
- } catch (e) {}
101
-
102
- process.exit()
103
-
104
- }
105
-
106
- /**
107
- * load Application config file from JSON
108
- * @param filename
109
- */
110
- loadConfig (fileName) {
111
- console.info(`Loading Config File ${fileName}`)
112
- this.appConfig = new ApplicationConfig()
113
- this.appConfig.loadFromFile(fileName)
114
- }
115
-
116
- /**
117
- * activate the profile with the givven ID
118
- */
119
- async activateProfile (id) {
120
- // todo Profile-change implementation
121
- var oldProfile = this.currentProfile
122
- if (this.appConfig.profiles.length >= id) {
123
- this.currentProfile = id
124
- }else{
125
- return
126
- }
127
-
128
- const dLeft = this.device.displays.left
129
- const dRight = this.device.displays.right
130
- const dCenter = this.device.displays.center
131
- const dKnob = this.device.displays.knob
132
-
133
- const profile = this.getCurrentProfile()
134
- this.screens.center = new ButtonField('center', this.device.rows, this.device.columns, dCenter.width, dCenter.height, profile.touch.center,profile)
135
- this.screens.left = new ButtonField('left', 1, 1, dLeft.width, dLeft.height, profile.touch.left,profile)
136
- this.screens.right = new ButtonField('right', 1, 1, dRight.width, dRight.height, profile.touch.right,profile)
137
- // knob Display is only available in the CT-version - not with live:
138
- if (dKnob) {
139
- this.screens.knob = new ButtonField('knob', 1, 1, dKnob.width, dKnob.height, profile.touch.knob,profile)
140
- }
141
-
142
- this.buttons = new ButtonField('buttons', 1, 1, 0, 0, profile.buttons,profile)
143
-
144
- await this.screens.center.load()
145
- await this.screens.right.load()
146
- await this.screens.left.load()
147
- if (dKnob) {
148
- await this.screens.knob.load()
149
- }
150
- await this.buttons.load()
151
-
152
- await this.screens.center.draw(this.device)
153
- if (dKnob) {
154
- await this.screens.knob.draw(this.device)
155
- }
156
-
157
- this.buttons.setState(this.currentProfile+1,1)
158
- this.buttons.setState(oldProfile+1,1)
159
-
160
- await this.buttons.draw(this.device)
161
- }
162
-
163
- /**
164
- * get the dictionary iwth the current profile settings
165
- */
166
- getCurrentProfile () {
167
- return this.appConfig.profiles[this.currentProfile]
168
- }
169
-
170
- /**
171
- * Triggered, when LoupeDeck Device is connected
172
- * - Initialize the profile from config-file and
173
- * - start the interface handlers accordingly
174
- */
175
- async onConnected (address) {
176
- console.info(`✅ Connected to ${this.device.type}, ${address}`)
177
-
178
- await this.activateProfile(0)
179
-
180
- var profile = this.getCurrentProfile()
181
- await InitializeInterfaces(profile,this.buttons.setState)
182
-
183
- const self = this
184
-
185
- // Register callback on monitored item change:
186
- opcuainterface.myEmitter.on("monitored item changed",(buttonID,nodeid,val) => { self.buttonStateChanged(buttonID,nodeid,val) })
187
-
188
- this.device.setBrightness(1)
189
- this.device.vibrate(HAPTIC.ASCEND_MED)
190
-
191
- console.info('✅ Done initializing')
192
- }
193
-
194
- /**
195
- * Fore an update of all screens
196
- */
197
- async updateScreens () {
198
- const keys = Object.keys(this.screenUpdate)
199
- for (let i = 0; i < keys.length; i++) {
200
- const screen = keys[i]
201
- await this.screens[screen].draw(this.device)
202
- }
203
- this.screenUpdate = {}
204
- }
205
-
206
- /**
207
- * Button Down Handler - triggered through Event Button Down - connected to LoupeDeck Event
208
- */
209
- async onButtonDown (event) {
210
- let ok = false
211
- const id = event.id
212
- ok = await this.buttons.pressed(id)
213
- await this.buttons.draw(this.device)
214
- return ok
215
- }
216
-
217
- /**
218
- * Button Up Handler - triggered through Event Button Up - connected to LoupeDeck Event
219
- */
220
- async onButtonUp (event) {
221
- let ok = false
222
- const id = event.id
223
- ok = await this.buttons.released(id)
224
- await this.buttons.draw(this.device)
225
-
226
- /*if (this.currentProfile != id){
227
- this.activateProfile(id-1)
228
- }*/
229
- return ok
230
- }
231
-
232
- /**
233
- * Button Rotate Handler - triggered through Event Rotate available with knob-Buttons - connected to LoupeDeck Event
234
- */
235
- async onRotate (event) {
236
- const id = event.id
237
- const delta = event.delta
238
- return await this.buttons.rotated(id, delta)
239
- }
240
-
241
- /**
242
- * TouchStart Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
243
- */
244
- async onTouchStart (event) {
245
- let ok = false
246
- const changedTouches = event.changedTouches
247
- for (let i = 0; i < changedTouches.length; i++) {
248
- const screen = changedTouches[i].target.screen
249
- let id = changedTouches[i].target.key
250
- this.screenUpdate[screen] = true
251
- if (id === undefined) {
252
- id = 0
253
- }
254
- ok = await this.screens[screen].pressed(id)
255
- }
256
- await this.updateScreens()
257
- return ok
258
- }
259
-
260
- /**
261
- * TouchMove Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
262
- */
263
- async onTouchMove (event) {
264
- let ok = false
265
- const changedTouches = event.changedTouches
266
- for (let i = 0; i < changedTouches.length; i++) {
267
- const x = changedTouches[i].x
268
- const y = changedTouches[i].y
269
- const screen = changedTouches[i].target.screen
270
- let id = changedTouches[i].target.key
271
- if (id === undefined) {
272
- id = 0 // for left/right
273
- }
274
- ok = await this.screens[screen].touchmove(id, x, y)
275
- }
276
- return ok
277
- }
278
-
279
- /**
280
- * TouchEnd Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
281
- */
282
- async onTouchEnd (event) {
283
- let ok = false
284
- const changedTouches = event.changedTouches
285
- for (let i = 0; i < changedTouches.length; i++) {
286
- const elem = changedTouches[i].target
287
- let id = changedTouches[i].target.key
288
- if (id === undefined) {
289
- id = 0
290
- }
291
- this.screenUpdate[elem.screen] = true
292
-
293
- ok = await this.screens[elem.screen].released(id)
294
- }
295
- await this.updateScreens()
296
- return ok
297
- }
298
-
299
- /**
300
- * Handler for StateChanged through OPC/UA Interface - only connected with touch-buttons on center field (yet)
301
- */
302
- async buttonStateChanged(buttonID,nodeid,val) {
303
- let ok = false
304
- this.screenUpdate["center"] = true
305
-
306
- ok = await this.screens.center.changed(buttonID,nodeid,val)
307
-
308
- await this.updateScreens()
309
- return ok
310
- }
311
-
312
-
313
- }
1
+ import {discover, HAPTIC,LoupedeckDevice } from 'loupedeck'
2
+ import { ApplicationConfig } from './ApplicationConfig.mjs'
3
+ import { ButtonField, StopInterfaces, InitializeInterfaces,opcuainterface} from './touchbuttons.mjs'
4
+
5
+ export class BaseLoupeDeckHandler {
6
+ device = undefined
7
+ appConfig = undefined
8
+ profileConfigs = []
9
+ currentProfile = 0
10
+ screens = {}
11
+ buttons = {}
12
+ screenUpdate = {}
13
+ stopping = false
14
+
15
+ constructor (config) {
16
+ console.log(`INIT with config ${config}`)
17
+ this.loadConfig(config)
18
+ }
19
+
20
+ /**
21
+ * event handler - start
22
+ */
23
+ async start () {
24
+ console.info('Start')
25
+ while (!this.device && !this.stopping) {
26
+ try {
27
+ var list = await LoupedeckDevice.list()
28
+ if (list.length>0){
29
+ var element = list[0]
30
+ console.log("Connecting to device")
31
+ console.log("Path: ", element.path)
32
+ console.log("vendorId: ", element.vendorId, element.productId)
33
+ console.log("serialNumber: ", element.serialNumber)
34
+ }
35
+
36
+ this.device = await discover()
37
+
38
+
39
+
40
+ } catch (e) {
41
+ console.error(`${e}. Reattempting in 3 seconds...`)
42
+ await new Promise(resolve => setTimeout(resolve, 3000))
43
+ }
44
+
45
+ if (this.stopping){
46
+ return
47
+ }
48
+ }
49
+ console.info(`✅ Discovered Device ${this.device.type}`)
50
+
51
+ const self = this
52
+
53
+ this.device.on('connect', (address) => { self.onConnected(address) })
54
+ this.device.on('down', (event) => { self.onButtonDown(event) })
55
+ this.device.on('up', (event) => { self.onButtonUp(event) })
56
+ this.device.on('rotate', (event) => { self.onRotate(event) })
57
+ this.device.on('touchstart', (event) => { self.onTouchStart(event) })
58
+ this.device.on('touchmove', (event) => { self.onTouchMove(event) })
59
+ this.device.on('touchend', (event) => { self.onTouchEnd(event) })
60
+ this.device.on('disconnect', (event) => { self.disconnectDevice(event) })
61
+
62
+ console.info(`✅ Registered callbacks`)
63
+ }
64
+
65
+ /**
66
+ * event handler - loupedeck device disconnected
67
+ */
68
+ async disconnectDevice (event) {
69
+ console.info("Device Disconnected")
70
+ this.device=undefined
71
+ }
72
+
73
+ /**
74
+ * stop handler - close the dipslay-connection and also stop all interface handlers
75
+ */
76
+ async stop () {
77
+ console.info('Stopping Handler')
78
+
79
+ try {
80
+ console.info(`Closing Device`)
81
+ this.stopping = true
82
+ if (this.device){
83
+ this.device.vibrate(HAPTIC.DESCEND_MED)
84
+ await new Promise(resolve => setTimeout(resolve, 250))
85
+ }
86
+ if (this.device){
87
+ this.device.setBrightness(0)
88
+ await new Promise(resolve => setTimeout(resolve, 250))
89
+ }
90
+ if (this.device){
91
+ this.device.reconnectInterval = 0
92
+ await this.device.close()
93
+ await new Promise(resolve => setTimeout(resolve, 2000))
94
+ console.info(`Device Closed`)
95
+ }
96
+
97
+ console.info(`Stopping interfaces`)
98
+ await StopInterfaces()
99
+ await new Promise(resolve => setTimeout(resolve, 500))
100
+ } catch (e) {}
101
+
102
+ process.exit()
103
+
104
+ }
105
+
106
+ /**
107
+ * load Application config file from JSON
108
+ * @param filename
109
+ */
110
+ loadConfig (fileName) {
111
+ console.info(`Loading Config File ${fileName}`)
112
+ this.appConfig = new ApplicationConfig()
113
+ this.appConfig.loadFromFile(fileName)
114
+ }
115
+
116
+ /**
117
+ * activate the profile with the givven ID
118
+ */
119
+ async activateProfile (id) {
120
+ // todo Profile-change implementation
121
+ var oldProfile = this.currentProfile
122
+ if (this.appConfig.profiles.length >= id) {
123
+ this.currentProfile = id
124
+ }else{
125
+ return
126
+ }
127
+
128
+ const dLeft = this.device.displays.left
129
+ const dRight = this.device.displays.right
130
+ const dCenter = this.device.displays.center
131
+ const dKnob = this.device.displays.knob
132
+
133
+ const profile = this.getCurrentProfile()
134
+ this.screens.center = new ButtonField('center', this.device.rows, this.device.columns, dCenter.width, dCenter.height, profile.touch.center,profile)
135
+ this.screens.left = new ButtonField('left', 1, 1, dLeft.width, dLeft.height, profile.touch.left,profile)
136
+ this.screens.right = new ButtonField('right', 1, 1, dRight.width, dRight.height, profile.touch.right,profile)
137
+ // knob Display is only available in the CT-version - not with live:
138
+ if (dKnob) {
139
+ this.screens.knob = new ButtonField('knob', 1, 1, dKnob.width, dKnob.height, profile.touch.knob,profile)
140
+ }
141
+
142
+ this.buttons = new ButtonField('buttons', 1, 1, 0, 0, profile.buttons,profile)
143
+
144
+ await this.screens.center.load()
145
+ await this.screens.right.load()
146
+ await this.screens.left.load()
147
+ if (dKnob) {
148
+ await this.screens.knob.load()
149
+ }
150
+ await this.buttons.load()
151
+
152
+ await this.screens.center.draw(this.device)
153
+ if (dKnob) {
154
+ await this.screens.knob.draw(this.device)
155
+ }
156
+
157
+ this.buttons.setState(this.currentProfile+1,1)
158
+ this.buttons.setState(oldProfile+1,1)
159
+
160
+ await this.buttons.draw(this.device)
161
+ }
162
+
163
+ /**
164
+ * get the dictionary iwth the current profile settings
165
+ */
166
+ getCurrentProfile () {
167
+ return this.appConfig.profiles[this.currentProfile]
168
+ }
169
+
170
+ /**
171
+ * Triggered, when LoupeDeck Device is connected
172
+ * - Initialize the profile from config-file and
173
+ * - start the interface handlers accordingly
174
+ */
175
+ async onConnected (address) {
176
+ console.info(`✅ Connected to ${this.device.type}, ${address}`)
177
+
178
+ await this.activateProfile(0)
179
+
180
+ var profile = this.getCurrentProfile()
181
+ await InitializeInterfaces(profile,this.buttons.setState)
182
+
183
+ const self = this
184
+
185
+ // Register callback on monitored item change:
186
+ opcuainterface.myEmitter.on("monitored item changed",(buttonID,nodeid,val) => { self.buttonStateChanged(buttonID,nodeid,val) })
187
+
188
+ this.device.setBrightness(1)
189
+ this.device.vibrate(HAPTIC.ASCEND_MED)
190
+
191
+ console.info('✅ Done initializing')
192
+ }
193
+
194
+ /**
195
+ * Fore an update of all screens
196
+ */
197
+ async updateScreens () {
198
+ const keys = Object.keys(this.screenUpdate)
199
+ for (let i = 0; i < keys.length; i++) {
200
+ const screen = keys[i]
201
+ await this.screens[screen].draw(this.device)
202
+ }
203
+ this.screenUpdate = {}
204
+ }
205
+
206
+ /**
207
+ * Button Down Handler - triggered through Event Button Down - connected to LoupeDeck Event
208
+ */
209
+ async onButtonDown (event) {
210
+ let ok = false
211
+ const id = event.id
212
+ ok = await this.buttons.pressed(id)
213
+ await this.buttons.draw(this.device)
214
+ return ok
215
+ }
216
+
217
+ /**
218
+ * Button Up Handler - triggered through Event Button Up - connected to LoupeDeck Event
219
+ */
220
+ async onButtonUp (event) {
221
+ let ok = false
222
+ const id = event.id
223
+ ok = await this.buttons.released(id)
224
+ await this.buttons.draw(this.device)
225
+
226
+ /*if (this.currentProfile != id){
227
+ this.activateProfile(id-1)
228
+ }*/
229
+ return ok
230
+ }
231
+
232
+ /**
233
+ * Button Rotate Handler - triggered through Event Rotate available with knob-Buttons - connected to LoupeDeck Event
234
+ */
235
+ async onRotate (event) {
236
+ const id = event.id
237
+ const delta = event.delta
238
+ return await this.buttons.rotated(id, delta)
239
+ }
240
+
241
+ /**
242
+ * TouchStart Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
243
+ */
244
+ async onTouchStart (event) {
245
+ let ok = false
246
+ const changedTouches = event.changedTouches
247
+ for (let i = 0; i < changedTouches.length; i++) {
248
+ const screen = changedTouches[i].target.screen
249
+ let id = changedTouches[i].target.key
250
+ this.screenUpdate[screen] = true
251
+ if (id === undefined) {
252
+ id = 0
253
+ }
254
+ ok = await this.screens[screen].pressed(id)
255
+ }
256
+ await this.updateScreens()
257
+ return ok
258
+ }
259
+
260
+ /**
261
+ * TouchMove Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
262
+ */
263
+ async onTouchMove (event) {
264
+ let ok = false
265
+ const changedTouches = event.changedTouches
266
+ for (let i = 0; i < changedTouches.length; i++) {
267
+ const x = changedTouches[i].x
268
+ const y = changedTouches[i].y
269
+ const screen = changedTouches[i].target.screen
270
+ let id = changedTouches[i].target.key
271
+ if (id === undefined) {
272
+ id = 0 // for left/right
273
+ }
274
+ ok = await this.screens[screen].touchmove(id, x, y)
275
+ }
276
+ return ok
277
+ }
278
+
279
+ /**
280
+ * TouchEnd Handler - triggered through Event touch available on all touchbuttons on the loupedeck display - connected to LoupeDeck Event
281
+ */
282
+ async onTouchEnd (event) {
283
+ let ok = false
284
+ const changedTouches = event.changedTouches
285
+ for (let i = 0; i < changedTouches.length; i++) {
286
+ const elem = changedTouches[i].target
287
+ let id = changedTouches[i].target.key
288
+ if (id === undefined) {
289
+ id = 0
290
+ }
291
+ this.screenUpdate[elem.screen] = true
292
+
293
+ ok = await this.screens[elem.screen].released(id)
294
+ }
295
+ await this.updateScreens()
296
+ return ok
297
+ }
298
+
299
+ /**
300
+ * Handler for StateChanged through OPC/UA Interface - only connected with touch-buttons on center field (yet)
301
+ */
302
+ async buttonStateChanged(buttonID,nodeid,val) {
303
+ let ok = false
304
+ this.screenUpdate["center"] = true
305
+
306
+ ok = await this.screens.center.changed(buttonID,nodeid,val)
307
+
308
+ await this.updateScreens()
309
+ return ok
310
+ }
311
+
312
+
313
+ }
@@ -1,16 +1,16 @@
1
- import { exec } from 'child_process'
2
-
3
- export async function sh (cmd) {
4
- // console.log('TRIGGER -> ', cmd)
5
-
6
- return new Promise(function (resolve, reject) {
7
- exec(cmd, (err, stdout, stderr) => {
8
- console.log('executed cmd, stdout:', stdout)
9
- if (err) {
10
- reject(err)
11
- } else {
12
- resolve({ stdout, stderr })
13
- }
14
- })
15
- })
16
- }
1
+ import { exec } from 'child_process'
2
+
3
+ export async function sh (cmd) {
4
+ // console.log('TRIGGER -> ', cmd)
5
+
6
+ return new Promise(function (resolve, reject) {
7
+ exec(cmd, (err, stdout, stderr) => {
8
+ console.log('executed cmd, stdout:', stdout)
9
+ if (err) {
10
+ reject(err)
11
+ } else {
12
+ resolve({ stdout, stderr })
13
+ }
14
+ })
15
+ })
16
+ }
package/common/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { BaseLoupeDeckHandler } from './BaseLoupeDeckHandler.mjs'
2
-
3
- module.exports = {
4
- BaseLoupeDeckHandler
5
- }
1
+ import { BaseLoupeDeckHandler } from './BaseLoupeDeckHandler.mjs'
2
+
3
+ module.exports = {
4
+ BaseLoupeDeckHandler
5
+ }