mirror of
https://github.com/stagehacks/Cue-View.git
synced 2026-08-15 02:33:38 +00:00
Add real-time timer updates to Eos
This commit is contained in:
+180
-4
@@ -27,6 +27,9 @@ exports.config = {
|
||||
action(_device) {
|
||||
const device = _device;
|
||||
device.data.cueListFilter = device.fields.cueListFilter;
|
||||
if (device.data.EOS) {
|
||||
subscribeToCueList(device);
|
||||
}
|
||||
device.draw();
|
||||
},
|
||||
},
|
||||
@@ -40,10 +43,14 @@ exports.ready = function ready(_device) {
|
||||
cue: _.template(fs.readFileSync(path.join(__dirname, `cue.ejs`))),
|
||||
};
|
||||
device.data.cueListFilter = device.fields.cueListFilter;
|
||||
device.data.EOS.progressCueList = resolveConfiguredCueList(device);
|
||||
|
||||
device.send('/eos/get/cuelist/count');
|
||||
device.send('/eos/get/version');
|
||||
device.send('/eos/subscribe', [{ type: 'i', value: 1 }]);
|
||||
|
||||
// subscribe to the selected cue list specifically
|
||||
subscribeToCueList(device);
|
||||
};
|
||||
|
||||
exports.data = function data(_device, osc) {
|
||||
@@ -80,6 +87,7 @@ exports.data = function data(_device, osc) {
|
||||
|
||||
device.update('cueData', {
|
||||
cue: device.data.EOS.cueLists[addressParts[4]][addressParts[5]],
|
||||
cueListNumber: addressParts[4],
|
||||
cueNumber: addressParts[5],
|
||||
uid: osc.args[1],
|
||||
});
|
||||
@@ -92,9 +100,88 @@ exports.data = function data(_device, osc) {
|
||||
if (osc.args.length === 3) {
|
||||
device.data.EOS.cueLists[addressParts[4]][addressParts[5]][0].extLinks = osc.args[2];
|
||||
}
|
||||
} else if (match(addressParts, ['eos', 'out', 'cuelist', '8001', '1'])) {
|
||||
const cueListNumber = resolveConfiguredCueList(device);
|
||||
const cueNumber = cueNumberValue(osc.args[1]);
|
||||
const totalMs = nonNegativeInt(osc.args[6]);
|
||||
const cueRemainingMs = nonNegativeInt(osc.args[7]);
|
||||
const previousCueNumber = cueNumberValue(device.data.EOS.activeCueByList[cueListNumber]);
|
||||
|
||||
if (cueNumber !== undefined) {
|
||||
device.data.EOS.activeCueByList[cueListNumber] = cueNumber;
|
||||
device.data.EOS.activeCue = cueNumber;
|
||||
}
|
||||
|
||||
if (cueNumber !== undefined || cueRemainingMs !== null || totalMs !== null) {
|
||||
const progress = device.data.EOS.progressByList[cueListNumber] || {};
|
||||
if (cueNumber !== undefined) {
|
||||
progress.cueNumber = cueNumber;
|
||||
}
|
||||
if (cueRemainingMs !== null) {
|
||||
progress.cueRemainingMs = cueRemainingMs;
|
||||
}
|
||||
if (totalMs !== null) {
|
||||
progress.totalMs = totalMs;
|
||||
}
|
||||
device.data.EOS.progressByList[cueListNumber] = progress;
|
||||
}
|
||||
|
||||
if (previousCueNumber !== undefined && previousCueNumber !== cueNumber) {
|
||||
device.update('cueState', {
|
||||
cueListNumber,
|
||||
cueNumber: previousCueNumber,
|
||||
});
|
||||
}
|
||||
|
||||
if (cueNumber !== undefined) {
|
||||
device.update('cueState', {
|
||||
cueListNumber,
|
||||
cueNumber,
|
||||
});
|
||||
}
|
||||
} else if (match(addressParts, ['eos', 'out', 'cuelist', '8001'])) {
|
||||
const cueListNumber = resolveConfiguredCueList(device);
|
||||
const followHangRemainingMs = nonNegativeInt(osc.args[2]);
|
||||
if (followHangRemainingMs !== null) {
|
||||
const progress = device.data.EOS.progressByList[cueListNumber] || {};
|
||||
const activeCueForList = cueNumberValue(device.data.EOS.activeCueByList[cueListNumber]);
|
||||
if (progress.cueNumber === undefined && activeCueForList !== undefined) {
|
||||
progress.cueNumber = activeCueForList;
|
||||
}
|
||||
progress.followHangRemainingMs = followHangRemainingMs;
|
||||
device.data.EOS.progressByList[cueListNumber] = progress;
|
||||
if (progress.cueNumber !== undefined) {
|
||||
device.update('cueState', {
|
||||
cueListNumber,
|
||||
cueNumber: progress.cueNumber,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (match(addressParts, ['eos', 'out', 'event', 'cue', '*', '*', 'fire'])) {
|
||||
device.data.EOS.activeCue = addressParts[5];
|
||||
device.draw();
|
||||
const cueListNumber = cueNumberValue(addressParts[4]);
|
||||
const cueNumber = cueNumberValue(addressParts[5]);
|
||||
const previousCueNumber = cueNumberValue(device.data.EOS.activeCueByList[cueListNumber]);
|
||||
|
||||
device.data.EOS.activeCue = cueNumber;
|
||||
device.data.EOS.activeCueByList[cueListNumber] = cueNumber;
|
||||
device.data.EOS.progressByList[cueListNumber] = {
|
||||
cueNumber,
|
||||
cueRemainingMs: null,
|
||||
followHangRemainingMs: null,
|
||||
totalMs: null,
|
||||
};
|
||||
|
||||
if (previousCueNumber !== undefined && previousCueNumber !== cueNumber) {
|
||||
device.update('cueState', {
|
||||
cueListNumber,
|
||||
cueNumber: previousCueNumber,
|
||||
});
|
||||
}
|
||||
device.update('cueState', {
|
||||
cueListNumber,
|
||||
cueNumber,
|
||||
});
|
||||
|
||||
const cues = device.data.EOS.cueLists[addressParts[4]][addressParts[5]];
|
||||
if (cues) {
|
||||
device.update('activeCue', {
|
||||
@@ -115,18 +202,48 @@ exports.data = function data(_device, osc) {
|
||||
exports.update = function update(device, doc, updateType, data) {
|
||||
if (updateType === 'cueData') {
|
||||
const $elem = doc.getElementById(data.uid);
|
||||
const cueState = cueRenderState(device, data.cueListNumber, data.cueNumber);
|
||||
if ($elem) {
|
||||
$elem.outerHTML = device.templates.cue({
|
||||
q: data.cue,
|
||||
cueNumber: data.cueNumber,
|
||||
isActive: false,
|
||||
isActive: cueState.isComplete,
|
||||
isComplete: cueState.isComplete,
|
||||
isRunning: cueState.isRunning,
|
||||
remainingDuration: cueState.remainingDuration,
|
||||
followHangRemainingDuration: cueState.followHangRemainingDuration,
|
||||
});
|
||||
} else {
|
||||
device.draw();
|
||||
}
|
||||
} else if (updateType === 'cueState') {
|
||||
const cueListNumber = cueNumberValue(data.cueListNumber);
|
||||
const cueNumber = cueNumberValue(data.cueNumber);
|
||||
const cues = device.data.EOS.cueLists?.[cueListNumber]?.[cueNumber];
|
||||
if (!cues || !cues[0]) {
|
||||
device.draw();
|
||||
return;
|
||||
}
|
||||
const $elem = doc.getElementById(cues[0].uid);
|
||||
if ($elem) {
|
||||
const cueState = cueRenderState(device, cueListNumber, cueNumber);
|
||||
$elem.outerHTML = device.templates.cue({
|
||||
q: cues,
|
||||
cueNumber,
|
||||
isActive: cueState.isComplete,
|
||||
isComplete: cueState.isComplete,
|
||||
isRunning: cueState.isRunning,
|
||||
remainingDuration: cueState.remainingDuration,
|
||||
followHangRemainingDuration: cueState.followHangRemainingDuration,
|
||||
});
|
||||
} else {
|
||||
device.draw();
|
||||
}
|
||||
} else if (updateType === 'activeCue') {
|
||||
const $elem = doc.getElementById(data.uid);
|
||||
$elem.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
if ($elem) {
|
||||
$elem.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -134,6 +251,62 @@ exports.heartbeat = function heartbeat(device) {
|
||||
device.send('/eos/ping');
|
||||
};
|
||||
|
||||
function resolveConfiguredCueList(device) {
|
||||
const cueListFilter = cueNumberValue(device.data.cueListFilter);
|
||||
return cueListFilter || '1';
|
||||
}
|
||||
|
||||
function subscribeToCueList(device) {
|
||||
const cueListNumber = resolveConfiguredCueList(device);
|
||||
const eosState = device.data.EOS;
|
||||
eosState.progressCueList = cueListNumber;
|
||||
device.send(`/eos/cuelist/8001/config/${cueListNumber}/0/0`);
|
||||
}
|
||||
|
||||
function cueRenderState(device, cueListNumber, cueNumber) {
|
||||
const list = cueNumberValue(cueListNumber);
|
||||
const cue = cueNumberValue(cueNumber);
|
||||
const progress = device.data.EOS.progressByList[list];
|
||||
const activeCue = cueNumberValue(device.data.EOS.activeCueByList[list]);
|
||||
const cueRemainingMs = progress?.cueRemainingMs;
|
||||
const followHangRemainingMs = progress?.followHangRemainingMs;
|
||||
const isComplete = cue === activeCue;
|
||||
const isRunning =
|
||||
isComplete &&
|
||||
progress !== undefined &&
|
||||
cue === cueNumberValue(progress.cueNumber) &&
|
||||
cueRemainingMs !== null &&
|
||||
cueRemainingMs > 0;
|
||||
const hasFollowHangCountdown = isComplete && followHangRemainingMs !== null && followHangRemainingMs > 0;
|
||||
|
||||
return {
|
||||
isRunning,
|
||||
isComplete,
|
||||
remainingDuration: isRunning ? cueRemainingMs : null,
|
||||
followHangRemainingDuration: hasFollowHangCountdown ? followHangRemainingMs : null,
|
||||
};
|
||||
}
|
||||
|
||||
function cueNumberValue(value) {
|
||||
if (value === undefined || value === null) {
|
||||
return undefined;
|
||||
}
|
||||
return `${value}`.trim();
|
||||
}
|
||||
|
||||
function nonNegativeInt(value) {
|
||||
if (value === undefined || value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const numericValue = Number(value);
|
||||
if (!Number.isFinite(numericValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Math.max(0, Math.round(numericValue));
|
||||
}
|
||||
|
||||
function match(testArray, patternArray) {
|
||||
let out = true;
|
||||
if (testArray.length !== patternArray.length) {
|
||||
@@ -152,5 +325,8 @@ class EOS {
|
||||
this.showName = '';
|
||||
this.cueLists = {};
|
||||
this.activeCue = undefined;
|
||||
this.activeCueByList = {};
|
||||
this.progressByList = {};
|
||||
this.progressCueList = '1';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user