From 19201475ae4f33b0e453c54136f17c20ff5d9ebf Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sun, 19 Feb 2023 15:14:49 -0600 Subject: [PATCH 1/9] initial commit for show cue systems --- plugins/scs/icon.png | Bin 0 -> 563 bytes plugins/scs/info.html | 4 + plugins/scs/main.js | 187 +++++++++++++++++++++++++++++++++++++++ plugins/scs/styles.css | 12 +++ plugins/scs/template.ejs | 25 ++++++ 5 files changed, 228 insertions(+) create mode 100644 plugins/scs/icon.png create mode 100644 plugins/scs/info.html create mode 100644 plugins/scs/main.js create mode 100644 plugins/scs/styles.css create mode 100644 plugins/scs/template.ejs diff --git a/plugins/scs/icon.png b/plugins/scs/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..383037ae934f0ac5735b251b852a72c623e1cb6c GIT binary patch literal 563 zcmV-30?hr1P)Nc#JGgO zyz1}nS+J=9!nOdwv;eoN)8ykIr<^mcrEapWi@LX$!@thm+oQ+DN1T;rsH1tQrk1U$ z&C$?Kx2|}-xR|!Hue!PM^Yf3z!l%EyzRAe6$i)Pei-f48u)MksjDruLmUfas$p8QW zRY^oaRCob>($%)ZAP@!6iMt1=M(WWk|Nn6fP=QqT>p3th6F{V>nr_HUAvG-9aa@__ zKk^`Sqj)ZfQsA=OK?#0=$gQxjBPpI27E6rqmqKPgawLl*R>-4U9wXw&*jEJ3Z9Z~V z>&;eH04O%%akLB+ctdw$p06@^%Zm5~OPXgzA=l^xc0ugw08m!-Zhw#mskaF$w(jG} zKVJ?Y(wyYJ^rp5>?Y8Ut1_ZPG|{YyDdRt(mYcDloh)mb~KP>s@lLLC44)}2Htu6 zzbJ=yl$I|KCv-xi&J^v6ou@(tVEFr&IpqGn60hLnWHFEFfEHLG#&0Dghi`?%v6L@` z1iO66?+PeRkP|*u7Connection Requirements +
    +
  • Network Protocol must be set to TCP under Remote App Interface settings
  • +
