"+prettyFormatTime(Math.min(def, value))+"`;
}else if(type=="postWait" || type=="action"){
- return "
"+prettyFormatTime(def)+"";
+ return `
${prettyFormatTime(def)}`;
}else{
return prettyFormatTime(def);
diff --git a/plugins/qlab/info.html b/plugins/qlab/info.html
new file mode 100644
index 0000000..5ca65d1
--- /dev/null
+++ b/plugins/qlab/info.html
@@ -0,0 +1,4 @@
+
Connection Requirements
+
\ No newline at end of file
diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js
index 8009d8b..c70f689 100644
--- a/plugins/qlab/main.js
+++ b/plugins/qlab/main.js
@@ -1,4 +1,4 @@
-let _ = require('lodash');
+const _ = require('lodash');
const fs = require('fs');
let lastElapsedUpdate = Date.now();
@@ -12,66 +12,62 @@ exports.searchOptions = {
bonjourName: 'qlab',
};
-exports.ready = function (device) {
+exports.ready = function ready(device) {
device.send(`/version`);
device.send('/workspaces');
};
-exports.data = function (device, oscData) {
- const address = oscData.address;
- let osc = oscData.address.split('/');
+exports.data = function data(device, oscData) {
+ const osc = oscData.address.split('/');
osc.shift();
-
- let data;
+ const d = device;
- //console.log(address)
+ // console.log(oscData.address)
if(match(osc, ["reply", "version"])){
- let json = JSON.parse(oscData.args[0]);
- device.data.version = json.data;
+ const json = JSON.parse(oscData.args[0]);
+ d.data.version = json.data;
- this.deviceInfoUpdate(device, 'status', 'ok');
+ this.deviceInfoUpdate(d, 'status', 'ok');
}else if(match(osc, ["reply", "workspaces"])){
- let json = JSON.parse(oscData.args[0]);
- device.data.workspaces = {};
+ const json = JSON.parse(oscData.args[0]);
+ d.data.workspaces = {};
json.data.forEach(wksp => {
- device.data.workspaces[wksp.uniqueID] = {
+ d.data.workspaces[wksp.uniqueID] = {
uniqueID: wksp.uniqueID,
displayName: wksp.displayName,
cueLists: {},
cues: {}
}
- device.send(`/workspace/${wksp.uniqueID}/connect`);
+ d.send(`/workspace/${wksp.uniqueID}/connect`);
});
- console.log(device.data.workspaces);
-
}else if(match(osc, ["reply", "workspace", "*", "connect"])){
- device.send(`/workspace/${osc[2]}/updates`, [
+ d.send(`/workspace/${osc[2]}/updates`, [
{ type: 'i', value: 1 },
]);
- device.send(`/workspace/${osc[2]}/cueLists`);
+ d.send(`/workspace/${osc[2]}/cueLists`);
}else if(match(osc, ["reply", "workspace", "*", "cueLists"])){
- this.deviceInfoUpdate(device, 'status', 'ok');
+ this.deviceInfoUpdate(d, 'status', 'ok');
- let workspace = device.data.workspaces[osc[2]];
- let json = JSON.parse(oscData.args[0]);
+ const workspace = d.data.workspaces[osc[2]];
+ const json = JSON.parse(oscData.args[0]);
workspace.cueLists = {};
workspace.cues = {};
@@ -82,13 +78,13 @@ exports.data = function (device, oscData) {
addChildrenToWorkspace(workspace, ql);
});
- device.draw();
+ d.draw();
- setTimeout(function(){
+ setTimeout(() => {
json.data.forEach(ql => {
workspace.cueLists[ql.uniqueID] = ql;
- getValuesForKeys(device, json.workspace_id, ql);
+ getValuesForKeys(d, json.workspace_id, ql);
});
}, 0);
@@ -96,31 +92,32 @@ exports.data = function (device, oscData) {
}else if(match(osc, ["reply", "cue_id", "*", "children"])){
- let json = JSON.parse(oscData.args[0]);
- let workspace = device.data.workspaces[json.workspace_id];
- let cue_id = osc[2];
- let cue = workspace.cues[cue_id];
+ const json = JSON.parse(oscData.args[0]);
+ const workspace = d.data.workspaces[json.workspace_id];
+ const cueID = osc[2];
+ const cue = workspace.cues[cueID];
if(!_.isEqual(cue.cues, json.data)){
- workspace.cueLists[cue_id].cues = json.data;
- addChildrenToWorkspace(workspace, workspace.cueLists[cue_id]);
+ workspace.cueLists[cueID].cues = json.data;
+ addChildrenToWorkspace(workspace, workspace.cueLists[cueID]);
- device.draw();
+ d.draw();
- getValuesForKeys(device, json.workspace_id, cue);
+ getValuesForKeys(d, json.workspace_id, cue);
}
}else if(match(osc, ["reply", "cue_id", "*", "valuesForKeys"])){
- let json = JSON.parse(oscData.args[0]);
- let cueValues = json.data;
+ const json = JSON.parse(oscData.args[0]);
+ const cueValues = json.data;
- let workspace = device.data.workspaces[json.workspace_id];
+ const workspace = d.data.workspaces[json.workspace_id];
let cue = workspace.cues[cueValues.uniqueID];
if(!cue){
- cue = workspace.cues[cueValues.uniqueID] = {};
+ workspace.cues[cueValues.uniqueID] = {};
+ cue = workspace.cues[cueValues.uniqueID];
}
cue.uniqueID = cueValues.uniqueID;
@@ -149,15 +146,15 @@ exports.data = function (device, oscData) {
cue.actionElapsed = cueValues.actionElapsed;
cue.postWaitElapsed = cueValues.postWaitElapsed;
- let nestedGroupModes = [];
- let nestedGroupPosition = [0];
- var obj = cue;
+ const nestedGroupModes = [];
+ const nestedGroupPosition = [0];
+ let obj = cue;
- while(obj.parent!="[root group of cue lists]"){
+ while(obj.parent !== "[root group of cue lists]"){
nestedGroupModes.push(obj.groupMode);
let pos = _.findIndex(workspace.cues[obj.parent].cues, {uniqueID: obj.uniqueID});
- pos= Math.abs(pos-workspace.cues[obj.parent].cues.length)-1;
+ pos = Math.abs(pos - workspace.cues[obj.parent].cues.length) - 1;
nestedGroupPosition.push(pos)
obj = workspace.cues[obj.parent];
@@ -165,61 +162,61 @@ exports.data = function (device, oscData) {
cue.nestedGroupModes = nestedGroupModes;
cue.nestedGroupPosition = nestedGroupPosition;
- //console.log("draw "+cue.number)
+ // console.log("draw "+cue.number)
- device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace});
+ d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
}else if(match(osc, ["reply", "cue_id", "*", "preWaitElapsed"])){
- let json = JSON.parse(oscData.args[0]);
- let workspace = device.data.workspaces[json.workspace_id];
- let cue = workspace.cues[osc[2]];
+ const json = JSON.parse(oscData.args[0]);
+ const workspace = d.data.workspaces[json.workspace_id];
+ const cue = workspace.cues[osc[2]];
cue.preWaitElapsed = json.data;
lastElapsedUpdate = Date.now();
- device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace});
+ d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
}else if(match(osc, ["reply", "cue_id", "*", "actionElapsed"])){
- let json = JSON.parse(oscData.args[0]);
- let workspace = device.data.workspaces[json.workspace_id];
- let cue = workspace.cues[osc[2]];
+ const json = JSON.parse(oscData.args[0]);
+ const workspace = d.data.workspaces[json.workspace_id];
+ const cue = workspace.cues[osc[2]];
cue.actionElapsed = json.data;
lastElapsedUpdate = Date.now();
- device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace});
+ d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
}else if(match(osc, ["reply", "cue_id", "*", "postWaitElapsed"])){
- let json = JSON.parse(oscData.args[0]);
- let workspace = device.data.workspaces[json.workspace_id];
- let cue = workspace.cues[osc[2]];
+ const json = JSON.parse(oscData.args[0]);
+ const workspace = device.data.workspaces[json.workspace_id];
+ const cue = workspace.cues[osc[2]];
cue.postWaitElapsed = json.data;
lastElapsedUpdate = Date.now();
- device.update("updateCueData", {cue: cue, allCues: workspace.cues, workspace: workspace});
+ d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
}else if(match(osc, ["update", "workspace", "*", "cue_id", "*"])){
- let workspace = device.data.workspaces[osc[2]];
+ const workspace = d.data.workspaces[osc[2]];
if(workspace){
- let cueLists = Object.keys(workspace.cueLists);
- let cue_id = osc[4];
+ const cueLists = Object.keys(workspace.cueLists);
+ const cueID = osc[4];
- if(cue_id!="[root group of cue lists"){
- if(cueLists.includes(cue_id)){
- device.send(`/workspace/${workspace.uniqueID}/cue_id/${cue_id}/children`);
+ if(cueID !== "[root group of cue lists"){
+ if(cueLists.includes(cueID)){
+ d.send(`/workspace/${workspace.uniqueID}/cue_id/${cueID}/children`);
}
- device.send(`/workspace/${osc[2]}/cue_id/${cue_id}/valuesForKeys`, [
+ d.send(`/workspace/${osc[2]}/cue_id/${cueID}/valuesForKeys`, [
{type: 's', value: valuesForKeysString}
]);
@@ -229,40 +226,40 @@ exports.data = function (device, oscData) {
}else if(match(osc, ["update", "workspace", "*"])){
// occurs when cue lists are reordered or a list is deleted
- device.send(`/workspace/${osc[2]}/cueLists`);
+ d.send(`/workspace/${osc[2]}/cueLists`);
}else if(match(osc, ["update", "workspace", "*", "dashboard"])){
- //this workspace might be new, let's check
-
- if(device.data.workspaces[osc[2]]){
+ // this workspace might be new, let's check
+ if(d.data.workspaces[osc[2]]){
+ //
}else{
console.log("new workspace!");
- device.send('/workspaces');
+ d.send('/workspaces');
}
}else if(match(osc, ["update", "workspace", "*", "cueList", "*", "playbackPosition"])){
- let workspace = device.data.workspaces[osc[2]];
+ const workspace = d.data.workspaces[osc[2]];
if(workspace){
- let cue = workspace.cues[oscData.args[0]];
+ const cue = workspace.cues[oscData.args[0]];
if(cue){
workspace.playbackPosition = oscData.args[0] ? cue.uniqueID : "";
- device.update("updatePlaybackPosition", {cue: cue});
+ d.update("updatePlaybackPosition", {'cue': cue});
}
}
}else if(match(osc, ["update", "workspace", "*", "disconnect"])){
- delete device.data.workspaces[osc[2]];
- device.draw();
+ delete d.data.workspaces[osc[2]];
+ d.draw();
}else{
- //console.log(address)
+ // console.log(address)
}
@@ -270,25 +267,24 @@ exports.data = function (device, oscData) {
};
-let cueTemplate = _.template(fs.readFileSync(`./plugins/qlab/cue.ejs`));
-let tileTemplate = _.template(fs.readFileSync(`./plugins/qlab/tile.ejs`));
-let cartTemplate = _.template(fs.readFileSync(`./plugins/qlab/cart.ejs`));
-let listTemplate = _.template(fs.readFileSync(`./plugins/qlab/cuelist.ejs`));
+const cueTemplate = _.template(fs.readFileSync(`./plugins/qlab/cue.ejs`));
+const tileTemplate = _.template(fs.readFileSync(`./plugins/qlab/tile.ejs`));
+const cartTemplate = _.template(fs.readFileSync(`./plugins/qlab/cart.ejs`));
-exports.update = function(device, doc, updateType, data){
+exports.update = function update(device, doc, updateType, data){
- if(updateType=="updateCueData"){
- $elem = doc.getElementById(data.cue.uniqueID);
+ if(updateType === "updateCueData"){
+ const $elem = doc.getElementById(data.cue.uniqueID);
if($elem){
- if(data.cue.type=="Cue List"){
- $elem.outerHTML = '
'+data.workspace.displayName+' — '+data.cue.name+'
';
+ if(data.cue.type === "Cue List"){
+ $elem.outerHTML = `
${data.workspace.displayName} — ${data.cue.name}
`;
- }else if(data.cue.type=="Cart"){
- $elem.outerHTML = cartTemplate({tileTemplate: tileTemplate, cueList: data.cue, allCues: data.workspace.cues});
+ }else if(data.cue.type === "Cart"){
+ $elem.outerHTML = cartTemplate({'tileTemplate': tileTemplate, 'cueList': data.cue, 'allCues': data.workspace.cues});
- }else if(data.cue.cartPosition && data.cue.cartPosition[0]!=0){
+ }else if(data.cue.cartPosition && data.cue.cartPosition[0] !== 0){
$elem.outerHTML = tileTemplate(data);
}else{
@@ -296,13 +292,13 @@ exports.update = function(device, doc, updateType, data){
}
}
- }else if(updateType=="updatePlaybackPosition"){
+ }else if(updateType === "updatePlaybackPosition"){
Array.from(doc.getElementsByClassName("playback-position")).forEach(
- function($elem, index, array) {
+ ($elem, index, array) => {
$elem.classList.remove("playback-position");
});
- $elem = doc.getElementById(data.cue.uniqueID);
+ const $elem = doc.getElementById(data.cue.uniqueID);
$elem.classList.add("playback-position");
$elem.scrollIntoView({behavior: "smooth", block: "center"});
@@ -319,30 +315,31 @@ exports.update = function(device, doc, updateType, data){
const valuesForKeysString =
'["uniqueID","number","name","listName","isBroken","isRunning","isLoaded","isFlagged",'
-+'"type","children","preWait","postWait","currentDuration","colorName","continueMode",'
-+'"mode","parent","cartRows","cartColumns","cartPosition","displayName","preWaitElapsed",'
-+'"actionElapsed","postWaitElapsed","isPaused"]';
++ '"type","children","preWait","postWait","currentDuration","colorName","continueMode",'
++ '"mode","parent","cartRows","cartColumns","cartPosition","displayName","preWaitElapsed",'
++ '"actionElapsed","postWaitElapsed","isPaused"]';
function addChildrenToWorkspace(workspace, q){
- workspace.cues[q.uniqueID] = q;
- workspace.cues[q.uniqueID].nestedGroupModes = [];
- workspace.cues[q.uniqueID].nestedGroupPosition = [];
+ const w = workspace;
+ w.cues[q.uniqueID] = q;
+ w.cues[q.uniqueID].nestedGroupModes = [];
+ w.cues[q.uniqueID].nestedGroupPosition = [];
if(q.cues){
- q.cues.forEach(q => {
- addChildrenToWorkspace(workspace, q);
+ q.cues.forEach(cue => {
+ addChildrenToWorkspace(w, cue);
});
}
}
-function getValuesForKeys(device, workspace_id, q){
- device.send(`/workspace/${workspace_id}/cue_id/${q.uniqueID}/valuesForKeys`, [
+function getValuesForKeys(device, workspaceID, q){
+ device.send(`/workspace/${workspaceID}/cue_id/${q.uniqueID}/valuesForKeys`, [
{type: 's', value: valuesForKeysString}
]);
if(q.cues){
- q.cues.forEach(q => {
- getValuesForKeys(device, workspace_id, q);
+ q.cues.forEach(cue => {
+ getValuesForKeys(device, workspaceID, cue);
});
}
}
@@ -350,11 +347,11 @@ function getValuesForKeys(device, workspace_id, q){
function match(osc, array){
let out = true;
- if(osc.length!=array.length){
+ if(osc.length !== array.length){
return false;
}
- array.forEach((match, i)=> {
- if(osc[i]!=match && match!="*"){
+ array.forEach((m, i)=> {
+ if(osc[i] !== m && m !== "*"){
out = false;
}
});
@@ -363,16 +360,16 @@ function match(osc, array){
let interval = 5;
let heartbeatCount = 0;
-exports.heartbeat = function (device) {
+exports.heartbeat = function heartbeat(device) {
heartbeatCount++;
- if(Date.now()-lastElapsedUpdate>300){
+ if(Date.now() - lastElapsedUpdate > 300){
interval = 5;
}else{
interval = 1;
}
- if(heartbeatCount%interval==0){
+ if(heartbeatCount % interval === 0){
device.send(`/cue/active/preWaitElapsed`);
device.send(`/cue/active/actionElapsed`);
device.send(`/cue/active/postWaitElapsed`);
diff --git a/plugins/qlab/styles.css b/plugins/qlab/styles.css
index f97bb37..9fc38f0 100644
--- a/plugins/qlab/styles.css
+++ b/plugins/qlab/styles.css
@@ -170,77 +170,73 @@ tr.playback-position .q-gray-text {
color: #424242;
}
.q-time-elapsed {
- margin: 0px 2px;
- outline: #49c042 1px solid;
+ margin: 0px 2px;
+ outline: #49c042 1px solid;
line-height: 18px;
}
-
-
-
-.cart{
+.cart {
position: relative;
- height: 600px;
- width: 100%;
+ height: 600px;
+ width: 100%;
background-color: #2c2b2a;
}
-.cartCueWrapper{
- display: block;
+.cartCueWrapper {
+ display: block;
position: absolute;
box-sizing: border-box;
- padding: 3px;
+ padding: 3px;
}
-.cartCue{
- height: 100%;
+.cartCue {
+ height: 100%;
box-sizing: border-box;
- border: 3px solid;
- border-radius: 6px;
- color: white;
+ border: 3px solid;
+ border-radius: 6px;
+ color: white;
}
-.cartCue p{
- margin: 10px;
+.cartCue p {
+ margin: 10px;
}
-.cartCueIcon{
+.cartCueIcon {
position: absolute;
- right: 13px;
- top: 13px;
+ right: 13px;
+ top: 13px;
}
-.cartColor-red{
- border-color: #ff4242;
- background-color: #9b3726;
+.cartColor-red {
+ border-color: #ff4242;
+ background-color: #9b3726;
}
-.cartColor-orange{
- border-color: #ffa500;
+.cartColor-orange {
+ border-color: #ffa500;
background-color: #ad6026;
}
-.cartColor-green{
- border-color: #01d52f;
+.cartColor-green {
+ border-color: #01d52f;
background-color: #397f27;
}
-.cartColor-blue{
- border-color: #536de0;
+.cartColor-blue {
+ border-color: #536de0;
background-color: #304893;
}
-.cartColor-purple{
- border-color: #a601c0;
+.cartColor-purple {
+ border-color: #a601c0;
background-color: #592d74;
}
-.cartColor-none{
- border-color: #95929f;
- background-color: #3b3b3b
+.cartColor-none {
+ border-color: #95929f;
+ background-color: #3b3b3b;
}
-.cartBlank{
- border-color: #1f1f1f;
+.cartBlank {
+ border-color: #1f1f1f;
background-color: #1f1f1f;
}
-.cartCueWrapper.playback-position .cartCue{
- border-color: #88b3db;
- outline: #88b3db 1px solid;
+.cartCueWrapper.playback-position .cartCue {
+ border-color: #88b3db;
+ outline: #88b3db 1px solid;
box-shadow: 0px 0px 3px 3px #88b3db, inset 0px 0px 5px #88b3db;
}
-
@media screen and (min-width: 0px) and (max-width: 750px) {
.hide-medium {
display: none;
diff --git a/plugins/qlab/tile.ejs b/plugins/qlab/tile.ejs
index 7d8a128..ca8e9e2 100644
--- a/plugins/qlab/tile.ejs
+++ b/plugins/qlab/tile.ejs
@@ -14,26 +14,24 @@
left = (cue.cartPosition[1]-1)*width;
}
+ let style = `style="left:${left}%; top:${top}px; width:${width }%; height:${height}px;"`;
+
%>
-
+
>
-
- <% if(cue.broken){ %>
-

- <% }else if(cue.running){ %>
-

- <% }else{ %>
-

- <% } %>
-
-
-
<%= cue.number %> • <%= cue.displayName %>
-
+
+ <% if(cue.broken){ %>
+

+ <% }else if(cue.running){ %>
+

+ <% }else{ %>
+

+ <% } %>
+
-
\ No newline at end of file
+
+
<%= cue.number %> • <%= cue.displayName %>
+
+
+
\ No newline at end of file
diff --git a/plugins/sacn/icon.png b/plugins/sacn/icon.png
new file mode 100644
index 0000000..ef9783e
Binary files /dev/null and b/plugins/sacn/icon.png differ
diff --git a/plugins/sacn/icon.psd b/plugins/sacn/icon.psd
new file mode 100644
index 0000000..9e2d797
Binary files /dev/null and b/plugins/sacn/icon.psd differ
diff --git a/plugins/sacn/info.html b/plugins/sacn/info.html
new file mode 100644
index 0000000..4e4c755
--- /dev/null
+++ b/plugins/sacn/info.html
@@ -0,0 +1 @@
+
sACN requires no configuration.
\ No newline at end of file
diff --git a/plugins/sacn/main.js b/plugins/sacn/main.js
new file mode 100644
index 0000000..bf9f3a0
--- /dev/null
+++ b/plugins/sacn/main.js
@@ -0,0 +1,158 @@
+const _ = require('lodash');
+
+exports.defaultName = 'sACN Universe';
+exports.connectionType = 'multicast';
+exports.defaultPort = 5568;
+exports.heartbeatInterval = 5000;
+exports.searchOptions = {
+ type: "multicast",
+ address: getMulticastGroup(1),
+ port: 5568,
+ validateResponse (msg, info) {
+ return msg.toString('utf8', 4, 13) === "ASC-E1.17";
+ },
+};
+exports.defaultPort = 5568;
+
+exports.ready = function ready(device) {
+
+ const d = device;
+ d.data.universes = {};
+ d.data.source = "Unknown Source";
+ d.data.orderedUniverses = [];
+
+ // device.draw();
+ for(let i = 1; i <= 16; i++){
+ d.connection.addMembership(getMulticastGroup(i));
+ }
+
+};
+
+
+exports.data = function data(device, buf) {
+
+ const univ = buf.readUInt16BE(113);
+ const d = device;
+
+ let u = d.data.universes[univ];
+
+ if(!u){
+ d.data.universes[univ] = {};
+ u = d.data.universes[univ];
+ }
+
+ u.sequence = buf.readUInt8(111);
+ u.priority = buf.readUInt8(108);
+ u.cid = buf.toString('hex', 22, 38);
+ u.slots = Array.prototype.slice.call(buf, 126);
+ if(buf.readUInt8(125) !== 0){
+ u.startCode = buf.readUInt8(125);
+ }
+
+
+ d.data.source = buf.toString('utf8', 44, 108);
+ d.displayName = `${d.data.source} sACN`;
+ d.data.ip = d.addresses[0];
+
+ if(!_.includes(d.data.orderedUniverses, univ)){
+ d.data.orderedUniverses.push(univ);
+ d.data.orderedUniverses.sort();
+ u.slotElems = [];
+ u.slotElemsSet = false;
+
+ d.draw();
+ updateElementsCache(d, d.data.universes, d.data.orderedUniverses);
+
+ }
+
+ d.update("universeData", {
+ u: univ,
+ universe: u,
+ startCode: u.startCode
+ });
+
+};
+
+
+exports.heartbeat = function heartbeat(device) {
+
+};
+
+
+
+let lastUpdate = Date.now();
+exports.update = function update(device, doc, updateType, updateData){
+
+ const d = device;
+ const data = updateData;
+
+ if(updateType === "universeData" && data.universe){
+
+ if(Date.now() - lastUpdate > 1000){
+ lastUpdate = Date.now();
+ updateElementsCache(d, d.data.universes, d.data.orderedUniverses);
+ }
+
+ const $elem = doc.getElementById(`universe-${data.u}`);
+
+ if($elem && data.universe.slotElemsSet){
+
+ if(data.universe.priority > 0){
+ for(let i = 0; i < 512; i++){
+ data.universe.slotElems[i].innerText = data.universe.slots[i];
+ }
+
+ const $code = doc.getElementById(`universe-${data.u}-code`);
+ if(data.startCode === 0xDD){
+ $code.innerText = "Net3"
+ }else if(data.startCode === 0x17){
+ $code.innerText = "Text"
+ }else if(data.startCode === 0xCF){
+ $code.innerText = "SIP"
+ }else if(data.startCode === 0xCC){
+ $code.innerText = "RDM"
+ }
+
+ }
+
+ }else{
+ d.draw();
+ updateElementsCache(d, d.data.universes, d.data.orderedUniverses);
+ }
+
+ }else if(updateType === "elementCache"){
+
+ data.orderedUniverses.forEach(univ => {
+ for(let i = 0; i < 512; i++){
+ data.universes[univ].slotElems[i] = doc.getElementById(`${univ}-${i}`);
+ }
+ data.universes[univ].slotElemsSet = true;
+ });
+
+ }
+
+
+}
+
+
+function updateElementsCache(device, univ, ordered){
+ device.update("elementCache", {
+ universes: univ,
+ orderedUniverses: ordered
+ });
+}
+
+
+
+
+
+
+
+// From https://github.com/hhromic/e131-node/blob/master/lib/e131.js
+function getMulticastGroup(universe) {
+ if (universe < 1 || universe > 63999) {
+ throw new RangeError('universe should be in the range [1-63999]');
+ }
+ return `239.255.${universe >> 8}.${universe & 0xff}`;
+
+}
\ No newline at end of file
diff --git a/plugins/sacn/styles.css b/plugins/sacn/styles.css
new file mode 100644
index 0000000..47209a9
--- /dev/null
+++ b/plugins/sacn/styles.css
@@ -0,0 +1,29 @@
+table {
+ margin-bottom: 50px;
+ background-color: #333;
+}
+td,
+th {
+ width: 35px;
+}
+td {
+ background-color: black;
+ text-align: center;
+ border-radius: 3px;
+ color: white;
+ font-size: 13px;
+}
+th {
+ background-color: #222;
+ color: #ccc;
+ font-size: 11px;
+}
+td.data {
+ padding: 7px;
+ font-size: 12px;
+ text-align: left;
+}
+td.data em {
+ font-size: 14px;
+ color: #ff0033;
+}
diff --git a/plugins/sacn/template.ejs b/plugins/sacn/template.ejs
new file mode 100644
index 0000000..de4a90a
--- /dev/null
+++ b/plugins/sacn/template.ejs
@@ -0,0 +1,58 @@
+
+ <%= data.source %> sACN (E1.31)
+
+
+
+
+<% data.orderedUniverses.forEach(univ => {
+ let universe = data.universes[univ];
+%>
+
+
+
+
+ Universe
+ <%= univ %>
+ |
+
+ Priority
+ <%= universe.priority %>
+ |
+
+ CID
+ <%= universe.cid %>
+ |
+
+ IP
+ <%= data.ip %>
+ |
+
+ Flavor
+ 0
+ |
+
+
+
+ |
+ <% for(col=1; col<=16; col++){ %>
+ <%= col %> |
+ <% } %>
+
+
+ <% let slot = 0; %>
+ <% for(row=0; row<32; row++){ %>
+
+ | <%= row*16+1 %> |
+ <% for(col=0; col<16; col++){ %>
+ <% slot++%>
+ <%= universe.slots[slot-1] %> |
+ <% } %>
+
+ <% } %>
+
+
+
+
+<% }); %>
+
+
\ No newline at end of file
diff --git a/plugins/watchout/info.html b/plugins/watchout/info.html
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/watchout/main.js b/plugins/watchout/main.js
index 1c43cca..0f4c7dd 100644
--- a/plugins/watchout/main.js
+++ b/plugins/watchout/main.js
@@ -5,47 +5,49 @@ exports.searchOptions = {
type: 'TCPport',
searchBuffer: Buffer.from('authenticate 1\n', 'ascii'),
testPort: 3040,
- validateResponse: function (msg, info) {
- return msg.toString().substring(0, 5) == 'Ready';
+ validateResponse (msg, info) {
+ return msg.toString().substring(0, 5) === 'Ready';
},
};
exports.defaultPort = 3040;
-exports.ready = function (device) {
+exports.ready = function ready(device) {
device.send('authenticate 1\n');
};
-exports.data = function (device, message) {
+exports.data = function data(device, message) {
const msg = message.toString();
- if (msg.substring(0, 5) == 'Ready') {
- device.send('getStatus\n');
- }
- if (msg.substring(0, 5) == 'Reply') {
+ const d = device;
+
+ if (msg.substring(0, 5) === 'Ready') {
+ d.send('getStatus\n');
+
+ }else if (msg.substring(0, 5) === 'Reply') {
const arr = msg.split(' ');
- device.data.showName = '';
+ d.data.showName = '';
let i = 0;
- while (arr[i][arr[i].length - 1] != '"') {
+ while (arr[i][arr[i].length - 1] !== '"') {
i++;
- device.data.showName += `${arr[i]} `;
+ d.data.showName += `${arr[i]} `;
}
- device.data.showName = device.data.showName.substring(
+ d.data.showName = d.data.showName.substring(
1,
- device.data.showName.length - 2
+ d.data.showName.length - 2
);
i--;
- device.data.busy = arr[i + 2];
- device.data.health = arr[i + 3];
- device.data.displayOpen = arr[i + 4];
- device.data.showActive = arr[i + 5];
- device.data.programmerOnline = arr[i + 6];
- device.data.position = Number(arr[i + 7]).toFixed(2);
- device.data.rate = arr[i + 8];
- device.data.standby = arr[i + 9];
+ d.data.busy = arr[i + 2];
+ d.data.health = arr[i + 3];
+ d.data.displayOpen = arr[i + 4];
+ d.data.showActive = arr[i + 5];
+ d.data.programmerOnline = arr[i + 6];
+ d.data.position = Number(arr[i + 7]).toFixed(2);
+ d.data.rate = arr[i + 8];
+ d.data.standby = arr[i + 9];
- this.deviceInfoUpdate(device, 'defaultName', device.data.showName);
- device.draw();
+ this.deviceInfoUpdate(d, 'defaultName', d.data.showName);
+ d.draw();
}
// if(msg.substring(0, 5)=="Error"){
// device.data.error = msg.substring(6, 7);
@@ -53,6 +55,6 @@ exports.data = function (device, message) {
// console.log(msg)
};
-exports.heartbeat = function (device) {
+exports.heartbeat = function heartbeat(device) {
device.send('getStatus\n');
};
diff --git a/plugins/x32/info.html b/plugins/x32/info.html
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/x32/main.js b/plugins/x32/main.js
index 7e20e5b..4d41dda 100644
--- a/plugins/x32/main.js
+++ b/plugins/x32/main.js
@@ -6,24 +6,25 @@ exports.searchOptions = {
searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]),
devicePort: 10023,
listenPort: 0,
- validateResponse: function (msg, info) {
- return msg.toString().indexOf('/xinfo') == 0;
+ validateResponse (msg, info) {
+ return msg.toString().indexOf('/xinfo') === 0;
},
};
exports.defaultPort = 10023;
-exports.ready = function (device) {
- device.data.channelFaders = new Array(32).fill(0);
- device.data.channelFadersDB = new Array(32).fill(0);
- device.data.channelMutes = new Array(32).fill(0);
- device.data.channelNames = new Array(32).fill('end');
- device.data.channelColors = new Array(32);
+exports.ready = function ready(device) {
+ const d = device;
+ d.data.channelFaders = new Array(32).fill(0);
+ d.data.channelFadersDB = new Array(32).fill(0);
+ d.data.channelMutes = new Array(32).fill(0);
+ d.data.channelNames = new Array(32).fill('end');
+ d.data.channelColors = new Array(32);
- device.data.stereoFader = 0;
- device.data.stereoFaderDB = 0;
- device.data.stereoMute = 0;
+ d.data.stereoFader = 0;
+ d.data.stereoFaderDB = 0;
+ d.data.stereoMute = 0;
- device.send(Buffer.from('/xinfo'));
+ d.send(Buffer.from('/xinfo'));
// device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
// device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
@@ -40,31 +41,33 @@ function parseAddress(msg) {
function convertToDBTheBehringerWay(f) {
if (f >= 0.5) {
return f * 40 - 30;
- } else if (f >= 0.25) {
- return f * 80 - 50;
- } else if (f >= 0.0625) {
- return f * 160 - 70;
- } else {
- return f * 480 - 90;
}
+ if (f >= 0.25) {
+ return f * 80 - 50;
+ }
+ if (f >= 0.0625) {
+ return f * 160 - 70;
+ }
+ return f * 480 - 90;
}
-exports.data = function (device, buf) {
+exports.data = function data(device, buf) {
this.deviceInfoUpdate(device, 'status', 'ok');
const msg = buf.toString().split('\u0000\u0000');
+ const d = device;
- if (msg[0] == '/xinfo') {
+ if (msg[0] === '/xinfo') {
this.deviceInfoUpdate(device, 'defaultName', msg[4]);
- device.data.name = msg[4];
- device.data.ip = msg[2];
- device.data.firmware = msg[7];
- device.data.model = msg[5];
+ d.data.name = msg[4];
+ d.data.ip = msg[2];
+ d.data.firmware = msg[7];
+ d.data.model = msg[5];
- device.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000'));
- device.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000'));
+ d.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000'));
+ d.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000'));
for (let i = 0; i <= 32; i++) {
- device.send(
+ d.send(
Buffer.from(
`/ch/${i
.toString()
@@ -72,59 +75,59 @@ exports.data = function (device, buf) {
)
);
}
- device.draw();
- } else if (msg[0] == '/meters/0') {
+ d.draw();
+ } else if (msg[0] === '/meters/0') {
// console.log(msg)
} else if (msg[0].indexOf('/mix/fader') >= 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- if (addr[0] == 'ch') {
- device.data.channelFaders[channel - 1] = buf.readFloatBE(24);
- device.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay(
+ if (addr[0] === 'ch') {
+ d.data.channelFaders[channel - 1] = buf.readFloatBE(24);
+ d.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay(
buf.readFloatBE(24)
);
- } else if (addr[0] == 'lr') {
- device.data.stereoFader = buf.readFloatBE(20);
- device.data.stereoFaderDB = convertToDBTheBehringerWay(
+ } else if (addr[0] === 'lr') {
+ d.data.stereoFader = buf.readFloatBE(20);
+ d.data.stereoFaderDB = convertToDBTheBehringerWay(
buf.readFloatBE(20)
);
}
- device.draw();
+ d.draw();
} else if (msg[0].indexOf('/mix/on') >= 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- if (addr[0] == 'ch') {
- device.data.channelMutes[channel - 1] = buf[23];
- } else if (addr[0] == 'lr') {
- device.data.stereoMute = buf[19];
+ if (addr[0] === 'ch') {
+ d.data.channelMutes[channel - 1] = buf[23];
+ } else if (addr[0] === 'lr') {
+ d.data.stereoMute = buf[19];
}
- device.draw();
- device.send(
+ d.draw();
+ d.send(
Buffer.from(`/ch/${addr[1]}/mix/fader\u0000\u0000\u0000\u0000`)
);
} else if (msg[0].indexOf('/config/name') > 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- device.data.channelNames[channel - 1] = msg[2];
- device.draw();
- device.send(
+ d.data.channelNames[channel - 1] = msg[2];
+ d.draw();
+ d.send(
Buffer.from(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`)
);
} else if (msg[0].indexOf('/config/color') > 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- device.data.channelColors[channel - 1] = buf.readInt8(27);
- device.draw();
- device.send(Buffer.from(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`));
+ d.data.channelColors[channel - 1] = buf.readInt8(27);
+ d.draw();
+ d.send(Buffer.from(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`));
} else {
// console.log(msg)
}
// console.log(msg)
};
-exports.heartbeat = function (device) {
+exports.heartbeat = function heartbeat(device) {
device.send(Buffer.from('/xremote'));
};
diff --git a/plugins/xair/info.html b/plugins/xair/info.html
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/xair/main.js b/plugins/xair/main.js
index 377632b..3c759c7 100644
--- a/plugins/xair/main.js
+++ b/plugins/xair/main.js
@@ -6,24 +6,25 @@ exports.searchOptions = {
searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]),
devicePort: 10024,
listenPort: 0,
- validateResponse: function (msg, info) {
- return msg.toString().indexOf('/xinfo') == 0;
+ validateResponse (msg, info) {
+ return msg.toString().indexOf('/xinfo') === 0;
},
};
exports.defaultPort = 10024;
-exports.ready = function (device) {
- device.data.channelFaders = new Array(32).fill(0);
- device.data.channelFadersDB = new Array(32).fill(0);
- device.data.channelMutes = new Array(32).fill(0);
- device.data.channelNames = new Array(32).fill('end');
- device.data.channelColors = new Array(32);
+exports.ready = function ready(device) {
+ const d = device;
+ d.data.channelFaders = new Array(32).fill(0);
+ d.data.channelFadersDB = new Array(32).fill(0);
+ d.data.channelMutes = new Array(32).fill(0);
+ d.data.channelNames = new Array(32).fill('end');
+ d.data.channelColors = new Array(32);
- device.data.stereoFader = 0;
- device.data.stereoFaderDB = 0;
- device.data.stereoMute = 0;
+ d.data.stereoFader = 0;
+ d.data.stereoFaderDB = 0;
+ d.data.stereoMute = 0;
- device.send('/xinfo');
+ d.send('/xinfo');
// device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
// device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
@@ -40,36 +41,38 @@ function parseAddress(msg) {
function convertToDBTheBehringerWay(f) {
if (f >= 0.5) {
return f * 40 - 30;
- } else if (f >= 0.25) {
- return f * 80 - 50;
- } else if (f >= 0.0625) {
- return f * 160 - 70;
- } else {
- return f * 480 - 90;
}
+ if (f >= 0.25) {
+ return f * 80 - 50;
+ }
+ if (f >= 0.0625) {
+ return f * 160 - 70;
+ }
+ return f * 480 - 90;
}
-exports.data = function (device, buf) {
+exports.data = function data(device, buf) {
this.deviceInfoUpdate(device, 'status', 'ok');
const msg = buf.toString().split('\u0000');
+ const d = device;
- if (msg[0] == '/xinfo') {
+ if (msg[0] === '/xinfo') {
if (msg[7].length > 0) {
- device.data.name = msg[7];
+ d.data.name = msg[7];
} else {
- device.data.name = msg[6];
+ d.data.name = msg[6];
}
- device.data.ip = msg[5];
- device.data.firmware = msg[13];
- device.data.model = msg[9];
- this.deviceInfoUpdate(device, 'defaultName', device.data.name);
+ d.data.ip = msg[5];
+ d.data.firmware = msg[13];
+ d.data.model = msg[9];
+ this.deviceInfoUpdate(d, 'defaultName', d.data.name);
- device.send('/lr/mix/fader\u0000\u0000\u0000\u0000');
- device.send('/lr/mix/on\u0000\u0000\u0000\u0000');
+ d.send('/lr/mix/fader\u0000\u0000\u0000\u0000');
+ d.send('/lr/mix/on\u0000\u0000\u0000\u0000');
for (let i = 0; i <= 32; i++) {
- device.send(
+ d.send(
Buffer.from(
`/ch/${i
.toString()
@@ -77,55 +80,60 @@ exports.data = function (device, buf) {
)
);
}
- device.draw();
- } else if (msg[0] == '/meters/0') {
+ d.draw();
+
+ } else if (msg[0] === '/meters/0') {
// console.log(msg)
} else if (msg[0].indexOf('/mix/fader') >= 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- if (addr[0] == 'ch') {
- device.data.channelFaders[channel - 1] = buf.readFloatBE(24);
- device.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay(
+ if (addr[0] === 'ch') {
+ d.data.channelFaders[channel - 1] = buf.readFloatBE(24);
+ d.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay(
buf.readFloatBE(24)
);
- } else if (addr[0] == 'lr') {
- device.data.stereoFader = buf.readFloatBE(20);
- device.data.stereoFaderDB = convertToDBTheBehringerWay(
+ } else if (addr[0] === 'lr') {
+ d.data.stereoFader = buf.readFloatBE(20);
+ d.data.stereoFaderDB = convertToDBTheBehringerWay(
buf.readFloatBE(20)
);
}
- device.draw();
+ d.draw();
+
} else if (msg[0].indexOf('/mix/on') >= 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- if (addr[0] == 'ch') {
- device.data.channelMutes[channel - 1] = buf[23];
- } else if (addr[0] == 'lr') {
- device.data.stereoMute = buf[19];
+ if (addr[0] === 'ch') {
+ d.data.channelMutes[channel - 1] = buf[23];
+ } else if (addr[0] === 'lr') {
+ d.data.stereoMute = buf[19];
}
device.draw();
device.send(`/ch/${addr[1]}/mix/fader\u0000\u0000\u0000\u0000`);
+
} else if (msg[0].indexOf('/config/name') > 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- device.data.channelNames[channel - 1] = msg[4];
- device.draw();
- device.send(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`);
+ d.data.channelNames[channel - 1] = msg[4];
+ d.draw();
+ d.send(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`);
+
} else if (msg[0].indexOf('/config/color') > 0) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
- device.data.channelColors[channel - 1] = buf.readInt8(27);
- device.draw();
- device.send(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`);
+ d.data.channelColors[channel - 1] = buf.readInt8(27);
+ d.draw();
+ d.send(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`);
+
} else {
// console.log(msg)
}
// console.log(msg)
};
-exports.heartbeat = function (device) {
+exports.heartbeat = function heartbeat(device) {
device.send('/xremote');
};