mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Merge remote-tracking branch 'origin/master' into temperture
This commit is contained in:
164
assets/webconfig/js/content_events.js
Normal file
164
assets/webconfig/js/content_events.js
Normal file
@@ -0,0 +1,164 @@
|
||||
$(document).ready(function () {
|
||||
performTranslation();
|
||||
|
||||
let isGuiMode = window.sysInfo.hyperion.isGuiMode;
|
||||
const CEC_ENABLED = (jQuery.inArray("cec", window.serverInfo.services) !== -1);
|
||||
|
||||
let conf_editor_osEvents = null;
|
||||
let conf_editor_cecEvents = null;
|
||||
let conf_editor_schedEvents = null;
|
||||
|
||||
if (window.showOptHelp) {
|
||||
//Operating System Events
|
||||
$('#conf_cont').append(createRow('conf_cont_os_events'));
|
||||
$('#conf_cont_os_events').append(createOptPanel('fa-laptop', $.i18n("conf_os_events_heading_title"), 'editor_container_os_events', 'btn_submit_os_events', 'panel-system'));
|
||||
$('#conf_cont_os_events').append(createHelpTable(window.schema.osEvents.properties, $.i18n("conf_os_events_heading_title")));
|
||||
|
||||
//Scheduled Events
|
||||
$('#conf_cont').append(createRow('conf_cont_sched_events'));
|
||||
$('#conf_cont_sched_events').append(createOptPanel('fa-laptop', $.i18n("conf_sched_events_heading_title"), 'editor_container_sched_events', 'btn_submit_sched_events', 'panel-system'));
|
||||
$('#conf_cont_sched_events').append(createHelpTable(window.schema.schedEvents.properties, $.i18n("conf_sched_events_heading_title")));
|
||||
|
||||
|
||||
//CEC Events
|
||||
if (CEC_ENABLED) {
|
||||
$('#conf_cont').append(createRow('conf_cont_event_cec'));
|
||||
$('#conf_cont_event_cec').append(createOptPanel('fa-tv', $.i18n("conf_cec_events_heading_title"), 'editor_container_cec_events', 'btn_submit_cec_events', 'panel-system'));
|
||||
$('#conf_cont_event_cec').append(createHelpTable(window.schema.cecEvents.properties, $.i18n("conf_cec_events_heading_title"), "cecEventsHelpPanelId"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#conf_cont').addClass('row');
|
||||
$('#conf_cont').append(createOptPanel('fa-laptop', $.i18n("conf_os_events_heading_title"), 'editor_container_os_events', 'btn_submit_os_events'));
|
||||
$('#conf_cont').append(createOptPanel('fa-laptop', $.i18n("conf_sched_events_heading_title"), 'editor_container_sched_events', 'btn_submit_sched_events'));
|
||||
if (CEC_ENABLED) {
|
||||
$('#conf_cont').append(createOptPanel('fa-tv', $.i18n("conf_cec_events_heading_title"), 'editor_container_cec_events', 'btn_submit_cec_events'));
|
||||
}
|
||||
}
|
||||
|
||||
function findDuplicateEventsIndices(data) {
|
||||
const eventIndices = {};
|
||||
data.forEach((item, index) => {
|
||||
const event = item.event;
|
||||
if (!eventIndices[event]) {
|
||||
eventIndices[event] = [index];
|
||||
} else {
|
||||
eventIndices[event].push(index);
|
||||
}
|
||||
});
|
||||
|
||||
return Object.values(eventIndices).filter(indices => indices.length > 1);
|
||||
}
|
||||
|
||||
JSONEditor.defaults.custom_validators.push(function (schema, value, path) {
|
||||
let errors = [];
|
||||
if (schema.type === 'array' && Array.isArray(value)) {
|
||||
const duplicateEventIndices = findDuplicateEventsIndices(value);
|
||||
|
||||
if (duplicateEventIndices.length > 0) {
|
||||
|
||||
let recs;
|
||||
duplicateEventIndices.forEach(indices => {
|
||||
const displayIndices = indices.map(index => index + 1);
|
||||
recs = displayIndices.join(', ');
|
||||
});
|
||||
|
||||
errors.push({
|
||||
path: path,
|
||||
message: $.i18n('edt_conf_action_record_validation_error', recs)
|
||||
});
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
});
|
||||
|
||||
//Operating System Events
|
||||
conf_editor_osEvents = createJsonEditor('editor_container_os_events', {
|
||||
osEvents: window.schema.osEvents
|
||||
}, true, true);
|
||||
|
||||
conf_editor_osEvents.on('ready', function () {
|
||||
if (!isGuiMode) {
|
||||
showInputOptionsForKey(conf_editor_osEvents, "osEvents", "suspendEnable", false);
|
||||
}
|
||||
});
|
||||
|
||||
conf_editor_osEvents.on('change', function () {
|
||||
conf_editor_osEvents.validate().length || window.readOnlyMode ? $('#btn_submit_os_events').prop('disabled', true) : $('#btn_submit_os_events').prop('disabled', false);
|
||||
});
|
||||
|
||||
$('#btn_submit_os_events').off().on('click', function () {
|
||||
requestWriteConfig(conf_editor_osEvents.getValue());
|
||||
});
|
||||
|
||||
//Scheduled Events
|
||||
conf_editor_schedEvents = createJsonEditor('editor_container_sched_events', {
|
||||
schedEvents: window.schema.schedEvents
|
||||
}, true, true);
|
||||
|
||||
conf_editor_schedEvents.on('change', function () {
|
||||
|
||||
const schedEventsEnable = conf_editor_schedEvents.getEditor("root.schedEvents.enable").getValue();
|
||||
|
||||
if (schedEventsEnable) {
|
||||
showInputOptionsForKey(conf_editor_schedEvents, "schedEvents", "enable", true);
|
||||
$('#schedEventsHelpPanelId').show();
|
||||
} else {
|
||||
showInputOptionsForKey(conf_editor_schedEvents, "schedEvents", "enable", false);
|
||||
$('#schedEventsHelpPanelId').hide();
|
||||
}
|
||||
|
||||
conf_editor_schedEvents.validate().length || window.readOnlyMode ? $('#btn_submit_sched_events').prop('disabled', true) : $('#btn_submit_sched_events').prop('disabled', false);
|
||||
});
|
||||
|
||||
$('#btn_submit_sched_events').off().on('click', function () {
|
||||
|
||||
const saveOptions = conf_editor_schedEvents.getValue();
|
||||
// Workaround, as otherwise values are not reflected correctly
|
||||
saveOptions.schedEvents.enable = conf_editor_schedEvents.getEditor("root.schedEvents.enable").getValue();
|
||||
saveOptions.schedEvents.actions = conf_editor_schedEvents.getEditor("root.schedEvents.actions").getValue();
|
||||
requestWriteConfig(saveOptions);
|
||||
});
|
||||
|
||||
//CEC Events
|
||||
if (CEC_ENABLED) {
|
||||
conf_editor_cecEvents = createJsonEditor('editor_container_cec_events', {
|
||||
cecEvents: window.schema.cecEvents
|
||||
}, true, true);
|
||||
|
||||
conf_editor_cecEvents.on('change', function () {
|
||||
|
||||
const cecEventsEnable = conf_editor_cecEvents.getEditor("root.cecEvents.enable").getValue();
|
||||
|
||||
if (cecEventsEnable) {
|
||||
showInputOptionsForKey(conf_editor_cecEvents, "cecEvents", "enable", true);
|
||||
$('#cecEventsHelpPanelId').show();
|
||||
} else {
|
||||
showInputOptionsForKey(conf_editor_cecEvents, "cecEvents", "enable", false);
|
||||
$('#cecEventsHelpPanelId').hide();
|
||||
}
|
||||
|
||||
conf_editor_cecEvents.validate().length || window.readOnlyMode ? $('#btn_submit_cec_events').prop('disabled', true) : $('#btn_submit_cec_events').prop('disabled', false);
|
||||
});
|
||||
|
||||
$('#btn_submit_cec_events').off().on('click', function () {
|
||||
|
||||
const saveOptions = conf_editor_cecEvents.getValue();
|
||||
// Workaround, as otherwise values are not reflected correctly
|
||||
saveOptions.cecEvents.enable = conf_editor_cecEvents.getEditor("root.cecEvents.enable").getValue();
|
||||
saveOptions.cecEvents.actions = conf_editor_cecEvents.getEditor("root.cecEvents.actions").getValue();
|
||||
requestWriteConfig(saveOptions);
|
||||
});
|
||||
}
|
||||
|
||||
//create introduction
|
||||
if (window.showOptHelp) {
|
||||
createHint("intro", $.i18n('conf_os_events_intro'), "editor_container_os_events");
|
||||
if (CEC_ENABLED) {
|
||||
createHint("intro", $.i18n('conf_cec_events_intro'), "editor_container_cec_events");
|
||||
}
|
||||
}
|
||||
|
||||
removeOverlay();
|
||||
});
|
||||
|
@@ -5,7 +5,6 @@ $(document).ready(function () {
|
||||
var screenGrabberAvailable = (window.serverInfo.grabbers.screen.available.length !== 0);
|
||||
var videoGrabberAvailable = (window.serverInfo.grabbers.video.available.length !== 0);
|
||||
const audioGrabberAvailable = (window.serverInfo.grabbers.audio.available.length !== 0);
|
||||
var CEC_ENABLED = (jQuery.inArray("cec", window.serverInfo.services) !== -1);
|
||||
|
||||
var conf_editor_video = null;
|
||||
var conf_editor_audio = null;
|
||||
@@ -327,7 +326,7 @@ $(document).ready(function () {
|
||||
var saveOptions = conf_editor_screen.getValue();
|
||||
|
||||
var instCaptOptions = window.serverConfig.instCapture;
|
||||
instCaptOptions.systemEnable = true;
|
||||
instCaptOptions.systemEnable = saveOptions.framegrabber.enable;
|
||||
saveOptions.instCapture = instCaptOptions;
|
||||
|
||||
requestWriteConfig(saveOptions);
|
||||
@@ -369,11 +368,6 @@ $(document).ready(function () {
|
||||
|
||||
conf_editor_video.on('change', function () {
|
||||
|
||||
// Hide elements not supported by the backend
|
||||
if (window.serverInfo.cec.enabled === false || !CEC_ENABLED) {
|
||||
showInputOptionForItem(conf_editor_video, "grabberV4L2", "cecDetection", false);
|
||||
}
|
||||
|
||||
// Validate the current editor's content
|
||||
if (!conf_editor_video.validate().length) {
|
||||
var deviceSelected = conf_editor_video.getEditor("root.grabberV4L2.available_devices").getValue();
|
||||
@@ -679,7 +673,7 @@ $(document).ready(function () {
|
||||
var saveOptions = conf_editor_video.getValue();
|
||||
|
||||
var instCaptOptions = window.serverConfig.instCapture;
|
||||
instCaptOptions.v4lEnable = true;
|
||||
instCaptOptions.v4lEnable = saveOptions.grabberV4L2.enable;
|
||||
saveOptions.instCapture = instCaptOptions;
|
||||
|
||||
requestWriteConfig(saveOptions);
|
||||
@@ -805,7 +799,7 @@ $(document).ready(function () {
|
||||
const saveOptions = conf_editor_audio.getValue();
|
||||
|
||||
const instCaptOptions = window.serverConfig.instCapture;
|
||||
instCaptOptions.audioEnable = true;
|
||||
instCaptOptions.audioEnable = saveOptions.grabberAudio.enable;
|
||||
saveOptions.instCapture = instCaptOptions;
|
||||
|
||||
requestWriteConfig(saveOptions);
|
||||
|
@@ -218,7 +218,9 @@ $(document).ready(function () {
|
||||
loadContent(undefined,true);
|
||||
|
||||
//Hide capture menu entries, if no grabbers are available
|
||||
if ((window.serverInfo.grabbers.screen.available.length === 0) && (window.serverInfo.grabbers.video.available.length === 0)) {
|
||||
if ((window.serverInfo.grabbers.screen.available.length === 0) &&
|
||||
(window.serverInfo.grabbers.video.available.length === 0) &&
|
||||
(window.serverInfo.grabbers.audio.available.length === 0)) {
|
||||
$("#MenuItemGrabber").attr('style', 'display:none')
|
||||
if ((jQuery.inArray("boblight", window.serverInfo.services) === -1)) {
|
||||
$("#MenuItemInstCapture").attr('style', 'display:none')
|
||||
|
@@ -1021,11 +1021,6 @@ $(document).ready(function () {
|
||||
var generalOptions = window.serverSchema.properties.device;
|
||||
|
||||
var ledType = $(this).val();
|
||||
|
||||
// philipshueentertainment backward fix
|
||||
if (ledType == "philipshueentertainment")
|
||||
ledType = "philipshue";
|
||||
|
||||
var specificOptions = window.serverSchema.properties.alldevices[ledType];
|
||||
|
||||
conf_editor = createJsonEditor('editor_container_leddevice', {
|
||||
@@ -1055,18 +1050,22 @@ $(document).ready(function () {
|
||||
// change save button state based on validation result
|
||||
conf_editor.validate().length || window.readOnlyMode ? $('#btn_submit_controller').prop('disabled', true) : $('#btn_submit_controller').prop('disabled', false);
|
||||
|
||||
// led controller sepecific wizards
|
||||
// LED controller specific wizards
|
||||
$('#btn_wiz_holder').html("");
|
||||
$('#btn_led_device_wiz').off();
|
||||
|
||||
if (ledType == "philipshue") {
|
||||
$('#root_specificOptions_useEntertainmentAPI').on("change", function () {
|
||||
var ledWizardType = (this.checked) ? "philipshueentertainment" : ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var hue_title = (this.checked) ? 'wiz_hue_e_title' : 'wiz_hue_title';
|
||||
changeWizard(data, hue_title, startWizardPhilipsHue);
|
||||
});
|
||||
$("#root_specificOptions_useEntertainmentAPI").trigger("change");
|
||||
var ledWizardType = ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var hue_title = 'wiz_hue_title';
|
||||
changeWizard(data, hue_title, startWizardPhilipsHue);
|
||||
}
|
||||
else if (ledType == "nanoleaf") {
|
||||
var ledWizardType = ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var nanoleaf_user_auth_title = 'wiz_nanoleaf_user_auth_title';
|
||||
changeWizard(data, nanoleaf_user_auth_title, startWizardNanoleafUserAuth);
|
||||
$('#btn_wiz_holder').hide();
|
||||
}
|
||||
else if (ledType == "atmoorb") {
|
||||
var ledWizardType = (this.checked) ? "atmoorb" : ledType;
|
||||
@@ -1092,6 +1091,7 @@ $(document).ready(function () {
|
||||
var colorOrderDefault = "rgb";
|
||||
var filter = {};
|
||||
|
||||
$('#btn_layout_controller').hide();
|
||||
$('#btn_test_controller').hide();
|
||||
|
||||
switch (ledType) {
|
||||
@@ -1349,6 +1349,13 @@ $(document).ready(function () {
|
||||
|
||||
if (host === "") {
|
||||
conf_editor.getEditor("root.generalOptions.hardwareLedCount").setValue(1);
|
||||
switch (ledType) {
|
||||
|
||||
case "nanoleaf":
|
||||
$('#btn_wiz_holder').hide();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
else {
|
||||
let params = {};
|
||||
@@ -1360,6 +1367,8 @@ $(document).ready(function () {
|
||||
break;
|
||||
|
||||
case "nanoleaf":
|
||||
$('#btn_wiz_holder').show();
|
||||
|
||||
var token = conf_editor.getEditor("root.specificOptions.token").getValue();
|
||||
if (token === "") {
|
||||
return;
|
||||
@@ -1676,6 +1685,33 @@ $(document).ready(function () {
|
||||
$("#leddevices").val(window.serverConfig.device.type);
|
||||
$("#leddevices").trigger("change");
|
||||
|
||||
// Generate layout for LED-Device
|
||||
$("#btn_layout_controller").off().on("click", function () {
|
||||
var ledType = $("#leddevices").val();
|
||||
var isGenerated = false;
|
||||
|
||||
switch (ledType) {
|
||||
case "nanoleaf":
|
||||
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
var ledDeviceProperties = devicesProperties[ledType][host];
|
||||
if (ledDeviceProperties) {
|
||||
var panelOrderTopDown = conf_editor.getEditor("root.specificOptions.panelOrderTopDown").getValue() === "top2down";
|
||||
var panelOrderLeftRight = conf_editor.getEditor("root.specificOptions.panelOrderLeftRight").getValue() === "left2right";
|
||||
var ledArray = nanoleafGeneratelayout(ledDeviceProperties.panelLayout, panelOrderTopDown, panelOrderLeftRight);
|
||||
aceEdt.set(ledArray);
|
||||
isGenerated = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if (isGenerated) {
|
||||
showInfoDialog('success', "", $.i18n('conf_leds_layout_generation_success'));
|
||||
} else {
|
||||
showInfoDialog('error', "", $.i18n('conf_leds_layout_generation_error'));
|
||||
}
|
||||
});
|
||||
|
||||
// Identify/ Test LED-Device
|
||||
$("#btn_test_controller").off().on("click", function () {
|
||||
var ledType = $("#leddevices").val();
|
||||
@@ -2069,7 +2105,7 @@ var updateOutputSelectList = function (ledType, discoveryInfo) {
|
||||
case "devRPiPWM":
|
||||
key = ledType;
|
||||
|
||||
if (discoveryInfo.devices.length == 0) {
|
||||
if (!discoveryInfo.isUserAdmin) {
|
||||
enumVals.push("NONE");
|
||||
enumTitleVals.push($.i18n('edt_dev_spec_devices_discovered_none'));
|
||||
$('#btn_submit_controller').prop('disabled', true);
|
||||
@@ -2155,6 +2191,7 @@ async function identify_device(type, params) {
|
||||
}
|
||||
|
||||
function updateElements(ledType, key) {
|
||||
var canLayout = false;
|
||||
if (devicesProperties[ledType][key]) {
|
||||
var hardwareLedCount = 1;
|
||||
switch (ledType) {
|
||||
@@ -2173,18 +2210,11 @@ function updateElements(ledType, key) {
|
||||
case "nanoleaf":
|
||||
var ledProperties = devicesProperties[ledType][key];
|
||||
|
||||
if (ledProperties && ledProperties.panelLayout.layout) {
|
||||
//Identify non-LED type panels, e.g. Rhythm (1) and Shapes Controller (12)
|
||||
var nonLedNum = 0;
|
||||
for (const panel of ledProperties.panelLayout.layout.positionData) {
|
||||
if (panel.shapeType === 1 || panel.shapeType === 12) {
|
||||
nonLedNum++;
|
||||
}
|
||||
}
|
||||
hardwareLedCount = ledProperties.panelLayout.layout.numPanels - nonLedNum;
|
||||
if (ledProperties) {
|
||||
hardwareLedCount = ledProperties.ledCount;
|
||||
canLayout = true;
|
||||
}
|
||||
conf_editor.getEditor("root.generalOptions.hardwareLedCount").setValue(hardwareLedCount);
|
||||
|
||||
break;
|
||||
|
||||
case "udpraw":
|
||||
@@ -2233,11 +2263,19 @@ function updateElements(ledType, key) {
|
||||
}
|
||||
|
||||
if (!conf_editor.validate().length) {
|
||||
if (canLayout) {
|
||||
$("#btn_layout_controller").show();
|
||||
$('#btn_layout_controller').prop('disabled', false);
|
||||
} else {
|
||||
$('#btn_layout_controller').hide();
|
||||
}
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_submit_controller').attr('disabled', false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#btn_layout_controller').prop('disabled', true);
|
||||
$('#btn_submit_controller').attr('disabled', true);
|
||||
}
|
||||
}
|
||||
@@ -2331,6 +2369,7 @@ function updateElementsWled(ledType, key) {
|
||||
var enumSegSelectVals = [];
|
||||
var enumSegSelectTitleVals = [];
|
||||
var enumSegSelectDefaultVal = "";
|
||||
var defaultSegmentId = "-1";
|
||||
|
||||
if (devicesProperties[ledType] && devicesProperties[ledType][key]) {
|
||||
var ledDeviceProperties = devicesProperties[ledType][key];
|
||||
@@ -2338,9 +2377,8 @@ function updateElementsWled(ledType, key) {
|
||||
if (!jQuery.isEmptyObject(ledDeviceProperties)) {
|
||||
|
||||
if (ledDeviceProperties.info) {
|
||||
if (ledDeviceProperties.info.liveseg && ledDeviceProperties.info.liveseg < 0) {
|
||||
if (!ledDeviceProperties.info.hasOwnProperty("liveseg") || ledDeviceProperties.info.liveseg < 0) {
|
||||
// "Use main segment only" is disabled
|
||||
var defaultSegmentId = "-1";
|
||||
enumSegSelectVals.push(defaultSegmentId);
|
||||
enumSegSelectTitleVals.push($.i18n('edt_dev_spec_segments_disabled_title'));
|
||||
enumSegSelectDefaultVal = defaultSegmentId;
|
||||
@@ -2392,13 +2430,12 @@ function updateElementsWled(ledType, key) {
|
||||
hardwareLedCount = 1;
|
||||
}
|
||||
|
||||
if (segmentConfig) {
|
||||
if (segmentConfig && segmentConfig.streamSegmentId > defaultSegmentId) {
|
||||
var configuredstreamSegmentId = window.serverConfig.device.segments.streamSegmentId.toString();
|
||||
enumSegSelectVals = [configuredstreamSegmentId];
|
||||
enumSegSelectTitleVals = ["Segment " + configuredstreamSegmentId];
|
||||
enumSegSelectDefaultVal = configuredstreamSegmentId;
|
||||
} else {
|
||||
defaultSegmentId = "-1";
|
||||
enumSegSelectVals.push(defaultSegmentId);
|
||||
enumSegSelectTitleVals.push($.i18n('edt_dev_spec_segments_disabled_title'));
|
||||
enumSegSelectDefaultVal = defaultSegmentId;
|
||||
@@ -2416,4 +2453,149 @@ function updateElementsWled(ledType, key) {
|
||||
}
|
||||
showInputOptionForItem(conf_editor, "root.specificOptions.segments", "switchOffOtherSegments", showAdditionalOptions);
|
||||
}
|
||||
function sortByPanelCoordinates(arr, topToBottom, leftToRight) {
|
||||
arr.sort((a, b) => {
|
||||
//Nanoleaf corodinates start at bottom left, therefore reverse topToBottom
|
||||
if (!topToBottom) {
|
||||
if (a.y === b.y) {
|
||||
if (leftToRight) {
|
||||
return a.x - b.x;
|
||||
} else {
|
||||
return b.x - a.x;
|
||||
}
|
||||
} else {
|
||||
return a.y - b.y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (a.y === b.y) {
|
||||
if (leftToRight) {
|
||||
return a.x - b.x;
|
||||
} else {
|
||||
return b.x - a.x;
|
||||
}
|
||||
} else {
|
||||
return b.y - a.y;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function rotateCoordinates(x, y, radians) {
|
||||
var rotatedX = x * Math.cos(radians) - y * Math.sin(radians);
|
||||
var rotatedY = x * Math.sin(radians) + y * Math.cos(radians);
|
||||
|
||||
return { x: rotatedX, y: rotatedY };
|
||||
}
|
||||
|
||||
function nanoleafGeneratelayout(panelLayout, panelOrderTopDown, panelOrderLeftRight) {
|
||||
|
||||
// Dictionary for Nanoleaf shape types
|
||||
let shapeTypes = {
|
||||
0: { name: "LightsTriangle", led: true, sideLengthX: 150, sideLengthY: 150 },
|
||||
1: { name: "LightsRythm", led: false, sideLengthX: 0, sideLengthY: 0 },
|
||||
2: { name: "Square", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||
3: { name: "SquareControllerMaster", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||
4: { name: "SquareControllerPassive", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||
5: { name: "PowerSupply", led: true, sideLengthX: 100, sideLengthY: 100 },
|
||||
7: { name: "ShapesHexagon", led: true, sideLengthX: 67, sideLengthY: 67 },
|
||||
8: { name: "ShapesTriangle", led: true, sideLengthX: 134, sideLengthY: 134 },
|
||||
9: { name: "ShapesMiniTriangle", led: true, sideLengthX: 67, sideLengthY: 67 },
|
||||
12: { name: "ShapesController", led: false, sideLengthX: 0, sideLengthY: 0 },
|
||||
14: { name: "ElementsHexagon", led: true, sideLengthX: 134, sideLengthY: 134 },
|
||||
15: { name: "ElementsHexagonCorner", led: true, sideLengthX: 33.5, sideLengthY: 58 },
|
||||
16: { name: "LinesConnector", led: false, sideLengthX: 11, sideLengthY: 11 },
|
||||
17: { name: "LightLines", led: true, sideLengthX: 154, sideLengthY: 154 },
|
||||
18: { name: "LightLinesSingleZone", led: true, sideLengthX: 77, sideLengthY: 77 },
|
||||
19: { name: "ControllerCap", led: false, sideLengthX: 11, sideLengthY: 11 },
|
||||
20: { name: "PowerConnector", led: false, sideLengthX: 11, sideLengthY: 11 },
|
||||
999: { name: "Unknown", led: true, sideLengthX: 100, sideLengthY: 100 }
|
||||
};
|
||||
|
||||
let { globalOrientation, layout } = panelLayout;
|
||||
|
||||
var degreesToRotate = 0;
|
||||
if (globalOrientation) {
|
||||
degreesToRotate = globalOrientation.value;
|
||||
}
|
||||
|
||||
//Align rotation degree to 15 degree steps
|
||||
const degreeSteps = 15;
|
||||
var degreeRounded = ((Math.round(degreesToRotate / degreeSteps) * degreeSteps) + 360) % 360;
|
||||
|
||||
//Nanoleaf orientation is counter-clockwise
|
||||
degreeRounded *= -1;
|
||||
|
||||
// Convert degrees to radians
|
||||
const radians = (degreeRounded * Math.PI) / 180;
|
||||
|
||||
//Reduce the capture area
|
||||
const areaSizeFactor = 0.5;
|
||||
|
||||
var panelDataXY = [...layout.positionData];
|
||||
panelDataXY.forEach(panel => {
|
||||
|
||||
if (shapeTypes[panel.shapeType] == undefined) {
|
||||
panel.shapeType = 999;
|
||||
}
|
||||
|
||||
panel.shapeName = shapeTypes[panel.shapeType].name;
|
||||
panel.led = shapeTypes[panel.shapeType].led;
|
||||
panel.areaWidth = shapeTypes[panel.shapeType].sideLengthX * areaSizeFactor;
|
||||
panel.areaHeight = shapeTypes[panel.shapeType].sideLengthY * areaSizeFactor;
|
||||
|
||||
if (radians !== 0) {
|
||||
var rotatedXY = rotateCoordinates(panel.x, panel.y, radians);
|
||||
panel.x = Math.round(rotatedXY.x);
|
||||
panel.y = Math.round(rotatedXY.y);
|
||||
}
|
||||
|
||||
panel.maxX = panel.x + panel.areaWidth;
|
||||
panel.maxY = panel.y + panel.areaHeight;
|
||||
});
|
||||
|
||||
var minX = panelDataXY[0].x;
|
||||
var maxX = panelDataXY[0].x;
|
||||
var minY = panelDataXY[0].y;
|
||||
var maxY = panelDataXY[0].y;
|
||||
panelDataXY.forEach(panel => {
|
||||
|
||||
if (panel.maxX > maxX) {
|
||||
maxX = panel.maxX;
|
||||
}
|
||||
if (panel.x < minX) {
|
||||
minX = panel.x;
|
||||
}
|
||||
if (panel.maxY > maxY) {
|
||||
maxY = panel.maxY;
|
||||
}
|
||||
if (panel.y < minY) {
|
||||
minY = panel.y;
|
||||
}
|
||||
});
|
||||
|
||||
const width = Math.abs(maxX - minX);
|
||||
const height = Math.abs(maxY - minY);
|
||||
const scaleX = 1 / width;
|
||||
const scaleY = 1 / height;
|
||||
|
||||
var layoutObjects = [];
|
||||
var i = 0;
|
||||
|
||||
sortByPanelCoordinates(panelDataXY, panelOrderTopDown, panelOrderLeftRight);
|
||||
panelDataXY.forEach(panel => {
|
||||
|
||||
if (panel.led) {
|
||||
let layoutObject = {
|
||||
name: i + "-" + panel.panelId,
|
||||
hmin: Math.min(1, Math.max(0, (panel.x - minX) * scaleX)),
|
||||
hmax: Math.min(1, Math.max(0, (panel.x - minX + panel.areaWidth) * scaleX)),
|
||||
//Nanoleaf corodinates start at bottom left, therefore reverse vertical positioning
|
||||
vmax: (1 - Math.min(1, Math.max(0, (panel.y - minY) * scaleY))),
|
||||
vmin: (1 - Math.min(1, Math.max(0, (panel.y - minY + panel.areaHeight) * scaleY)))
|
||||
};
|
||||
layoutObjects.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
++i;
|
||||
}
|
||||
});
|
||||
return layoutObjects;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
var storedLang;
|
||||
var availLang = ['ca', 'cs', 'da', 'de', 'el', 'en', 'es', 'fr', 'hu', 'it', 'ja', 'nl', 'nb', 'pl', 'pt', 'ro', 'sv', 'vi', 'ru', 'tr', 'zh-CN'];
|
||||
var availLangText = ['Català', 'Čeština', 'Dansk', 'Deutsch', 'Ελληνική', 'English', 'Español', 'Français', 'Magyar', 'Italiano', '日本語', 'Nederlands', 'Norsk Bokmål', 'Polski', 'Português', 'Română', 'Svenska', 'Tiếng Việt', 'русский', 'Türkçe', '汉语'];
|
||||
var availLang = ['ca', 'cs', 'da', 'de', 'el', 'en', 'es', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nl', 'nb', 'pl', 'pt', 'ro', 'ru', 'sv', 'tr', 'uk', 'vi', 'zh-CN'];
|
||||
var availLangText = ['Català', 'Čeština', 'Dansk', 'Deutsch', 'Ελληνική', 'English', 'Español', 'Français', 'עִברִית' ,'Magyar', 'Indonesia', 'Italiano', '日本語', 'Nederlands', 'Norsk Bokmål', 'Polski', 'Português', 'Română', 'русский', 'Svenska', 'Türkçe', 'Українська', 'Tiếng Việt', '汉语'];
|
||||
|
||||
//$.i18n.debug = true;
|
||||
|
||||
|
@@ -1224,6 +1224,7 @@ function getSystemInfo() {
|
||||
info += '- Avail Services: ' + window.serverInfo.services + '\n';
|
||||
info += '- Config path: ' + shy.rootPath + '\n';
|
||||
info += '- Database: ' + (shy.readOnlyMode ? "ready-only" : "read/write") + '\n';
|
||||
info += '- Mode: ' + (shy.isGuiMode ? "GUI" : "Non-GUI") + '\n';
|
||||
|
||||
info += '\n';
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user