diff --git a/plugins/scs/main.js b/plugins/scs/main.js new file mode 100644 index 0000000..638a545 --- /dev/null +++ b/plugins/scs/main.js @@ -0,0 +1,187 @@ +exports.config = { + defaultName: 'Show Cue Systems', + connectionType: 'TCPsocket', + defaultPort: 58000, + mayChangePort: true, + heartbeatInterval: 5000, + searchOptions: { + type: 'TCPport', + searchBuffer: Buffer.from('/_status', 'ascii'), + testPort: 58000, + validateResponse(msg, info) { + return msg.toString().includes('/_status'); + }, + }, + fields: [], +}; + +const typeMap = { + A: 'Video/Image', + E: 'Memo', + F: 'Audio File', + G: 'GoTo Cue', + H: 'Multi-File Cue', + I: 'Live Input', + J: 'Enable/Disable', + K: 'Lighting', + L: 'Level Change', + M: 'Control Send', + N: 'Note', + P: 'Playlist', + Q: 'Call Cue', + R: 'Run Program', + S: 'SFR', + T: 'Set Position', + U: 'MIDI Time Code', +}; + +const versionMap = { + 10: 'LITE', + 20: 'STD', + 30: 'PRO', + 40: 'PLUS', + 45: 'DEMO', + 50: 'PLAT', +}; + +exports.ready = function ready(_device) { + const device = _device; + console.log('Show Cue Systems ready'); + device.data.cues = []; + device.send(Buffer.from('/_prod/gettitle')); +}; + +exports.data = function data(_device, message) { + const device = _device; + this.deviceInfoUpdate(device, 'status', 'ok'); + const msg = message.toString(); + const messagePath = msg.substring(0, msg.indexOf(' ')); + if (messagePath === '/_prod/gettitle') { + const title = msg.replace(messagePath, '').replaceAll('"', '').trim(); + this.deviceInfoUpdate(device, 'defaultName', title); + device.send(Buffer.from('/_info/scsversion')); + } else if (messagePath === '/_info/scsversion') { + const versionInfo = msg.replace(messagePath, '').trim().split(' '); + const versionNumber = versionInfo[0]; + const versionMajor = versionNumber.substring(0, 2).replace('0', ''); + const versionMinor = versionNumber.substring(2, 4).replace('0', ''); + const versionPatch = versionNumber.substring(4, 6).replace('0', ''); + const versionString = `${versionMajor}.${versionMinor}.${versionPatch}`; + + const versionType = versionMap[versionInfo[1]]; + device.data.version = { + number: versionString, + type: versionType, + }; + device.send(Buffer.from('/_info/finalcue', 'ascii')); + } else if (messagePath === '/_info/finalcue') { + const cueCount = parseInt(msg.replace(messagePath, '').trim(), 10); + device.data.cues = new Array(cueCount).fill(0).map(() => ({ + label: '', + page: '', + description: '', + type: { code: '', display: '' }, + state: '', + activation: '', + file_info: '', + length: '', + colors: ['', ''], + })); + device.send(Buffer.from(`/_cue/getitemsn 1 QNTCLSPARZ`)); + } else if (messagePath === '/_info/getcue') { + const cueLabelInfo = msg.replace(messagePath, '').trim().split(' '); + const cueNumber = parseInt(cueLabelInfo[0], 10); + const cueLabel = cueLabelInfo[1].replaceAll('"', ''); + + device.data.cues[cueNumber - 1].label = cueLabel; + device.draw(); + } else if (messagePath === '/_cue/getpage') { + const pageInfo = msg.replace(messagePath, '').trim().match(/".*?"/g); + const cueLabel = pageInfo[0].replaceAll('"', ''); + const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); + device.data.cues[cueIndex].page = pageInfo[1].replaceAll('"', ''); + if (cueIndex < device.data.cues.length - 1) { + device.send(Buffer.from(`/_cue/getpage ${device.data.cues[cueIndex + 1].label}`)); + } else { + // console.log('done loading cue pages'); + device.draw(); + device.send(Buffer.from('/_status')); + } + } else if (messagePath === '/_cue/getname') { + const nameInfo = msg.replace(messagePath, '').trim().match(/".*?"/g); + const cueLabel = nameInfo[0].replaceAll('"', ''); + const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); + + device.data.cues[cueIndex].description = nameInfo[1].replaceAll('"', ''); + device.draw(); + } else if (messagePath === '/_cue/gettype') { + const typeInfo = msg.replace(messagePath, '').trim().match(/".*?"/g); + const cueLabel = typeInfo[0].replaceAll('"', ''); + const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); + + device.data.cues[cueIndex].type = { + code: typeInfo[1].replaceAll('"', ''), + display: typeMap[typeInfo[1].replaceAll('"', '')], + }; + device.draw(); + } else if (messagePath === '/_cue/getitemsn') { + const itemParts = msg + .replace(messagePath, '') + .trim('') + .match(/".*?"|\d+/g); + if (itemParts.length === 12) { + const cueIndex = itemParts[0] - 1; + device.data.cues[cueIndex].label = sanitizeSCSString(itemParts[2]); + device.data.cues[cueIndex].description = sanitizeSCSString(itemParts[3]); + device.data.cues[cueIndex].type = { + code: sanitizeSCSString(itemParts[4]), + display: typeMap[sanitizeSCSString(itemParts[4])], + }; + device.data.cues[cueIndex].colors = sanitizeSCSString(itemParts[5]).split(', '); + device.data.cues[cueIndex].length = millisToString(itemParts[6]); + device.data.cues[cueIndex].state = itemParts[7]; + device.data.cues[cueIndex].position = itemParts[8]; + device.data.cues[cueIndex].activation = sanitizeSCSString(itemParts[9]); + device.data.cues[cueIndex].repeat = itemParts[10]; + device.data.cues[cueIndex].loop = itemParts[11]; + device.draw(); + + if (cueIndex < device.data.cues.length - 1) { + device.send(Buffer.from(`/_cue/getitemsn ${cueIndex + 2} QNTCLSPARZ`)); + } else { + // console.log('done loading cue items'); + device.send(Buffer.from(`/_cue/getpage ${device.data.cues[0].label}`)); + } + } else { + console.error('bad response from getitems'); + } + } else if (messagePath === '/_status') { + const status = parseInt(msg.split(' ')[1].trim(), 10); + console.log(`status: ${status}`); + } else { + console.error(`unhandled message path: ${messagePath}`); + } +}; + +function sanitizeSCSString(string) { + return string.substring(1, string.length - 1); +} + +function millisToString(duration) { + const milliseconds = parseInt(duration % 1000, 10); + let seconds = parseInt((duration / 1000) % 60, 10); + const minutes = parseInt((duration / (1000 * 60)) % 60, 10); + + if (minutes === 0) { + return `${seconds}.${milliseconds}`; + } + if (seconds === 0) { + return `0.${milliseconds}`; + } + if (seconds < 10) { + seconds = `0${seconds}`; + } + return `${minutes}:${seconds}.${milliseconds}`; +} + +exports.heartbeat = function heartbeat(device) {}; diff --git a/plugins/scs/styles.css b/plugins/scs/styles.css new file mode 100644 index 0000000..35b357a --- /dev/null +++ b/plugins/scs/styles.css @@ -0,0 +1,12 @@ +table { + background: white; +} + +th { + text-align: left; + font-weight: normal; +} + +.header-row { + background: white; +} diff --git a/plugins/scs/template.ejs b/plugins/scs/template.ejs new file mode 100644 index 0000000..0d4ac32 --- /dev/null +++ b/plugins/scs/template.ejs @@ -0,0 +1,25 @@ +
+

<%= listName %>

+
+ + + + + + + + + + + <% data.cues.forEach((cue)=>{ %> + + + + + + + + + + <% }) %> +
LabelPageDescriptionCue TypeStateActivationLength
<%=cue.label%><%=cue.page%><%=cue.description%><%=cue.type.display%><%=cue.state%><%=cue.activation%><%=cue.length%>
\ No newline at end of file From b72bc7584e1cdfdcc40db52d5024c148f830db52 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sun, 19 Feb 2023 16:45:49 -0600 Subject: [PATCH 2/9] add padding around cells --- plugins/scs/styles.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/scs/styles.css b/plugins/scs/styles.css index 35b357a..e0b94ac 100644 --- a/plugins/scs/styles.css +++ b/plugins/scs/styles.css @@ -10,3 +10,8 @@ th { .header-row { background: white; } + +td { + padding-left: 5px; + padding-right: 5px; +} From ecc82882232a13eeed2bad382b0278e0d6c5e946 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sun, 19 Feb 2023 16:46:07 -0600 Subject: [PATCH 3/9] add activation displaying --- plugins/scs/main.js | 24 ++++++++++++++++++++++-- plugins/scs/template.ejs | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/plugins/scs/main.js b/plugins/scs/main.js index 638a545..ff8712e 100644 --- a/plugins/scs/main.js +++ b/plugins/scs/main.js @@ -44,6 +44,23 @@ const versionMap = { 50: 'PLAT', }; +const activationMap = { + man: 'Manual', + 'm+c': 'Manual w/ Confirmation', + auto: 'Auto-start', + 'a+c': 'Auto-start w/ Confirmation', + callq: 'Call Cue', + hot: 'Hotkey (Trigger)', + hktg: 'Hotkey (Toggle)', + hknt: 'Hotkey (Note)', + time: 'Time-Based', + ext: 'External (Trigger)', + extg: 'External (Toggle)', + exnt: 'External (Note)', + mtc: 'MIDI Time Code', + ocm: 'On Cue Marker', +}; + exports.ready = function ready(_device) { const device = _device; console.log('Show Cue Systems ready'); @@ -82,7 +99,7 @@ exports.data = function data(_device, message) { description: '', type: { code: '', display: '' }, state: '', - activation: '', + activation: { code: '', display: '' }, file_info: '', length: '', colors: ['', ''], @@ -141,7 +158,10 @@ exports.data = function data(_device, message) { device.data.cues[cueIndex].length = millisToString(itemParts[6]); device.data.cues[cueIndex].state = itemParts[7]; device.data.cues[cueIndex].position = itemParts[8]; - device.data.cues[cueIndex].activation = sanitizeSCSString(itemParts[9]); + device.data.cues[cueIndex].activation = { + code: sanitizeSCSString(itemParts[9]), + display: activationMap[sanitizeSCSString(itemParts[9])], + }; device.data.cues[cueIndex].repeat = itemParts[10]; device.data.cues[cueIndex].loop = itemParts[11]; device.draw(); diff --git a/plugins/scs/template.ejs b/plugins/scs/template.ejs index 0d4ac32..d00d628 100644 --- a/plugins/scs/template.ejs +++ b/plugins/scs/template.ejs @@ -18,7 +18,7 @@ <%=cue.description%> <%=cue.type.display%> <%=cue.state%> - <%=cue.activation%> + <%=cue.activation.display%> <%=cue.length%> <% }) %> From ab66f3056829ea63c11028d618acc9518c6d576d Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Mon, 1 Apr 2024 22:44:25 -0500 Subject: [PATCH 4/9] add ability for osc plugins to specify slip encoding --- src/device.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/device.js b/src/device.js index bd48864..14f6cd9 100644 --- a/src/device.js +++ b/src/device.js @@ -122,6 +122,7 @@ function initDeviceConnection(id) { device.connection = new osc.TCPSocketPort({ address: device.addresses[0], port: device.remotePort, + useSLIP: plugins[type].config.useSLIP !== undefined ? plugins[type].config.useSLIP : true }); } device.connection.open(); From 3e85a1136bff0a240e22fba1d14fec57a73c81fa Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Mon, 1 Apr 2024 23:33:03 -0500 Subject: [PATCH 5/9] start conversion of SCS to OSC --- plugins/scs/main.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/scs/main.js b/plugins/scs/main.js index ff8712e..e59905d 100644 --- a/plugins/scs/main.js +++ b/plugins/scs/main.js @@ -1,15 +1,16 @@ exports.config = { defaultName: 'Show Cue Systems', - connectionType: 'TCPsocket', - defaultPort: 58000, + connectionType: 'osc', + useSLIP: false, + defaultPort: 58100, mayChangePort: true, heartbeatInterval: 5000, searchOptions: { type: 'TCPport', - searchBuffer: Buffer.from('/_status', 'ascii'), - testPort: 58000, + searchBuffer: Buffer.from('/status', 'ascii'), + testPort: 58100, validateResponse(msg, info) { - return msg.toString().includes('/_status'); + return msg.toString().includes('/status'); }, }, fields: [], @@ -65,7 +66,7 @@ exports.ready = function ready(_device) { const device = _device; console.log('Show Cue Systems ready'); device.data.cues = []; - device.send(Buffer.from('/_prod/gettitle')); + device.send('/prod/gettitle'); }; exports.data = function data(_device, message) { From b1a58ec7fd47c54ac25e1816a4cfa35e20ebf80e Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Wed, 3 Apr 2024 12:09:44 -0500 Subject: [PATCH 6/9] convert to new osc interface --- plugins/scs/main.js | 165 ++++++++++++++++++++++++--------------- plugins/scs/template.ejs | 13 ++- 2 files changed, 115 insertions(+), 63 deletions(-) diff --git a/plugins/scs/main.js b/plugins/scs/main.js index e59905d..4d335d0 100644 --- a/plugins/scs/main.js +++ b/plugins/scs/main.js @@ -3,7 +3,7 @@ exports.config = { connectionType: 'osc', useSLIP: false, defaultPort: 58100, - mayChangePort: true, + mayChangePorts: true, heartbeatInterval: 5000, searchOptions: { type: 'TCPport', @@ -62,25 +62,33 @@ const activationMap = { ocm: 'On Cue Marker', }; +const stateMap = { + 0: 'Ready', + 1: 'Playing', + 2: 'Paused', + 3: 'Completed', +}; + exports.ready = function ready(_device) { const device = _device; console.log('Show Cue Systems ready'); device.data.cues = []; + device.data.initialized = false; device.send('/prod/gettitle'); }; -exports.data = function data(_device, message) { +exports.data = function data(_device, oscData) { const device = _device; this.deviceInfoUpdate(device, 'status', 'ok'); - const msg = message.toString(); - const messagePath = msg.substring(0, msg.indexOf(' ')); - if (messagePath === '/_prod/gettitle') { - const title = msg.replace(messagePath, '').replaceAll('"', '').trim(); + console.log(oscData); + const messagePath = oscData.address; + if (messagePath === '/prod/gettitle') { + const title = oscData.args[0].replaceAll('"', '').trim(); this.deviceInfoUpdate(device, 'defaultName', title); - device.send(Buffer.from('/_info/scsversion')); - } else if (messagePath === '/_info/scsversion') { - const versionInfo = msg.replace(messagePath, '').trim().split(' '); - const versionNumber = versionInfo[0]; + device.send('/info/scsversion'); + } else if (messagePath === '/info/scsversion') { + const versionInfo = oscData.args; + const versionNumber = versionInfo[0].toString(); const versionMajor = versionNumber.substring(0, 2).replace('0', ''); const versionMinor = versionNumber.substring(2, 4).replace('0', ''); const versionPatch = versionNumber.substring(4, 6).replace('0', ''); @@ -91,49 +99,57 @@ exports.data = function data(_device, message) { number: versionString, type: versionType, }; - device.send(Buffer.from('/_info/finalcue', 'ascii')); - } else if (messagePath === '/_info/finalcue') { - const cueCount = parseInt(msg.replace(messagePath, '').trim(), 10); - device.data.cues = new Array(cueCount).fill(0).map(() => ({ - label: '', - page: '', - description: '', - type: { code: '', display: '' }, - state: '', - activation: { code: '', display: '' }, - file_info: '', - length: '', - colors: ['', ''], - })); - device.send(Buffer.from(`/_cue/getitemsn 1 QNTCLSPARZ`)); - } else if (messagePath === '/_info/getcue') { - const cueLabelInfo = msg.replace(messagePath, '').trim().split(' '); - const cueNumber = parseInt(cueLabelInfo[0], 10); + device.send('/info/finalcue'); + } else if (messagePath === '/info/finalcue') { + const cueCount = oscData.args[0]; + if (cueCount !== device.data.cues.length) { + device.data.initialized = false; + device.data.cues = new Array(cueCount).fill(0).map(() => ({ + label: '', + page: '', + description: '', + type: { code: '', display: '' }, + state: '', + activation: { code: '', display: '' }, + file_info: '', + length: '', + colors: ['', ''], + })); + device.send('/cue/getitemsn', [ + { type: 'i', value: 1 }, + { type: 's', value: 'QNTCLSPARZ' }, + ]); + } + } else if (messagePath === '/info/getcue') { + const cueLabelInfo = oscData.args; + const cueNumber = cueLabelInfo[0]; const cueLabel = cueLabelInfo[1].replaceAll('"', ''); device.data.cues[cueNumber - 1].label = cueLabel; device.draw(); - } else if (messagePath === '/_cue/getpage') { - const pageInfo = msg.replace(messagePath, '').trim().match(/".*?"/g); + } else if (messagePath === '/cue/getpage') { + const pageInfo = oscData.args; const cueLabel = pageInfo[0].replaceAll('"', ''); const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); device.data.cues[cueIndex].page = pageInfo[1].replaceAll('"', ''); + console.log(`cue index ${cueIndex}`); if (cueIndex < device.data.cues.length - 1) { - device.send(Buffer.from(`/_cue/getpage ${device.data.cues[cueIndex + 1].label}`)); + device.send('/cue/getpage', [{ type: 's', value: device.data.cues[cueIndex + 1].label }]); } else { // console.log('done loading cue pages'); device.draw(); - device.send(Buffer.from('/_status')); + device.data.initialized = true; + device.send('/status'); } - } else if (messagePath === '/_cue/getname') { - const nameInfo = msg.replace(messagePath, '').trim().match(/".*?"/g); + } else if (messagePath === '/cue/getname') { + const nameInfo = oscData.args; const cueLabel = nameInfo[0].replaceAll('"', ''); const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); device.data.cues[cueIndex].description = nameInfo[1].replaceAll('"', ''); device.draw(); - } else if (messagePath === '/_cue/gettype') { - const typeInfo = msg.replace(messagePath, '').trim().match(/".*?"/g); + } else if (messagePath === '/cue/gettype') { + const typeInfo = oscData.args; const cueLabel = typeInfo[0].replaceAll('"', ''); const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); @@ -142,52 +158,77 @@ exports.data = function data(_device, message) { display: typeMap[typeInfo[1].replaceAll('"', '')], }; device.draw(); - } else if (messagePath === '/_cue/getitemsn') { - const itemParts = msg - .replace(messagePath, '') - .trim('') - .match(/".*?"|\d+/g); + } else if (messagePath === '/cue/getitemsn') { + const itemParts = oscData.args; if (itemParts.length === 12) { const cueIndex = itemParts[0] - 1; - device.data.cues[cueIndex].label = sanitizeSCSString(itemParts[2]); - device.data.cues[cueIndex].description = sanitizeSCSString(itemParts[3]); + device.data.cues[cueIndex].label = itemParts[2]; + device.data.cues[cueIndex].description = itemParts[3]; device.data.cues[cueIndex].type = { - code: sanitizeSCSString(itemParts[4]), - display: typeMap[sanitizeSCSString(itemParts[4])], + code: itemParts[4], + display: typeMap[itemParts[4]], }; - device.data.cues[cueIndex].colors = sanitizeSCSString(itemParts[5]).split(', '); + device.data.cues[cueIndex].colors = itemParts[5].split(', '); device.data.cues[cueIndex].length = millisToString(itemParts[6]); - device.data.cues[cueIndex].state = itemParts[7]; + device.data.cues[cueIndex].state = stateMap[itemParts[7]]; device.data.cues[cueIndex].position = itemParts[8]; device.data.cues[cueIndex].activation = { - code: sanitizeSCSString(itemParts[9]), - display: activationMap[sanitizeSCSString(itemParts[9])], + code: itemParts[9], + display: activationMap[itemParts[9]], }; device.data.cues[cueIndex].repeat = itemParts[10]; device.data.cues[cueIndex].loop = itemParts[11]; device.draw(); - if (cueIndex < device.data.cues.length - 1) { - device.send(Buffer.from(`/_cue/getitemsn ${cueIndex + 2} QNTCLSPARZ`)); - } else { - // console.log('done loading cue items'); - device.send(Buffer.from(`/_cue/getpage ${device.data.cues[0].label}`)); + if (!device.data.initialized) { + console.log(`cueIndex: ${cueIndex} cue count: ${device.data.cues.length}`); + if (cueIndex < device.data.cues.length - 1) { + console.log(`loading next cue ${cueIndex + 2}`); + device.send('/cue/getitemsn', [ + { type: 'i', value: cueIndex + 2 }, + { type: 's', value: 'QNTCLSPARZ' }, + ]); + } else { + console.log('done loading cue items'); + device.send('/cue/getpage', [{ type: 's', value: device.data.cues[0].label }]); + } } } else { console.error('bad response from getitems'); } - } else if (messagePath === '/_status') { - const status = parseInt(msg.split(' ')[1].trim(), 10); + } else if (messagePath === '/cue/statechange') { + const cueLabel = oscData.args[0]; + const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); + if (cueIndex !== undefined) { + device.data.cues[cueIndex].state = stateMap[oscData.args[1]]; + device.draw(); + device.send('/cue/getitemsn', [ + { type: 'i', value: cueIndex + 1 }, + { type: 's', value: 'QNTCLSPARZ' }, + ]); + } + } else if (messagePath === '/status') { + const status = oscData.args[0]; console.log(`status: ${status}`); + device.send('/info/currcue'); + } else if (messagePath === '/connected') { + device.send('/prod/gettitle'); + } else if (messagePath === '/info/currcue') { + device.data.currentCue = oscData.args[0]; + device.draw(); + } else if (messagePath === '/info/nextcue') { + device.data.nextCue = oscData.args[0]; + device.draw(); + device.data.initialized = false; + device.send('/cue/getitemsn', [ + { type: 'i', value: 1 }, + { type: 's', value: 'QNTCLSPARZ' }, + ]); } else { console.error(`unhandled message path: ${messagePath}`); } }; -function sanitizeSCSString(string) { - return string.substring(1, string.length - 1); -} - function millisToString(duration) { const milliseconds = parseInt(duration % 1000, 10); let seconds = parseInt((duration / 1000) % 60, 10); @@ -205,4 +246,6 @@ function millisToString(duration) { return `${minutes}:${seconds}.${milliseconds}`; } -exports.heartbeat = function heartbeat(device) {}; +exports.heartbeat = function heartbeat(device) { + device.send('/info/finalcue'); +}; diff --git a/plugins/scs/template.ejs b/plugins/scs/template.ejs index d00d628..f090df8 100644 --- a/plugins/scs/template.ejs +++ b/plugins/scs/template.ejs @@ -11,8 +11,17 @@ Activation Length - <% data.cues.forEach((cue)=>{ %> - + <% data.cues.forEach((cue, index )=>{ %> + + <% if (data.currentCue === index + 1){ %> + + <%} else if (index + 1 < data.currentCue){ %> + + <%} else{ %> + + <% } %> + + <%=cue.label%> <%=cue.page%> <%=cue.description%> From 011ace07cdfb357b11ac47b438cacf5574dc33a0 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 5 Apr 2024 21:21:38 -0500 Subject: [PATCH 7/9] cleanup console logging --- plugins/scs/main.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/scs/main.js b/plugins/scs/main.js index 4d335d0..7bf1ba2 100644 --- a/plugins/scs/main.js +++ b/plugins/scs/main.js @@ -71,7 +71,6 @@ const stateMap = { exports.ready = function ready(_device) { const device = _device; - console.log('Show Cue Systems ready'); device.data.cues = []; device.data.initialized = false; device.send('/prod/gettitle'); @@ -80,7 +79,6 @@ exports.ready = function ready(_device) { exports.data = function data(_device, oscData) { const device = _device; this.deviceInfoUpdate(device, 'status', 'ok'); - console.log(oscData); const messagePath = oscData.address; if (messagePath === '/prod/gettitle') { const title = oscData.args[0].replaceAll('"', '').trim(); @@ -132,11 +130,9 @@ exports.data = function data(_device, oscData) { const cueLabel = pageInfo[0].replaceAll('"', ''); const cueIndex = device.data.cues.map((cue) => cue.label).indexOf(cueLabel); device.data.cues[cueIndex].page = pageInfo[1].replaceAll('"', ''); - console.log(`cue index ${cueIndex}`); if (cueIndex < device.data.cues.length - 1) { device.send('/cue/getpage', [{ type: 's', value: device.data.cues[cueIndex + 1].label }]); } else { - // console.log('done loading cue pages'); device.draw(); device.data.initialized = true; device.send('/status'); @@ -181,15 +177,12 @@ exports.data = function data(_device, oscData) { device.draw(); if (!device.data.initialized) { - console.log(`cueIndex: ${cueIndex} cue count: ${device.data.cues.length}`); if (cueIndex < device.data.cues.length - 1) { - console.log(`loading next cue ${cueIndex + 2}`); device.send('/cue/getitemsn', [ { type: 'i', value: cueIndex + 2 }, { type: 's', value: 'QNTCLSPARZ' }, ]); } else { - console.log('done loading cue items'); device.send('/cue/getpage', [{ type: 's', value: device.data.cues[0].label }]); } } @@ -209,7 +202,6 @@ exports.data = function data(_device, oscData) { } } else if (messagePath === '/status') { const status = oscData.args[0]; - console.log(`status: ${status}`); device.send('/info/currcue'); } else if (messagePath === '/connected') { device.send('/prod/gettitle'); From e4495229e445398a5c66fbb35c7fc15452a5d035 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 5 Apr 2024 21:24:58 -0500 Subject: [PATCH 8/9] cleanup --- plugins/scs/info.html | 1 + plugins/scs/main.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/scs/info.html b/plugins/scs/info.html index 9863b00..d59d189 100644 --- a/plugins/scs/info.html +++ b/plugins/scs/info.html @@ -1,4 +1,5 @@

Connection Requirements

    +
  • Remote App must be set to OSC App under Remote App Interface settings
  • Network Protocol must be set to TCP under Remote App Interface settings
diff --git a/plugins/scs/main.js b/plugins/scs/main.js index 7bf1ba2..bdd39ea 100644 --- a/plugins/scs/main.js +++ b/plugins/scs/main.js @@ -201,7 +201,7 @@ exports.data = function data(_device, oscData) { ]); } } else if (messagePath === '/status') { - const status = oscData.args[0]; + // const status = oscData.args[0]; device.send('/info/currcue'); } else if (messagePath === '/connected') { device.send('/prod/gettitle'); From 317c370e05b3293d8efbe0a6a4190f8a7ecaa994 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Tue, 17 Sep 2024 21:32:34 -0500 Subject: [PATCH 9/9] SCS is starting to implement proper OSC --- plugins/scs/info.html | 1 + plugins/scs/main.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scs/info.html b/plugins/scs/info.html index d59d189..8197996 100644 --- a/plugins/scs/info.html +++ b/plugins/scs/info.html @@ -2,4 +2,5 @@

Connection Requirements

  • Remote App must be set to OSC App under Remote App Interface settings
  • Network Protocol must be set to TCP under Remote App Interface settings
  • +
  • OSC Version must be set to 1.1 under Remote App Interface settings
diff --git a/plugins/scs/main.js b/plugins/scs/main.js index bdd39ea..d7db126 100644 --- a/plugins/scs/main.js +++ b/plugins/scs/main.js @@ -1,7 +1,6 @@ exports.config = { defaultName: 'Show Cue Systems', connectionType: 'osc', - useSLIP: false, defaultPort: 58100, mayChangePorts: true, heartbeatInterval: 5000,