Files
Cue-View/plugins/digico/main.js
T
2023-01-26 02:21:05 -05:00

180 lines
5.7 KiB
JavaScript

const _ = require('lodash');
const fs = require('fs');
const path = require('path');
exports.config = {
defaultName: 'DiGiCo',
connectionType: 'osc-udp',
remotePort: 8000,
localPort: 8001,
mayChangePorts: true,
heartbeatInterval: 2000,
heartbeatTimeout: 11000,
searchOptions: {
type: 'UDPsocket',
// send "/Console/Name/?" this is what the iPad sends to check connection
searchBuffer: Buffer.from([
0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2f, 0x4e, 0x61, 0x6d, 0x65, 0x2f, 0x3f, 0x00, 0x2c, 0x00, 0x00,
0x00,
]),
devicePort: 8000,
listenPort: 9000,
validateResponse(msg, info) {
console.log(msg);
console.log(msg.toString());
return msg.toString().includes('/Console');
},
},
};
exports.ready = function ready(_device) {
const device = _device;
device.data = new DiGiCo();
device.send('/Console/Name/?');
device.send('/Console/Session/Filename/?');
device.send('/Console/Channels/?');
device.send('/Snapshots/Current_Snapshot/?');
// These are also sent by the iPad app but aren't queries (?) so may potentially write to console?
// device.send('/Meters/clear');
// device.send('/Meters/clear');
};
exports.data = function data(_device, oscData) {
const device = _device;
this.deviceInfoUpdate(device, 'status', 'ok');
const properties = oscData.address.split('/');
properties.shift();
setObjectProperty(device.data, properties, oscData.args);
if (properties[0] === 'Console' && properties[1] === 'Control_Groups') {
for (let i = 1; i <= device.data.Console.Control_Groups; i++) {
device.send(`/Control_Groups/${i}/?`);
}
device.draw();
} else if (['Control_Groups', 'Input_Channels', 'Group_Outputs', 'Aux_Outputs'].includes(properties[0])) {
device.update('fader', {
type: properties[0],
channel: properties[1],
});
// } else if (properties[0] === 'Control_Groups') {
// device.update('fader', {
// type: 'Control_Groups',
// channel: properties[1],
// });
} else if (properties[0] === 'Console' && properties[1] === 'Input_Channels') {
for (let i = 1; i <= device.data.Console.Input_Channels; i++) {
device.send(`/Input_Channels/${i}/Channel_Input/name`); // yup, no ? at the end of this one
device.send(`/Input_Channels/${i}/mute/?`);
device.send(`/Input_Channels/${i}/solo/?`);
device.send(`/Input_Channels/${i}/fader/?`);
}
device.draw();
// } else if (properties[0] === 'Input_Channels') {
// device.update('fader', {
// type: 'Input_Channels',
// channel: properties[1],
// });
} else if (properties[0] === 'Console' && properties[1] === 'Group_Outputs') {
for (let i = 1; i <= device.data.Console.Group_Outputs; i++) {
device.send(`/Group_Outputs/${i}/mute/?`);
device.send(`/Group_Outputs/${i}/solo/?`);
device.send(`/Group_Outputs/${i}/fader/?`);
device.send(`/Group_Outputs/${i}/Buss_Trim/name/?`);
}
device.draw();
// } else if (properties[0] === 'Group_Outputs') {
// device.update('fader', {
// type: 'Group_Outputs',
// channel: properties[1],
// });
} else if (properties[0] === 'Console' && properties[1] === 'Aux_Outputs') {
for (let i = 1; i <= device.data.Console.Aux_Outputs; i++) {
device.send(`/Aux_Outputs/${i}/mute/?`);
device.send(`/Aux_Outputs/${i}/solo/?`);
device.send(`/Aux_Outputs/${i}/fader/?`);
device.send(`/Aux_Outputs/${i}/Buss_Trim/name/?`);
}
device.draw();
// } else if (properties[0] === 'Aux_Outputs') {
// device.update('fader', {
// type: 'Aux_Outputs',
// channel: properties[1],
// });
} else if (properties[0] === 'Console' && properties[1] === 'Name') {
this.deviceInfoUpdate(device, 'defaultName', device.data.Console.Name);
} else if (properties[0] === 'Snapshots') {
device.update('updateSnapshot', {
snapshots: device.data.Snapshots,
});
}
};
exports.heartbeat = function heartbeat(device) {
device.send('/Console/Name/?');
console.log(device.data);
};
class DiGiCo {
constructor() {
this.Console = {};
this.Input_Channels = {};
this.Aux_Outputs = {};
this.Control_Groups = {};
this.Group_Outputs = {};
this.Matrix_Outputs = {};
this.Layout = {};
}
}
/*
This function takes somethings like this /Console/Session/Filename with a osc args like ['session.ses']
and turns it into a nested object like. An easy way to set properties converting OSC paths to properties
{
Console: {
Session: {
Filename: 'session.ses'
}
}
}
*/
function setObjectProperty(_object, _properties, value) {
let object = _object;
const properties = _properties;
for (let i = 0; i < properties.length - 1; i++) {
const property = properties[i];
if (object[property] === undefined) {
object[property] = {};
}
object = object[property];
}
const property = properties[properties.length - 1];
if (Array.isArray(value)) {
// if this is an array of length one just set the property to the contents so ['string'] becomes 'string'
if (value.length === 1) {
object[property] = value[0];
return;
}
}
object[property] = value;
}
const faderTemplate = _.template(fs.readFileSync(path.join(__dirname, `/fader.ejs`)));
exports.update = function update(device, doc, updateType, data) {
if (updateType === 'fader') {
const $elem = doc.getElementById(`${data.type}-${data.channel}`);
$elem.outerHTML = faderTemplate({
type: data.type,
fader: device.data[data.type][data.channel],
index: data.channel,
});
} else if (updateType === 'snapshot') {
const $elem = doc.getElementById(`snapshot`);
$elem.textContent = `${data.snapshots.Current_Snapshot}`;
}
};