diff --git a/index.html b/index.html
index 7000668..296d0c2 100644
--- a/index.html
+++ b/index.html
@@ -49,17 +49,33 @@
Addr:
-
+
- Port:
+ Port:
-
+
Pin:
+
+ Local:
+
+
+
+
+
+
diff --git a/plugins/artnet/main.js b/plugins/artnet/main.js
index 459dfd0..5ccfde7 100644
--- a/plugins/artnet/main.js
+++ b/plugins/artnet/main.js
@@ -1,8 +1,8 @@
exports.config = {
defaultName: 'Art-Net',
connectionType: 'UDPsocket',
- defaultPort: 6454,
- mayChangePort: false,
+ remotePort: 6454,
+ mayChangePorts: false,
heartbeatInterval: 5000,
heartbeatTimeout: 15000,
searchOptions: {
diff --git a/plugins/digico/fader.ejs b/plugins/digico/fader.ejs
new file mode 100644
index 0000000..38c444e
--- /dev/null
+++ b/plugins/digico/fader.ejs
@@ -0,0 +1,42 @@
+
+ <% if(fader && fader.meter>0){ %>
+
+ <%=index%>
+
+ <% }else{ %>
+ <%=index%>
+ <% } %>
+
+ <% if(type=="Control_Groups"){ %>
+
+ <%= fader ? fader.name : "-" %>
+
+ <% }else if(type=="Input_Channels"){ %>
+
+ <%= fader ? (fader.Channel_Input ? fader.Channel_Input.name: "") : "" %>
+
+ <% }else if(type=="Group_Outputs"){ %>
+
+ <%= fader ? (fader.Buss_Trim ? fader.Buss_Trim.name: "") : "" %>
+
+ <% }else if(type=="Aux_Outputs"){ %>
+
+ <%= fader ? (fader.Buss_Trim ? fader.Buss_Trim.name: "") : "" %>
+
+ <% } %>
+
+
+
+ <% if(fader){ %>
+ <% let percent = (fader.fader-10)*1.5+100 %>
+
+ <% if(fader.fader>-100){ %>
+ <%= fader ? Math.round(fader.fader*10.0)/10.0 : '-' %>db
+ <% } %>
+
+ <% }else{ %>
+ -
+ <% } %>
+
+
+
\ No newline at end of file
diff --git a/plugins/digico/icon.afphoto b/plugins/digico/icon.afphoto
new file mode 100644
index 0000000..ff2c905
Binary files /dev/null and b/plugins/digico/icon.afphoto differ
diff --git a/plugins/digico/icon.png b/plugins/digico/icon.png
new file mode 100644
index 0000000..4a5276a
Binary files /dev/null and b/plugins/digico/icon.png differ
diff --git a/plugins/digico/info.html b/plugins/digico/info.html
new file mode 100644
index 0000000..9d0f401
--- /dev/null
+++ b/plugins/digico/info.html
@@ -0,0 +1,17 @@
+Cue View emulates to be the DiGiCo SD iPad app.
+
+ On the SD console open Master Screen → Setup → External Control
+ Enable External Control by pressing the button at the top of the panel
+ Press the add device button and select DiGiCo Pad
+ Enter a Device Name for Cue View and then enter the IP Address of this computer
+ Enter Send and Receive Port numbers
+
+ Cue View Port = DiGiCo Receive
+ Cue View Local = DiGiCo Send
+
+ Tick the Enable column for this device
+
+ Press the Load button in the bottom right corner of the panel and select the commands button for the
+ relevant console
+
+
diff --git a/plugins/digico/main.js b/plugins/digico/main.js
new file mode 100644
index 0000000..c541510
--- /dev/null
+++ b/plugins/digico/main.js
@@ -0,0 +1,192 @@
+const _ = require('lodash');
+const fs = require('fs');
+const path = require('path');
+
+exports.config = {
+ defaultName: 'DiGiCo SD',
+ 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/?');
+ 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();
+
+ if (properties[0] !== 'Meters') {
+ setObjectProperty(device.data, properties, oscData.args);
+ // console.log(properties);
+ }
+
+ 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 (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/?`);
+ device.send(`/Input_Channels/${i}/mute/?`);
+ device.send(`/Input_Channels/${i}/solo/?`);
+ device.send(`/Input_Channels/${i}/fader/?`);
+ device.send(`/Meters/request/1${i}`, [
+ { type: 's', value: `/Input_Channels/${i}/Channel_Input/post_meter/left` },
+ ]);
+ }
+ device.draw();
+ } 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.send(`/Meters/request/3${i}`, [{ type: 's', value: `/Group_Outputs/${i}/fader_meter/left` }]);
+ }
+ device.draw();
+ } 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.send(`/Meters/request/4${i}`, [{ type: 's', value: `/Aux_Outputs/${i}/fader_meter/left` }]);
+ }
+ device.draw();
+ } else if (properties[0] === 'Console' && properties[1] === 'Name') {
+ this.deviceInfoUpdate(device, 'defaultName', device.data.Console.Name);
+ } 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] === 'Snapshots') {
+ device.update('updateSnapshot', {
+ snapshots: device.data.Snapshots,
+ });
+ } else if (properties[0] === 'Meters' && properties[1] === 'values') {
+ for (let i = 0; i < oscData.args.length; i += 2) {
+ const channelType = oscData.args[i].toString()[0];
+ const channelNumber = oscData.args[i].toString().substring(1);
+ const meterValue = BigInt(oscData.args[i + 1]) / -40000n + 100n;
+
+ if (channelType === '1' && device.data.Input_Channels[channelNumber]) {
+ device.data.Input_Channels[channelNumber].meter = meterValue;
+ device.update('fader', {
+ type: 'Input_Channels',
+ channel: channelNumber,
+ });
+ } else if (channelType === '3' && device.data.Group_Outputs[channelNumber]) {
+ device.data.Group_Outputs[channelNumber].meter = meterValue;
+ device.update('fader', {
+ type: 'Group_Outputs',
+ channel: channelNumber,
+ });
+ } else if (channelType === '4' && device.data.Aux_Outputs[channelNumber]) {
+ device.data.Aux_Outputs[channelNumber].meter = meterValue;
+ device.update('fader', {
+ type: 'Aux_Outputs',
+ channel: channelNumber,
+ });
+ }
+ }
+ }
+};
+
+exports.heartbeat = function heartbeat(device) {
+ device.send('/Console/Name/?');
+ console.log(device.data);
+
+ // Need to do a /Meters/clear when quitting Cue View or closing the View
+};
+
+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}`;
+ }
+};
diff --git a/plugins/digico/styles.css b/plugins/digico/styles.css
new file mode 100644
index 0000000..4a36e34
--- /dev/null
+++ b/plugins/digico/styles.css
@@ -0,0 +1,76 @@
+.column {
+ float: left;
+ margin: 5px;
+}
+.section {
+ border: #333 3px solid;
+ border-bottom: none;
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ padding: 10px;
+ margin-bottom: 30px;
+}
+.section h3 {
+ font-weight: 300;
+ margin-top: 0px;
+ color: #aaa !important;
+}
+table {
+ border-collapse: collapse;
+ display: block;
+}
+.fader:nth-child(even) {
+ background: #1a1a1a;
+}
+.fader:nth-child(odd) {
+ background: #1f1f1f;
+}
+.fader td {
+ text-align: center;
+ width: 30px;
+ height: 20px;
+ border: black 1px solid;
+}
+.fader .fader-channel {
+ color: #777;
+ font-size: 10px;
+}
+.fader .fader-name {
+ width: 80px;
+ color: black;
+ font-family: monospace;
+}
+.fader .lcd-control-group {
+ background-color: rgb(66, 132, 255);
+}
+.fader .lcd-channel-input {
+ background-color: rgb(135, 175, 235);
+}
+.fader .lcd-group-output {
+ background-color: rgb(241, 71, 48);
+}
+.fader .lcd-aux-output {
+ background-color: rgb(197, 0, 187);
+}
+.fader .fader-name.state-1 {
+ background-color: rgb(0, 185, 0);
+}
+.fader .fader-mute {
+ width: 10px;
+ background-color: #444;
+}
+.fader .fader-mute.state-1 {
+ background-color: red;
+}
+.fader .fader-fader {
+ text-align: left;
+ width: 70px;
+ padding: 0px 10px;
+ color: rgb(68, 68, 68);
+}
+
+#snapshot {
+ font-size: 36px;
+ font-weight: bold;
+ font-family: 'Arial Black', 'Impact';
+}
diff --git a/plugins/digico/template.ejs b/plugins/digico/template.ejs
new file mode 100644
index 0000000..25667c2
--- /dev/null
+++ b/plugins/digico/template.ejs
@@ -0,0 +1,56 @@
+
+ <%= listName %>
+ <%= data.Console.Session.Filename %>
+
+
+<%
+const fs = require('fs');
+let _ = require('lodash');
+const path = require('path');
+
+ let faderTemplate = _.template(fs.readFileSync(path.join(__dirname, `/plugins/digico/fader.ejs`)));
+%>
+
+
+
+
snapshot
+
+
+
+
control groups
+
+ <% for(let i=1; i<=data.Console.Control_Groups; i++){ %>
+ <%= faderTemplate({type: "Control_Groups", fader: data.Control_Groups[i], index: i}) %>
+ <% } %>
+
+
+
+
+
group outputs
+
+ <% for(let i=1; i<=data.Console.Group_Outputs; i++){ %>
+ <%= faderTemplate({type: "Group_Outputs", fader: data.Group_Outputs[i], index: i}) %>
+ <% } %>
+
+
+
+
+
aux outputs
+
+ <% for(let i=1; i<=data.Console.Aux_Outputs; i++){ %>
+ <%= faderTemplate({type: "Aux_Outputs", fader: data.Aux_Outputs[i], index: i}) %>
+ <% } %>
+
+
+
+
+
+
input channels
+
+ <% for(let i=1; i<=data.Console.Input_Channels; i++){ %>
+ <%= faderTemplate({type: "Input_Channels", fader: data.Input_Channels[i], index: i}) %>
+ <% } %>
+
+
+
+
diff --git a/plugins/pjlink/main.js b/plugins/pjlink/main.js
index e1e227b..d701049 100644
--- a/plugins/pjlink/main.js
+++ b/plugins/pjlink/main.js
@@ -3,8 +3,8 @@ const md5 = require('md5');
exports.config = {
defaultName: 'PJLink Projector',
connectionType: 'TCPsocket',
- defaultPort: 4352,
- mayChangePort: false,
+ remotePort: 4352,
+ mayChangePorts: false,
heartbeatInterval: 5000,
heartbeatTimeout: 15000,
searchOptions: {
diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js
index 7a8d4e6..d242e6f 100644
--- a/plugins/qlab/main.js
+++ b/plugins/qlab/main.js
@@ -5,8 +5,10 @@ const path = require('path');
exports.config = {
defaultName: 'QLab',
connectionType: 'osc',
- defaultPort: 53000,
- mayChangePort: true,
+ remotePort: 53000,
+ localPort: 53001,
+ mayChangePorts: true,
+ mayChangeLocalPort: false,
heartbeatInterval: 100,
heartbeatTimeout: 5000,
searchOptions: {
diff --git a/plugins/sacn/main.js b/plugins/sacn/main.js
index 4274185..0fe9eb5 100644
--- a/plugins/sacn/main.js
+++ b/plugins/sacn/main.js
@@ -3,8 +3,8 @@ const _ = require('lodash');
exports.config = {
defaultName: 'sACN',
connectionType: 'multicast',
- defaultPort: 5568,
- mayChangePort: false,
+ remotePort: 5568,
+ mayChangePorts: false,
heartbeatInterval: 5000,
heartbeatTimeout: 15000,
searchOptions: {
diff --git a/plugins/shure/main.js b/plugins/shure/main.js
index e4f539b..05897b6 100644
--- a/plugins/shure/main.js
+++ b/plugins/shure/main.js
@@ -3,8 +3,8 @@ const Channel = require('./channel');
exports.config = {
defaultName: 'Shure Wireless',
connectionType: 'TCPsocket',
- defaultPort: 2202,
- mayChangePort: false,
+ remotePort: 2202,
+ mayChangePorts: false,
heartbeatInterval: 5000,
heartbeatTimeout: 10000,
searchOptions: {
diff --git a/plugins/watchout/main.js b/plugins/watchout/main.js
index 340aa9f..d6abc35 100644
--- a/plugins/watchout/main.js
+++ b/plugins/watchout/main.js
@@ -1,8 +1,8 @@
exports.config = {
defaultName: 'Dataton Watchout',
connectionType: 'TCPsocket',
- defaultPort: 3040,
- mayChangePort: false,
+ remotePort: 3040,
+ mayChangePorts: false,
heartbeatInterval: 250,
heartbeatTimeout: 5000,
searchOptions: {
diff --git a/plugins/x32/main.js b/plugins/x32/main.js
index 5021abd..6d28b87 100644
--- a/plugins/x32/main.js
+++ b/plugins/x32/main.js
@@ -1,8 +1,8 @@
exports.config = {
defaultName: 'X32 Mixer',
connectionType: 'osc-udp',
- defaultPort: 10023,
- mayChangePort: false,
+ remotePort: 10023,
+ mayChangePorts: false,
heartbeatInterval: 9000,
heartbeatTimeout: 11000,
searchOptions: {
diff --git a/plugins/xair/main.js b/plugins/xair/main.js
index ffc70f3..482360b 100644
--- a/plugins/xair/main.js
+++ b/plugins/xair/main.js
@@ -1,8 +1,8 @@
exports.config = {
defaultName: 'X Air Mixer',
connectionType: 'UDPsocket',
- defaultPort: 10024,
- mayChangePort: false,
+ remotePort: 10024,
+ mayChangePorts: false,
heartbeatInterval: 9000,
heartbeatTimeout: 15000,
searchOptions: {
diff --git a/preload.js b/preload.js
index 5e5aeca..cb7f165 100644
--- a/preload.js
+++ b/preload.js
@@ -59,6 +59,11 @@ window.init = function init() {
DEVICE.changeActivePort(e.target.value);
};
+ document.getElementById('device-settings-rx-port').onchange = function portChange(e) {
+ e.stopPropagation();
+ DEVICE.changeActiveRxPort(e.target.value);
+ };
+
document.getElementById('device-settings-pin').onchange = function pinChange(e) {
e.stopPropagation();
if (e.target.checked) {
@@ -101,7 +106,7 @@ window.init = function init() {
{
type: e.target.value,
defaultName: 'New Device',
- port: undefined,
+ remotePort: PLUGINS.all[e.target.value].config.remotePort || '',
addresses: [],
},
'fromAddButton'
diff --git a/src/assets/css/index.css b/src/assets/css/index.css
index f1884b4..c3b675a 100644
--- a/src/assets/css/index.css
+++ b/src/assets/css/index.css
@@ -182,7 +182,8 @@ a {
#device-settings #device-settings-plugin-dropdown {
width: 170px;
}
-#device-settings #device-settings-port {
+#device-settings #device-settings-port,
+#device-settings #device-settings-rx-port {
width: 70px;
}
#network-indicator-dot {
diff --git a/src/assets/css/plugin_default.css b/src/assets/css/plugin_default.css
index 3a82e48..81eb742 100644
--- a/src/assets/css/plugin_default.css
+++ b/src/assets/css/plugin_default.css
@@ -43,7 +43,9 @@ header h2 {
header h2 {
color: #b6b6b6;
}
-
+h3 {
+ font-weight: 300;
+}
table.cv-table {
border: none;
table-layout: fixed;
diff --git a/src/device.js b/src/device.js
index bb907db..c73fe7f 100644
--- a/src/device.js
+++ b/src/device.js
@@ -27,6 +27,16 @@ function registerDevice(newDevice, discoveryMethod) {
return false;
}
+ // set the local port for the new device
+ let newLocalPort = newDevice.localPort;
+ if (!newLocalPort) {
+ if (PLUGINS.all[newDevice.type].config.localPort) {
+ newLocalPort = PLUGINS.all[newDevice.type].config.localPort;
+ } else {
+ newLocalPort = newDevice.remotePort;
+ }
+ }
+
const id = newDevice.id || uuid();
devices[id] = {
id,
@@ -35,7 +45,8 @@ function registerDevice(newDevice, discoveryMethod) {
type: newDevice.type,
displayName: newDevice.displayName,
defaultName: newDevice.defaultName,
- port: newDevice.port,
+ remotePort: newDevice.remotePort,
+ localPort: newLocalPort,
addresses: newDevice.addresses,
data: {},
templates: {},
@@ -82,11 +93,11 @@ function initDeviceConnection(id) {
infoUpdate(device, 'status', 'new');
- if (device.port === undefined) {
- device.port = device.plugin.config.defaultPort;
+ if (device.remotePort === undefined) {
+ device.remotePort = device.plugin.config.defaultPort;
}
- if (device.port === undefined || device.addresses.length === 0) {
+ if (device.remotePort === undefined || device.addresses.length === 0) {
return true;
}
try {
@@ -103,13 +114,14 @@ function initDeviceConnection(id) {
if (plugins[type].config.connectionType.includes('udp')) {
device.connection = new osc.UDPPort({
localAddress: '0.0.0.0',
+ localPort: device.localPort,
remoteAddress: device.addresses[0],
- remotePort: device.port,
+ remotePort: device.remotePort,
});
} else {
device.connection = new osc.TCPSocketPort({
address: device.addresses[0],
- port: device.port,
+ port: device.remotePort,
});
}
device.connection.open();
@@ -144,7 +156,7 @@ function initDeviceConnection(id) {
device.connection = new net.Socket();
device.connection.connect(
{
- port: device.port,
+ port: device.remotePort,
host: device.addresses[0],
},
() => {}
@@ -176,7 +188,7 @@ function initDeviceConnection(id) {
} else if (plugins[type].config.connectionType === 'UDPsocket') {
device.connection = udp.createSocket('udp4');
- device.connection.bind({ port: plugins[type].config.defaultPort }, () => {
+ device.connection.bind({ port: plugins[type].config.remotePort }, () => {
plugins[type].ready(device);
device.connection.on('message', (msg, info) => {
@@ -198,7 +210,7 @@ function initDeviceConnection(id) {
} else if (plugins[type].config.connectionType === 'multicast') {
device.connection = udp.createSocket('udp4');
- device.connection.bind(device.port, () => {
+ device.connection.bind(device.remotePort, () => {
plugins[type].ready(device);
device.connection.on('message', (msg, info) => {
@@ -287,7 +299,7 @@ module.exports.changeActiveIP = function changeActiveIP(newIP) {
module.exports.changeActivePort = function changeActivePort(newPort) {
const device = VIEW.getActiveDevice();
- device.port = newPort;
+ device.remotePort = newPort;
initDeviceConnection(device.id);
VIEW.draw(device);
diff --git a/src/saveSlots.js b/src/saveSlots.js
index 2ef2273..ac30072 100644
--- a/src/saveSlots.js
+++ b/src/saveSlots.js
@@ -62,7 +62,8 @@ module.exports.loadDevices = function loadDevices() {
type: savedDevices[i].type,
displayName: savedDevices[i].displayName,
defaultName: savedDevices[i].defaultName,
- port: savedDevices[i].port,
+ remotePort: savedDevices[i].remotePort,
+ localPort: savedDevices[i].localPort,
addresses: savedDevices[i].addresses,
id: savedDevices[i].id,
fields: savedDevices[i].fields,
@@ -110,7 +111,8 @@ module.exports.saveAll = function saveAll() {
type: device.type,
displayName: device.displayName,
defaultName: device.defaultName,
- port: device.port,
+ remotePort: device.remotePort,
+ localPort: device.localPort,
id: device.id,
fields: device.fields,
};
diff --git a/src/search.js b/src/search.js
index a713dbe..27bfcbc 100644
--- a/src/search.js
+++ b/src/search.js
@@ -130,7 +130,7 @@ function searchBonjour(pluginType, pluginConfig) {
{
type: pluginType,
defaultName: e.name,
- port: e.port,
+ remotePort: e.port,
addresses: validAddresses,
},
'fromSearch'
@@ -157,7 +157,7 @@ function TCPtest(ipAddr, pluginType, pluginConfig) {
{
type: pluginType,
defaultName: pluginConfig.defaultName,
- port: pluginConfig.defaultPort,
+ remotePort: pluginConfig.remotePort,
addresses: [ipAddr],
},
'fromSearch'
@@ -215,7 +215,7 @@ function searchUDP(pluginType, pluginConfig) {
{
type: pluginType,
defaultName: pluginConfig.defaultName,
- port: pluginConfig.defaultPort,
+ remotePort: pluginConfig.remotePort,
addresses: [info.address],
},
'fromSearch'
@@ -247,7 +247,7 @@ function searchMulticast(pluginType, pluginConfig) {
{
type: pluginType,
defaultName: pluginConfig.defaultName,
- port: pluginConfig.defaultPort,
+ remotePort: pluginConfig.remotePort,
addresses: [info.address],
},
'fromSearch'
diff --git a/src/view.js b/src/view.js
index 3c750dc..1c144b1 100644
--- a/src/view.js
+++ b/src/view.js
@@ -190,13 +190,30 @@ function switchDevice(id) {
document.getElementById('device-settings-plugin-dropdown').value = activeDevice.type;
document.getElementById('device-settings-name').value = activeDevice.displayName || activeDevice.defaultName || '';
document.getElementById('device-settings-ip').value = activeDevice.addresses[0] || '';
- document.getElementById('device-settings-port').value = activeDevice.port || '';
+ document.getElementById('device-settings-port').value = activeDevice.remotePort || '';
document.getElementById('device-settings-pin').checked = activeDevice.pinIndex;
- if (activeDevice.plugin.config.mayChangePort) {
+ if (activeDevice.plugin.config.mayChangePorts) {
document.getElementById('device-settings-port').disabled = false;
+ document.getElementById('device-settings-rx-port').disabled = false;
} else {
document.getElementById('device-settings-port').disabled = true;
+ document.getElementById('device-settings-rx-port').disabled = true;
+ }
+
+ if (activeDevice.plugin.config.mayChangeLocalPort === false) {
+ document.getElementById('device-settings-rx-port').disabled = true;
+ } else {
+ document.getElementById('device-settings-rx-port').disabled = false;
+ }
+
+ if (activeDevice.plugin.config.localPort) {
+ // document.getElementById('device-settings-port-label').textContent = 'Remote\nPort:';
+ document.getElementById('device-settings-rx-port-row').style.display = 'table-row';
+ document.getElementById('device-settings-rx-port').value = activeDevice.localPort || '';
+ } else {
+ document.getElementById('device-settings-port-label').textContent = 'Port:';
+ document.getElementById('device-settings-rx-port-row').style.display = 'none';
}
updateFields();