Skip to content

Commit 294e894

Browse files
authored
Merge pull request #12 from onfire4g05/master
Fixes connections not always working
2 parents dc5980d + 03a7907 commit 294e894

File tree

2 files changed

+56
-37
lines changed

2 files changed

+56
-37
lines changed

index.js

+55-36
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ class instance extends instance_skel {
1010
constructor(system, id, config) {
1111
super(system, id, config)
1212

13+
this.CONTROL_STX = '\u0002'
14+
this.CONTROL_ACK = '\u0006'
15+
1316
this.cmdPipe = []
1417
this.pollMixerTimer = undefined
1518
this.buttonSet = []
19+
this.lastReturnedCommand = ''
1620

1721
this.CHOICES_INPUTS = [
1822
{ label: 'SDI IN 1', id: '0' },
@@ -77,6 +81,17 @@ class instance extends instance_skel {
7781
this.init_tcp()
7882
this.initPolling()
7983
this.initPresets()
84+
85+
this.setVariableDefinitions([
86+
{ name: 'program', label: 'Currently active input' }, // #
87+
{ name: 'preview', label: 'Input in preview' }, // #
88+
{ name: 'aux', label: 'Input currently active in aux' }, // #
89+
{ name: 'dsk_status', label: 'DSK is on or off' }, // 4 == 1
90+
{ name: 'pip_1_status', label: 'PiP1 is on or off' }, // 3 = 1
91+
{ name: 'pip_2_status', label: 'PiP2 is on or off' }, // 3 = 2
92+
{ name: 'split_status', label: 'SPLIT is on or off' }, // 3 = 3
93+
{ name: 'outputfade_status', label: 'Output fade is on or off' } // 5 == 1
94+
]);
8095
}
8196

8297
init_tcp() {
@@ -110,52 +125,46 @@ class instance extends instance_skel {
110125

111126
this.socket.on('data', (receivebuffer) => {
112127
pipeline += receivebuffer.toString('utf8')
113-
if (pipeline.length == 1 && pipeline.charAt(0) == '\u0006') {
114-
// process simple <ack> responses (06H) as these come back for all successsful Control commands
115-
this.cmdPipeNext()
116-
pipeline = ''
117-
} else {
118-
// partial response pipeline processing as TCP Serial module can return partial responses in stream.
119-
if (pipeline.includes(';')) {
120-
// got at least one command terminated with ';'
121-
// multiple rapid Query strings can result in async multiple responses so split response into individual messages
122-
let allresponses = pipeline.split(';')
123-
// last element will either be a partial response an <ack> (processed next timer tick) or an empty string from split where a complete pipeline ends with ';'
124-
pipeline = allresponses.pop()
125-
for (let response of allresponses) {
126-
// Chance of leading <ack> responses from key commands or prior Query
127-
while (response.charAt[0] == '\u0006') {
128-
response = response.slice(1)
129-
this.cmdPipeNext()
130-
}
131-
if (response.length > 0) {
132-
this.processResponse(response)
133-
}
128+
129+
// ACKs are sent at the end of the stream result, we should have 1 command to 1 ack
130+
if (pipeline.includes(this.CONTROL_ACK)) {
131+
this.lastReturnedCommand = this.cmdPipeNext()
132+
if (pipeline.length == 1) pipeline = ''
133+
}
134+
135+
// Every command ends with ; and an ACK or an ACK if nothing needed; `VER` is the only command that won't return an ACK, which we do not use
136+
if (pipeline.includes(';')) {
137+
// multiple rapid Query strings can result in async multiple responses so split response into individual messages
138+
// however, the documentation for the V-60 says NOT to send more than 1 command before receiving the ACK from the last one,
139+
// so we should always have one at a time
140+
let allresponses = pipeline.split(';')
141+
// last element will either be a partial response, an <ack> (processed next timer tick), or an empty string from split where a complete pipeline ends with ';'
142+
pipeline = allresponses.pop()
143+
for (let response of allresponses) {
144+
response = response.replace(new RegExp(this.CONTROL_ACK, 'g'), '')
145+
146+
if (response.length > 0) {
147+
this.processResponse(response)
134148
}
135149
}
136150
}
137151
})
138152
}
139153
}
140154
cmdPipeNext() {
141-
if (this.cmdPipe.length > 0) {
142-
const return_cmd = this.cmdPipe.shift()
155+
const return_cmd = this.cmdPipe.shift()
143156

144-
if(this.cmdPipe.length > 0) {
145-
this.socket.send('\u0002' + this.cmdPipe[0] + ';')
146-
}
147-
148-
return return_cmd
149-
} else {
150-
this.log('error', 'Unexpected response count (pipe underrun)')
151-
return ''
157+
if(this.cmdPipe.length > 0) {
158+
this.socket.send(this.CONTROL_STX + this.cmdPipe[0] + ';')
152159
}
160+
161+
return return_cmd
153162
}
154163
processResponse(response) {
155164
let category = 'XXX'
156165
let args = []
157166

158-
const errorMessage = (errcode, pipeitem) => {
167+
const errorMessage = (errcode) => {
159168
let errstring = ''
160169
switch (errcode) {
161170
case '0':
@@ -171,7 +180,7 @@ class instance extends instance_skel {
171180
errstring = '(UNKNOWN Error)'
172181
break
173182
}
174-
this.log('error', 'ERR: ' + errstring + ' - Command = ' + pipeitem)
183+
this.log('error', 'ERR: ' + errstring + ' - Command = ' + this.lastReturnedCommand)
175184
}
176185

177186
let settingseparator = response.search(':')
@@ -183,10 +192,20 @@ class instance extends instance_skel {
183192
switch (category) {
184193
case 'QPL': //button settings array (polled)
185194
this.buttonSet = args
195+
196+
this.setVariable('program', parseInt(this.buttonSet[0]) + 1);
197+
this.setVariable('preview', parseInt(this.buttonSet[1]) + 1);
198+
this.setVariable('aux', parseInt(this.buttonSet[2]) + 1);
199+
this.setVariable('dsk_status', this.buttonSet[4] === '1' ? 'on' : 'off');
200+
this.setVariable('pip_1_status', this.buttonSet[3] === '1' ? 'on' : 'off');
201+
this.setVariable('pip_2_status', this.buttonSet[3] === '2' ? 'on' : 'off');
202+
this.setVariable('split_status', this.buttonSet[3] === '3' ? 'on' : 'off');
203+
this.setVariable('outputfade_status', this.buttonSet[5] === '1' ? 'on' : 'off');
204+
186205
this.checkFeedbacks()
187206
break
188207
case 'ERR':
189-
errorMessage(args[0], this.cmdPipeNext())
208+
errorMessage(args[0])
190209
break
191210
}
192211
}
@@ -196,7 +215,7 @@ class instance extends instance_skel {
196215
this.cmdPipe.push(cmd)
197216

198217
if(this.cmdPipe.length === 1) {
199-
this.socket.send('\u0002' + cmd + ';')
218+
this.socket.send(this.CONTROL_STX + cmd + ';')
200219
}
201220
} else {
202221
debug('Socket not connected :(')
@@ -237,7 +256,7 @@ class instance extends instance_skel {
237256
label: 'Polling Interval (ms), set to 0 to disable polling',
238257
min: 0,
239258
max: 30000,
240-
default: 0,
259+
default: 1000,
241260
width: 8,
242261
},
243262
]

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "roland-v60hd",
3-
"version": "1.0.15",
3+
"version": "1.0.16",
44
"api_version": "1.0.0",
55
"keywords": [
66
"Vision Mixer",

0 commit comments

Comments
 (0)