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 ftdi_basic
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);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
$(document).ready( function() {
|
||||
|
||||
$("#create_user").on("click", function() {
|
||||
var connectionRetries = 15;
|
||||
var data = {"devicetype":"hyperion#"+Date.now()};
|
||||
var UserInterval = setInterval(function(){
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'http://'+$("#ip").val()+'/api',
|
||||
processData: false,
|
||||
timeout: 1000,
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function(r) {
|
||||
connectionRetries--;
|
||||
$("#connectionTime").html(connectionRetries);
|
||||
if(connectionRetries == 0) {
|
||||
abortConnection(UserInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#abortConnection").hide();
|
||||
$('#pairmodal').modal('show');
|
||||
$("#ip_alert").hide();
|
||||
if (typeof r[0].error != 'undefined') {
|
||||
console.log("link not pressed");
|
||||
}
|
||||
if (typeof r[0].success != 'undefined') {
|
||||
$('#pairmodal').modal('hide');
|
||||
$('#user').val(r[0].success.username);
|
||||
|
||||
$( "#hue_lights" ).empty();
|
||||
get_hue_lights();
|
||||
clearInterval(UserInterval);
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function(XMLHttpRequest, textStatus, errorThrown) {
|
||||
$("#ip_alert").show();
|
||||
clearInterval(UserInterval);
|
||||
}
|
||||
});
|
||||
},1000);
|
||||
});
|
||||
|
||||
function abortConnection(UserInterval){
|
||||
clearInterval(UserInterval);
|
||||
$("#abortConnection").show();
|
||||
$('#pairmodal').modal('hide');
|
||||
}
|
||||
|
||||
});
|
||||
@@ -73,26 +73,30 @@ $(document).ready(function () {
|
||||
//End language selection
|
||||
|
||||
$(window.hyperion).on("cmd-authorize-tokenRequest cmd-authorize-getPendingTokenRequests", function (event) {
|
||||
var val = event.response.info;
|
||||
if (Array.isArray(event.response.info)) {
|
||||
if (event.response.info.length == 0) {
|
||||
return
|
||||
}
|
||||
val = event.response.info[0]
|
||||
if (val.comment == '')
|
||||
$('#modal_dialog').modal('hide');
|
||||
}
|
||||
|
||||
showInfoDialog("grantToken", $.i18n('conf_network_tok_grantT'), $.i18n('conf_network_tok_grantMsg') + '<br><span style="font-weight:bold">App: ' + val.comment + '</span><br><span style="font-weight:bold">Code: ' + val.id + '</span>')
|
||||
$("#tok_grant_acc").off().on('click', function () {
|
||||
tokenList.push(val)
|
||||
// forward event, in case we need to rebuild the list now
|
||||
$(window.hyperion).trigger({ type: "build-token-list" });
|
||||
requestHandleTokenRequest(val.id, true)
|
||||
});
|
||||
$("#tok_deny_acc").off().on('click', function () {
|
||||
requestHandleTokenRequest(val.id, false)
|
||||
});
|
||||
if (event.response && event.response.info !== undefined) {
|
||||
var val = event.response.info;
|
||||
|
||||
if (Array.isArray(event.response.info)) {
|
||||
if (event.response.info.length == 0) {
|
||||
return
|
||||
}
|
||||
val = event.response.info[0]
|
||||
if (val.comment == '')
|
||||
$('#modal_dialog').modal('hide');
|
||||
}
|
||||
|
||||
showInfoDialog("grantToken", $.i18n('conf_network_tok_grantT'), $.i18n('conf_network_tok_grantMsg') + '<br><span style="font-weight:bold">App: ' + val.comment + '</span><br><span style="font-weight:bold">Code: ' + val.id + '</span>')
|
||||
$("#tok_grant_acc").off().on('click', function () {
|
||||
tokenList.push(val)
|
||||
// forward event, in case we need to rebuild the list now
|
||||
$(window.hyperion).trigger({ type: "build-token-list" });
|
||||
requestHandleTokenRequest(val.id, true)
|
||||
});
|
||||
$("#tok_deny_acc").off().on('click', function () {
|
||||
requestHandleTokenRequest(val.id, false)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(window.hyperion).one("cmd-authorize-getTokenList", function (event) {
|
||||
@@ -186,21 +190,12 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
|
||||
$(window.hyperion).on("cmd-authorize-adminRequired", function (event) {
|
||||
//Check if a admin login is required.
|
||||
//If yes: check if default pw is set. If no: go ahead to get server config and render page
|
||||
if (event.response.info.adminRequired === true)
|
||||
requestRequiresDefaultPasswortChange();
|
||||
else
|
||||
requestServerConfigSchema();
|
||||
});
|
||||
|
||||
$(window.hyperion).on("error", function (event) {
|
||||
//If we are getting an error "No Authorization" back with a set loginToken we will forward to new Login (Token is expired.
|
||||
//e.g.: hyperiond was started new in the meantime)
|
||||
if (event.reason == "No Authorization" && getStorage("loginToken")) {
|
||||
removeStorage("loginToken");
|
||||
requestRequiresAdminAuth();
|
||||
requestRequiresDefaultPasswortChange();
|
||||
}
|
||||
else if (event.reason == "Selected Hyperion instance isn't running") {
|
||||
//Switch to default instance
|
||||
@@ -211,14 +206,16 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
$(window.hyperion).on("open", function (event) {
|
||||
requestRequiresAdminAuth();
|
||||
requestRequiresDefaultPasswortChange();
|
||||
});
|
||||
|
||||
$(window.hyperion).on("ready", function (event) {
|
||||
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')
|
||||
|
||||
@@ -469,17 +469,18 @@ function createClassicLeds() {
|
||||
aceEdt.set(finalLedArray);
|
||||
}
|
||||
|
||||
function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction) {
|
||||
function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction, gap) {
|
||||
// Big thank you to RanzQ (Juha Rantanen) from Github for this script
|
||||
// https://raw.githubusercontent.com/RanzQ/hyperion-audio-effects/master/matrix-config.js
|
||||
|
||||
var parallel = false
|
||||
var leds = []
|
||||
var hblock = 1.0 / ledshoriz
|
||||
var vblock = 1.0 / ledsvert
|
||||
let parallel = false;
|
||||
const leds = [];
|
||||
|
||||
const hblock = (1.0 - gap.left - gap.right) / ledshoriz;
|
||||
const vblock = (1.0 - gap.top - gap.bottom) / ledsvert;
|
||||
|
||||
if (cabling == "parallel") {
|
||||
parallel = true
|
||||
parallel = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -488,10 +489,10 @@ function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction) {
|
||||
* @param {Number} y Vertical position in matrix
|
||||
*/
|
||||
function addLed(x, y) {
|
||||
var hscanMin = x * hblock
|
||||
var hscanMax = (x + 1) * hblock
|
||||
var vscanMin = y * vblock
|
||||
var vscanMax = (y + 1) * vblock
|
||||
let hscanMin = gap.left + (x * hblock);
|
||||
let hscanMax = gap.left + (x + 1) * hblock;
|
||||
let vscanMin = gap.top + y * vblock;
|
||||
let vscanMax = gap.top + (y + 1) * vblock;
|
||||
|
||||
hscanMin = round(hscanMin);
|
||||
hscanMax = round(hscanMax);
|
||||
@@ -503,43 +504,41 @@ function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction) {
|
||||
hmax: hscanMax,
|
||||
vmin: vscanMin,
|
||||
vmax: vscanMax
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
var startYX = start.split('-')
|
||||
var startX = startYX[1] === 'right' ? ledshoriz - 1 : 0
|
||||
var startY = startYX[0] === 'bottom' ? ledsvert - 1 : 0
|
||||
var endX = startX === 0 ? ledshoriz - 1 : 0
|
||||
var endY = startY === 0 ? ledsvert - 1 : 0
|
||||
var forward = startX < endX
|
||||
const startYX = start.split('-');
|
||||
let startX = startYX[1] === 'right' ? ledshoriz - 1 : 0;
|
||||
let startY = startYX[0] === 'bottom' ? ledsvert - 1 : 0;
|
||||
let endX = startX === 0 ? ledshoriz - 1 : 0;
|
||||
let endY = startY === 0 ? ledsvert - 1 : 0;
|
||||
let forward = startX < endX;
|
||||
let downward = startY < endY;
|
||||
|
||||
var downward = startY < endY
|
||||
|
||||
var x, y
|
||||
let x, y;
|
||||
|
||||
if (direction === 'vertical') {
|
||||
for (x = startX; forward && x <= endX || !forward && x >= endX; x += forward ? 1 : -1) {
|
||||
for (y = startY; downward && y <= endY || !downward && y >= endY; y += downward ? 1 : -1) {
|
||||
|
||||
addLed(x, y)
|
||||
addLed(x, y);
|
||||
}
|
||||
if (!parallel) {
|
||||
downward = !downward
|
||||
var tmp = startY
|
||||
startY = endY
|
||||
endY = tmp
|
||||
downward = !downward;
|
||||
const tmp = startY;
|
||||
startY = endY;
|
||||
endY = tmp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = startY; downward && y <= endY || !downward && y >= endY; y += downward ? 1 : -1) {
|
||||
for (x = startX; forward && x <= endX || !forward && x >= endX; x += forward ? 1 : -1) {
|
||||
addLed(x, y)
|
||||
addLed(x, y);
|
||||
}
|
||||
if (!parallel) {
|
||||
forward = !forward
|
||||
var tmp = startX
|
||||
startX = endX
|
||||
endX = tmp
|
||||
forward = !forward;
|
||||
const tmp = startX;
|
||||
startX = endX;
|
||||
endX = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -552,13 +551,20 @@ function createMatrixLeds() {
|
||||
// https://raw.githubusercontent.com/RanzQ/hyperion-audio-effects/master/matrix-config.js
|
||||
|
||||
//get values
|
||||
var ledshoriz = parseInt($("#ip_ma_ledshoriz").val());
|
||||
var ledsvert = parseInt($("#ip_ma_ledsvert").val());
|
||||
var cabling = $("#ip_ma_cabling").val();
|
||||
var direction = $("#ip_ma_direction").val();
|
||||
var start = $("#ip_ma_start").val();
|
||||
const ledshoriz = parseInt($("#ip_ma_ledshoriz").val());
|
||||
const ledsvert = parseInt($("#ip_ma_ledsvert").val());
|
||||
const cabling = $("#ip_ma_cabling").val();
|
||||
const direction = $("#ip_ma_direction").val();
|
||||
const start = $("#ip_ma_start").val();
|
||||
const gap = {
|
||||
//gap values % -> float
|
||||
left: parseInt($("#ip_ma_gapleft").val()) / 100,
|
||||
right: parseInt($("#ip_ma_gapright").val()) / 100,
|
||||
top: parseInt($("#ip_ma_gaptop").val()) / 100,
|
||||
bottom: parseInt($("#ip_ma_gapbottom").val()) / 100,
|
||||
};
|
||||
|
||||
nonBlacklistLedArray = createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction);
|
||||
nonBlacklistLedArray = createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction, gap);
|
||||
finalLedArray = blackListLeds(nonBlacklistLedArray, ledBlacklist);
|
||||
|
||||
createLedPreview(finalLedArray);
|
||||
@@ -798,6 +804,35 @@ $(document).ready(function () {
|
||||
|
||||
$('.ledMAconstr').on("change", function () {
|
||||
valValue(this.id, this.value, this.min, this.max);
|
||||
|
||||
// top/bottom and left/right must not overlap
|
||||
switch (this.id) {
|
||||
case "ip_ma_gapleft":
|
||||
let left = 100 - parseInt($("#ip_ma_gapright").val());
|
||||
if (this.value > left) {
|
||||
$(this).val(left);
|
||||
}
|
||||
break;
|
||||
case "ip_ma_gapright":
|
||||
let right = 100 - parseInt($("#ip_ma_gapleft").val());
|
||||
if (this.value > right) {
|
||||
$(this).val(right);
|
||||
}
|
||||
break;
|
||||
case "ip_ma_gaptop":
|
||||
let top = 100 - parseInt($("#ip_ma_gapbottom").val());
|
||||
if (this.value > top) {
|
||||
$(this).val(top);
|
||||
}
|
||||
break;
|
||||
case "ip_ma_gapbottom":
|
||||
let bottom = 100 - parseInt($("#ip_ma_gaptop").val());
|
||||
if (this.value > bottom) {
|
||||
$(this).val(bottom);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
createMatrixLeds();
|
||||
});
|
||||
|
||||
@@ -1019,33 +1054,28 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
$("#leddevices").off().on("change", function () {
|
||||
var generalOptions = window.serverSchema.properties.device;
|
||||
const generalOptions = window.serverSchema.properties.device;
|
||||
|
||||
var ledType = $(this).val();
|
||||
|
||||
// philipshueentertainment backward fix
|
||||
if (ledType == "philipshueentertainment")
|
||||
ledType = "philipshue";
|
||||
|
||||
var specificOptions = window.serverSchema.properties.alldevices[ledType];
|
||||
const ledType = $(this).val();
|
||||
const specificOptions = window.serverSchema.properties.alldevices[ledType];
|
||||
|
||||
conf_editor = createJsonEditor('editor_container_leddevice', {
|
||||
specificOptions: specificOptions,
|
||||
generalOptions: generalOptions,
|
||||
});
|
||||
|
||||
var values_general = {};
|
||||
var values_specific = {};
|
||||
var isCurrentDevice = (window.serverConfig.device.type == ledType);
|
||||
let values_general = {};
|
||||
let values_specific = {};
|
||||
const isCurrentDevice = (window.serverConfig.device.type == ledType);
|
||||
|
||||
for (var key in window.serverConfig.device) {
|
||||
for (const key in window.serverConfig.device) {
|
||||
if (key != "type" && key in generalOptions.properties) values_general[key] = window.serverConfig.device[key];
|
||||
};
|
||||
conf_editor.getEditor("root.generalOptions").setValue(values_general);
|
||||
|
||||
if (isCurrentDevice) {
|
||||
var specificOptions_val = conf_editor.getEditor("root.specificOptions").getValue();
|
||||
for (var key in specificOptions_val) {
|
||||
const specificOptions_val = conf_editor.getEditor("root.specificOptions").getValue();
|
||||
for (const key in specificOptions_val) {
|
||||
values_specific[key] = (key in window.serverConfig.device) ? window.serverConfig.device[key] : specificOptions_val[key];
|
||||
};
|
||||
conf_editor.getEditor("root.specificOptions").setValue(values_specific);
|
||||
@@ -1056,43 +1086,15 @@ $(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
|
||||
$('#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");
|
||||
}
|
||||
else if (ledType == "atmoorb") {
|
||||
var ledWizardType = (this.checked) ? "atmoorb" : ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var atmoorb_title = 'wiz_atmoorb_title';
|
||||
changeWizard(data, atmoorb_title, startWizardAtmoOrb);
|
||||
}
|
||||
else if (ledType == "yeelight") {
|
||||
var ledWizardType = (this.checked) ? "yeelight" : ledType;
|
||||
var data = { type: ledWizardType };
|
||||
var yeelight_title = 'wiz_yeelight_title';
|
||||
changeWizard(data, yeelight_title, startWizardYeelight);
|
||||
}
|
||||
|
||||
function changeWizard(data, hint, fn) {
|
||||
$('#btn_wiz_holder').html("")
|
||||
createHint("wizard", $.i18n(hint), "btn_wiz_holder", "btn_led_device_wiz");
|
||||
$('#btn_led_device_wiz').off().on('click', data, fn);
|
||||
}
|
||||
// LED controller specific wizards
|
||||
createLedDeviceWizards(ledType);
|
||||
|
||||
conf_editor.on('ready', function () {
|
||||
var hwLedCountDefault = 1;
|
||||
var colorOrderDefault = "rgb";
|
||||
var filter = {};
|
||||
let hwLedCountDefault = 1;
|
||||
let colorOrderDefault = "rgb";
|
||||
let filter = {};
|
||||
|
||||
$('#btn_layout_controller').hide();
|
||||
$('#btn_test_controller').hide();
|
||||
|
||||
switch (ledType) {
|
||||
@@ -1145,66 +1147,55 @@ $(document).ready(function () {
|
||||
showNotification('danger', "Device discovery for " + ledType + " failed with error:" + error);
|
||||
});
|
||||
|
||||
hwLedCountDefault = 1;
|
||||
|
||||
switch (ledType) {
|
||||
case "sk6812spi":
|
||||
case "sk6812_ftdi":
|
||||
colorOrderDefault = "grb";
|
||||
break;
|
||||
default:
|
||||
colorOrderDefault = "rgb";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "philipshue":
|
||||
case "philipshue": {
|
||||
disableAutoResolvedGeneralOptions();
|
||||
|
||||
var lights = conf_editor.getEditor("root.specificOptions.lightIds").getValue();
|
||||
const lights = conf_editor.getEditor("root.specificOptions.lightIds").getValue();
|
||||
hwLedCountDefault = lights.length;
|
||||
colorOrderDefault = "rgb";
|
||||
}
|
||||
break;
|
||||
|
||||
case "yeelight":
|
||||
case "yeelight": {
|
||||
disableAutoResolvedGeneralOptions();
|
||||
|
||||
var lights = conf_editor.getEditor("root.specificOptions.lights").getValue();
|
||||
const lights = conf_editor.getEditor("root.specificOptions.lights").getValue();
|
||||
hwLedCountDefault = lights.length;
|
||||
colorOrderDefault = "rgb";
|
||||
}
|
||||
break;
|
||||
|
||||
case "atmoorb":
|
||||
case "atmoorb": {
|
||||
disableAutoResolvedGeneralOptions();
|
||||
|
||||
var configruedOrbIds = conf_editor.getEditor("root.specificOptions.orbIds").getValue().trim();
|
||||
const configruedOrbIds = conf_editor.getEditor("root.specificOptions.orbIds").getValue().trim();
|
||||
if (configruedOrbIds.length !== 0) {
|
||||
hwLedCountDefault = configruedOrbIds.split(",").map(Number).length;
|
||||
} else {
|
||||
hwLedCountDefault = 0;
|
||||
}
|
||||
colorOrderDefault = "rgb";
|
||||
}
|
||||
break;
|
||||
|
||||
case "razer":
|
||||
case "razer": {
|
||||
disableAutoResolvedGeneralOptions();
|
||||
hwLedCountDefault = 1;
|
||||
colorOrderDefault = "bgr";
|
||||
|
||||
var subType = conf_editor.getEditor("root.specificOptions.subType").getValue();
|
||||
let params = { subType: subType };
|
||||
const subType = conf_editor.getEditor("root.specificOptions.subType").getValue();
|
||||
const params = { subType };
|
||||
getProperties_device(ledType, subType, params);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
if (ledType !== window.serverConfig.device.type) {
|
||||
var hwLedCount = conf_editor.getEditor("root.generalOptions.hardwareLedCount");
|
||||
let hwLedCount = conf_editor.getEditor("root.generalOptions.hardwareLedCount");
|
||||
if (hwLedCount) {
|
||||
hwLedCount.setValue(hwLedCountDefault);
|
||||
}
|
||||
var colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder");
|
||||
let colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder");
|
||||
if (colorOrder) {
|
||||
colorOrder.setValue(colorOrderDefault);
|
||||
}
|
||||
@@ -1213,8 +1204,8 @@ $(document).ready(function () {
|
||||
|
||||
conf_editor.on('change', function () {
|
||||
// //Check, if device can be identified/tested and/or saved
|
||||
var canIdentify = false;
|
||||
var canSave = false;
|
||||
let canIdentify = false;
|
||||
let canSave = false;
|
||||
|
||||
switch (ledType) {
|
||||
|
||||
@@ -1226,11 +1217,12 @@ $(document).ready(function () {
|
||||
case "udpartnet":
|
||||
case "udpddp":
|
||||
case "udph801":
|
||||
case "udpraw":
|
||||
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
case "udpraw": {
|
||||
const host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
if (host !== "") {
|
||||
canSave = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "adalight":
|
||||
@@ -1238,50 +1230,63 @@ $(document).ready(function () {
|
||||
case "karate":
|
||||
case "dmx":
|
||||
case "sedu":
|
||||
case "tpm2":
|
||||
var rate = conf_editor.getEditor("root.specificOptions.rate").getValue();
|
||||
case "tpm2": {
|
||||
let currentDeviceType = window.serverConfig.device.type;
|
||||
if ($.inArray(currentDeviceType, devSerial) === -1) {
|
||||
canIdentify = true;
|
||||
} else {
|
||||
let output = conf_editor.getEditor("root.specificOptions.output").getValue();
|
||||
if (window.serverConfig.device.output !== output) {
|
||||
canIdentify = true;
|
||||
}
|
||||
}
|
||||
|
||||
const rate = conf_editor.getEditor("root.specificOptions.rate").getValue();
|
||||
if (rate > 0) {
|
||||
canSave = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "philipshue":
|
||||
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
var username = conf_editor.getEditor("root.specificOptions.username").getValue();
|
||||
case "philipshue": {
|
||||
const host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
const username = conf_editor.getEditor("root.specificOptions.username").getValue();
|
||||
if (host !== "" && username != "") {
|
||||
var useEntertainmentAPI = conf_editor.getEditor("root.specificOptions.useEntertainmentAPI").getValue();
|
||||
var clientkey = conf_editor.getEditor("root.specificOptions.clientkey").getValue();
|
||||
const useEntertainmentAPI = conf_editor.getEditor("root.specificOptions.useEntertainmentAPI").getValue();
|
||||
const clientkey = conf_editor.getEditor("root.specificOptions.clientkey").getValue();
|
||||
if (!useEntertainmentAPI || clientkey !== "") {
|
||||
canSave = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "wled":
|
||||
case "cololight":
|
||||
var hostList = conf_editor.getEditor("root.specificOptions.hostList").getValue();
|
||||
case "cololight": {
|
||||
const hostList = conf_editor.getEditor("root.specificOptions.hostList").getValue();
|
||||
if (hostList !== "SELECT") {
|
||||
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
const host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
if (host !== "") {
|
||||
canIdentify = true;
|
||||
canSave = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "nanoleaf":
|
||||
var hostList = conf_editor.getEditor("root.specificOptions.hostList").getValue();
|
||||
case "nanoleaf": {
|
||||
const hostList = conf_editor.getEditor("root.specificOptions.hostList").getValue();
|
||||
if (hostList !== "SELECT") {
|
||||
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
var token = conf_editor.getEditor("root.specificOptions.token").getValue();
|
||||
const host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
const token = conf_editor.getEditor("root.specificOptions.token").getValue();
|
||||
if (host !== "" && token !== "") {
|
||||
canIdentify = true;
|
||||
canSave = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
canIdentify = false;
|
||||
canSave = true;
|
||||
}
|
||||
|
||||
@@ -1365,6 +1370,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 = {};
|
||||
@@ -1376,6 +1388,8 @@ $(document).ready(function () {
|
||||
break;
|
||||
|
||||
case "nanoleaf":
|
||||
$('#btn_wiz_holder').show();
|
||||
|
||||
var token = conf_editor.getEditor("root.specificOptions.token").getValue();
|
||||
if (token === "") {
|
||||
return;
|
||||
@@ -1400,30 +1414,27 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
conf_editor.watch('root.specificOptions.output', () => {
|
||||
var output = conf_editor.getEditor("root.specificOptions.output").getValue();
|
||||
const output = conf_editor.getEditor("root.specificOptions.output").getValue();
|
||||
if (output === "NONE" || output === "SELECT" || output === "") {
|
||||
|
||||
$('#btn_submit_controller').prop('disabled', true);
|
||||
$('#btn_test_controller').prop('disabled', true);
|
||||
$('#btn_test_controller').hide();
|
||||
|
||||
conf_editor.getEditor("root.generalOptions.hardwareLedCount").setValue(1);
|
||||
showAllDeviceInputOptions("output", false);
|
||||
}
|
||||
else {
|
||||
showAllDeviceInputOptions("output", true);
|
||||
let params = {};
|
||||
var canIdentify = false;
|
||||
switch (ledType) {
|
||||
case "adalight":
|
||||
canIdentify = true;
|
||||
break;
|
||||
case "atmo":
|
||||
case "karate":
|
||||
params = { serialPort: output };
|
||||
getProperties_device(ledType, output, params);
|
||||
break;
|
||||
case "adalight":
|
||||
case "dmx":
|
||||
case "sedu":
|
||||
case "tpm2":
|
||||
@@ -1445,8 +1456,8 @@ $(document).ready(function () {
|
||||
}
|
||||
|
||||
if ($.inArray(ledType, devSerial) != -1) {
|
||||
var rateList = conf_editor.getEditor("root.specificOptions.rateList").getValue();
|
||||
var showRate = false;
|
||||
const rateList = conf_editor.getEditor("root.specificOptions.rateList").getValue();
|
||||
let showRate = false;
|
||||
if (rateList == "CUSTOM") {
|
||||
showRate = true;
|
||||
}
|
||||
@@ -1454,13 +1465,6 @@ $(document).ready(function () {
|
||||
}
|
||||
|
||||
if (!conf_editor.validate().length) {
|
||||
if (canIdentify) {
|
||||
$("#btn_test_controller").show();
|
||||
$('#btn_test_controller').prop('disabled', false);
|
||||
} else {
|
||||
$('#btn_test_controller').hide();
|
||||
$('#btn_test_controller').prop('disabled', true);
|
||||
}
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_submit_controller').prop('disabled', false);
|
||||
}
|
||||
@@ -1512,12 +1516,12 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
conf_editor.watch('root.specificOptions.rateList', () => {
|
||||
var specOptPath = 'root.specificOptions.';
|
||||
var rateList = conf_editor.getEditor("root.specificOptions.rateList");
|
||||
if (rateList) {
|
||||
var val = rateList.getValue();
|
||||
var rate = conf_editor.getEditor("root.specificOptions.rate");
|
||||
const specOptPath = 'root.specificOptions.';
|
||||
const rateList = conf_editor.getEditor("root.specificOptions.rateList");
|
||||
let rate = conf_editor.getEditor("root.specificOptions.rate");
|
||||
|
||||
if (rateList) {
|
||||
const val = rateList.getValue();
|
||||
switch (val) {
|
||||
case 'CUSTOM':
|
||||
case '':
|
||||
@@ -1701,6 +1705,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();
|
||||
@@ -2155,7 +2186,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);
|
||||
@@ -2240,6 +2271,7 @@ async function identify_device(type, params) {
|
||||
}
|
||||
|
||||
function updateElements(ledType, key) {
|
||||
var canLayout = false;
|
||||
if (devicesProperties[ledType][key]) {
|
||||
var hardwareLedCount = 1;
|
||||
switch (ledType) {
|
||||
@@ -2258,18 +2290,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":
|
||||
@@ -2318,11 +2343,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);
|
||||
}
|
||||
}
|
||||
@@ -2416,6 +2449,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];
|
||||
@@ -2423,9 +2457,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;
|
||||
@@ -2477,13 +2510,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;
|
||||
@@ -2501,4 +2533,153 @@ 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 },
|
||||
29: { name: "4DLightstrip", led: true, sideLengthX: 50, sideLengthY: 50 },
|
||||
30: { name: "Skylight Panel", led: true, sideLengthX: 180, sideLengthY: 180 },
|
||||
31: { name: "SkylightControllerPrimary", led: true, sideLengthX: 180, sideLengthY: 180 },
|
||||
32: { name: "SkylightControllerPassive", led: true, sideLengthX: 180, sideLengthY: 180 },
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,13 @@ var createdCont = false;
|
||||
var isScroll = true;
|
||||
|
||||
performTranslation();
|
||||
requestLoggingStop();
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
window.addEventListener('hashchange', function(event) {
|
||||
requestLoggingStop();
|
||||
});
|
||||
|
||||
requestLoggingStart();
|
||||
|
||||
$('#conf_cont').append(createOptPanel('fa-reorder', $.i18n("edt_conf_log_heading_title"), 'editor_container', 'btn_submit'));
|
||||
@@ -178,9 +181,9 @@ $(document).ready(function () {
|
||||
if (!window.loggingHandlerInstalled) {
|
||||
window.loggingHandlerInstalled = true;
|
||||
|
||||
$(window.hyperion).on("cmd-logging-update", function (event) {
|
||||
$(window.hyperion).on("cmd-logmsg-update", function (event) {
|
||||
|
||||
var messages = (event.response.result.messages);
|
||||
var messages = (event.response.data.messages);
|
||||
|
||||
if (messages.length != 0) {
|
||||
if (!createdCont) {
|
||||
|
||||
@@ -213,13 +213,13 @@ $(document).ready(function () {
|
||||
for (var key in tokenList) {
|
||||
var lastUse = (tokenList[key].last_use) ? tokenList[key].last_use : "-";
|
||||
var btn = '<button id="tok' + tokenList[key].id + '" type="button" class="btn btn-danger">' + $.i18n('general_btn_delete') + '</button>';
|
||||
$('.tktbody').append(createTableRow([tokenList[key].comment, lastUse, btn], false, true));
|
||||
$('.tktbody').append(createTableRow([tokenList[key].id, tokenList[key].comment, lastUse, btn], false, true));
|
||||
$('#tok' + tokenList[key].id).off().on('click', handleDeleteToken);
|
||||
}
|
||||
}
|
||||
|
||||
createTable('tkthead', 'tktbody', 'tktable');
|
||||
$('.tkthead').html(createTableRow([$.i18n('conf_network_tok_cidhead'), $.i18n('conf_network_tok_lastuse'), $.i18n('general_btn_delete')], true, true));
|
||||
$('.tkthead').html(createTableRow([$.i18n('conf_network_tok_idhead'), $.i18n('conf_network_tok_cidhead'), $.i18n('conf_network_tok_lastuse'), $.i18n('general_btn_delete')], true, true));
|
||||
buildTokenList();
|
||||
|
||||
function handleDeleteToken(e) {
|
||||
|
||||
@@ -177,6 +177,7 @@ function sendToHyperion(command, subcommand, msg)
|
||||
else
|
||||
msg = "";
|
||||
|
||||
window.wsTan = Math.floor(Math.random() * 1000)
|
||||
window.websocket.send('{"command":"'+command+'", "tan":'+window.wsTan+subcommand+msg+'}');
|
||||
}
|
||||
|
||||
@@ -187,7 +188,7 @@ function sendToHyperion(command, subcommand, msg)
|
||||
// data: The json data as Object
|
||||
// tan: The optional tan, default 1. If the tan is -1, we skip global response error handling
|
||||
// Returns data of response or false if timeout
|
||||
async function sendAsyncToHyperion (command, subcommand, data, tan = 1) {
|
||||
async function sendAsyncToHyperion (command, subcommand, data, tan = Math.floor(Math.random() * 1000) ) {
|
||||
let obj = { command, tan }
|
||||
if (subcommand) {Object.assign(obj, {subcommand})}
|
||||
if (data) { Object.assign(obj, data) }
|
||||
@@ -486,38 +487,38 @@ async function requestLedDeviceDiscovery(type, params)
|
||||
{
|
||||
let data = { ledDeviceType: type, params: params };
|
||||
|
||||
return sendAsyncToHyperion("leddevice", "discover", data, Math.floor(Math.random() * 1000) );
|
||||
return sendAsyncToHyperion("leddevice", "discover", data);
|
||||
}
|
||||
|
||||
async function requestLedDeviceProperties(type, params)
|
||||
{
|
||||
let data = { ledDeviceType: type, params: params };
|
||||
|
||||
return sendAsyncToHyperion("leddevice", "getProperties", data, Math.floor(Math.random() * 1000));
|
||||
return sendAsyncToHyperion("leddevice", "getProperties", data);
|
||||
}
|
||||
|
||||
function requestLedDeviceIdentification(type, params)
|
||||
{
|
||||
let data = { ledDeviceType: type, params: params };
|
||||
|
||||
return sendAsyncToHyperion("leddevice", "identify", data, Math.floor(Math.random() * 1000));
|
||||
return sendAsyncToHyperion("leddevice", "identify", data);
|
||||
}
|
||||
|
||||
async function requestLedDeviceAddAuthorization(type, params) {
|
||||
let data = { ledDeviceType: type, params: params };
|
||||
|
||||
return sendAsyncToHyperion("leddevice", "addAuthorization", data, Math.floor(Math.random() * 1000));
|
||||
return sendAsyncToHyperion("leddevice", "addAuthorization", data);
|
||||
}
|
||||
|
||||
async function requestInputSourcesDiscovery(type, params) {
|
||||
let data = { sourceType: type, params: params };
|
||||
|
||||
return sendAsyncToHyperion("inputsource", "discover", data, Math.floor(Math.random() * 1000));
|
||||
return sendAsyncToHyperion("inputsource", "discover", data);
|
||||
}
|
||||
|
||||
async function requestServiceDiscovery(type, params) {
|
||||
let data = { serviceType: type, params: params };
|
||||
|
||||
return sendAsyncToHyperion("service", "discover", data, Math.floor(Math.random() * 1000));
|
||||
return sendAsyncToHyperion("service", "discover", data);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = ['bg', '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;
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ $(document).ready(function () {
|
||||
$("body").get(0).style.setProperty("--background-var", "none");
|
||||
}
|
||||
else {
|
||||
printLedsToCanvas(event.response.result.leds)
|
||||
printLedsToCanvas(event.response.data.leds)
|
||||
$("body").get(0).style.setProperty("--background-var", "url(" + ($('#leds_preview_canv')[0]).toDataURL("image/jpg") + ") no-repeat top left");
|
||||
}
|
||||
});
|
||||
@@ -275,7 +275,7 @@ $(document).ready(function () {
|
||||
}
|
||||
}
|
||||
else {
|
||||
var imageData = (event.response.result.image);
|
||||
var imageData = (event.response.data.image);
|
||||
|
||||
var image = new Image();
|
||||
image.onload = function () {
|
||||
|
||||
@@ -319,9 +319,9 @@ function showInfoDialog(type, header, message) {
|
||||
});
|
||||
|
||||
$(document).on('click', '[data-dismiss-modal]', function () {
|
||||
var target = $(this).attr('data-dismiss-modal');
|
||||
$.find(target).modal('hide');
|
||||
});
|
||||
var target = $(this).data('dismiss-modal');
|
||||
$($.find(target)).modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
function createHintH(type, text, container) {
|
||||
@@ -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';
|
||||
|
||||
@@ -1392,3 +1393,32 @@ function isValidHostnameOrIP(value) {
|
||||
return (isValidHostnameOrIP4(value) || isValidIPv6(value) || isValidServicename(value));
|
||||
}
|
||||
|
||||
const loadedScripts = [];
|
||||
|
||||
function isScriptLoaded(src) {
|
||||
return loadedScripts.indexOf(src) > -1;
|
||||
}
|
||||
|
||||
function loadScript(src, callback, ...params) {
|
||||
if (isScriptLoaded(src)) {
|
||||
debugMessage('Script ' + src + ' already loaded');
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback( ...params);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = src;
|
||||
|
||||
script.onload = function () {
|
||||
debugMessage('Script ' + src + ' loaded successfully');
|
||||
loadedScripts.push(src);
|
||||
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback(...params);
|
||||
}
|
||||
};
|
||||
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
283
assets/webconfig/js/wizards/LedDevice_atmoorb.js
Normal file
283
assets/webconfig/js/wizards/LedDevice_atmoorb.js
Normal file
@@ -0,0 +1,283 @@
|
||||
//****************************
|
||||
// Wizard AtmoOrb
|
||||
//****************************
|
||||
|
||||
import { ledDeviceWizardUtils as utils } from './LedDevice_utils.js';
|
||||
|
||||
const atmoorbWizard = (() => {
|
||||
|
||||
const lights = [];
|
||||
let configuredLights = [];
|
||||
|
||||
function getIdInLights(id) {
|
||||
return lights.filter(
|
||||
function (lights) {
|
||||
return lights.id === id
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function begin() {
|
||||
|
||||
const configruedOrbIds = conf_editor.getEditor("root.specificOptions.orbIds").getValue().trim();
|
||||
if (configruedOrbIds.length !== 0) {
|
||||
configuredLights = configruedOrbIds.split(",").map(Number);
|
||||
}
|
||||
|
||||
const multiCastGroup = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
const multiCastPort = parseInt(conf_editor.getEditor("root.specificOptions.port").getValue());
|
||||
|
||||
discover(multiCastGroup, multiCastPort);
|
||||
|
||||
$('#btn_wiz_save').off().on("click", function () {
|
||||
let ledConfig = [];
|
||||
let finalLights = [];
|
||||
|
||||
//create atmoorb led config
|
||||
for (let key in lights) {
|
||||
if ($('#orb_' + key).val() !== "disabled") {
|
||||
// Set Name to layout-position, if empty
|
||||
if (lights[key].name === "") {
|
||||
lights[key].name = $.i18n('conf_leds_layout_cl_' + $('#orb_' + key).val());
|
||||
}
|
||||
|
||||
finalLights.push(lights[key].id);
|
||||
|
||||
let name = lights[key].id;
|
||||
if (lights[key].host !== "")
|
||||
name += ':' + lights[key].host;
|
||||
|
||||
const idx_content = utils.assignLightPos($('#orb_' + key).val(), name);
|
||||
ledConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
||||
}
|
||||
}
|
||||
|
||||
//LED layout
|
||||
window.serverConfig.leds = ledConfig;
|
||||
|
||||
//LED device config
|
||||
//Start with a clean configuration
|
||||
let d = {};
|
||||
|
||||
d.type = 'atmoorb';
|
||||
d.hardwareLedCount = finalLights.length;
|
||||
d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue();
|
||||
|
||||
d.orbIds = finalLights.toString();
|
||||
d.useOrbSmoothing = utils.eV("useOrbSmoothing");
|
||||
|
||||
d.host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
d.port = parseInt(conf_editor.getEditor("root.specificOptions.port").getValue());
|
||||
d.latchTime = parseInt(conf_editor.getEditor("root.specificOptions.latchTime").getValue());;
|
||||
|
||||
window.serverConfig.device = d;
|
||||
|
||||
requestWriteConfig(window.serverConfig, true);
|
||||
resetWizard();
|
||||
});
|
||||
|
||||
$('#btn_wiz_abort').off().on('click', resetWizard);
|
||||
}
|
||||
|
||||
async function discover(multiCastGroup, multiCastPort) {
|
||||
let params = {};
|
||||
if (multiCastGroup !== "") {
|
||||
params.multiCastGroup = multiCastGroup;
|
||||
}
|
||||
|
||||
if (multiCastPort !== 0) {
|
||||
params.multiCastPort = multiCastPort;
|
||||
}
|
||||
|
||||
// Get discovered lights
|
||||
const res = await requestLedDeviceDiscovery('atmoorb', params);
|
||||
if (res && !res.error) {
|
||||
const r = res.info;
|
||||
|
||||
// Process devices returned by discovery
|
||||
processDiscoveredDevices(r.devices);
|
||||
|
||||
// Add additional items from configuration
|
||||
for (const configuredLight of configuredLights) {
|
||||
processConfiguredLight(configuredLight);
|
||||
}
|
||||
|
||||
sortLightsById();
|
||||
assign_lights();
|
||||
}
|
||||
}
|
||||
|
||||
function processDiscoveredDevices(devices) {
|
||||
for (const device of devices) {
|
||||
if (device.id !== "" && getIdInLights(device.id).length === 0) {
|
||||
const light = {
|
||||
id: device.id,
|
||||
ip: device.ip,
|
||||
host: device.hostname
|
||||
};
|
||||
lights.push(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function processConfiguredLight(configuredLight) {
|
||||
if (configuredLight !== "" && !isNaN(configuredLight)) {
|
||||
if (getIdInLights(configuredLight).length === 0) {
|
||||
const light = {
|
||||
id: configuredLight,
|
||||
ip: "",
|
||||
host: ""
|
||||
};
|
||||
lights.push(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function attachIdentifyButtonEvent() {
|
||||
// Use event delegation to handle clicks on buttons with class "btn-identify"
|
||||
$('#wizp2_body').on('click', '.btn-identify', function () {
|
||||
const orbId = $(this).data('orb-id');
|
||||
identify(orbId);
|
||||
});
|
||||
}
|
||||
|
||||
function sortLightsById() {
|
||||
lights.sort((a, b) => (a.id > b.id) ? 1 : -1);
|
||||
}
|
||||
|
||||
function assign_lights() {
|
||||
// If records are left for configuration
|
||||
if (Object.keys(lights).length > 0) {
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
$('#orb_ids_t, #btn_wiz_save').toggle(true);
|
||||
|
||||
const lightOptions = [
|
||||
"top", "topleft", "topright",
|
||||
"bottom", "bottomleft", "bottomright",
|
||||
"left", "lefttop", "leftmiddle", "leftbottom",
|
||||
"right", "righttop", "rightmiddle", "rightbottom",
|
||||
"entire",
|
||||
"lightPosTopLeft112", "lightPosTopLeftNewMid", "lightPosTopLeft121",
|
||||
"lightPosBottomLeft14", "lightPosBottomLeft12", "lightPosBottomLeft34", "lightPosBottomLeft11",
|
||||
"lightPosBottomLeft112", "lightPosBottomLeftNewMid", "lightPosBottomLeft121"
|
||||
];
|
||||
|
||||
lightOptions.unshift("disabled");
|
||||
|
||||
$('.lidsb').html("");
|
||||
let pos = "";
|
||||
|
||||
for (const lightid in lights) {
|
||||
const orbId = lights[lightid].id;
|
||||
const orbIp = lights[lightid].ip;
|
||||
let orbHostname = lights[lightid].host;
|
||||
|
||||
if (orbHostname === "")
|
||||
orbHostname = $.i18n('edt_dev_spec_lights_itemtitle');
|
||||
|
||||
let options = "";
|
||||
for (const opt in lightOptions) {
|
||||
const val = lightOptions[opt];
|
||||
const txt = (val !== 'entire' && val !== 'disabled') ? 'conf_leds_layout_cl_' : 'wiz_ids_';
|
||||
options += '<option value="' + val + '"';
|
||||
if (pos === val) options += ' selected="selected"';
|
||||
options += '>' + $.i18n(txt + val) + '</option>';
|
||||
}
|
||||
|
||||
let enabled = 'enabled';
|
||||
if (orbId < 1 || orbId > 255) {
|
||||
enabled = 'disabled';
|
||||
options = '<option value=disabled>' + $.i18n('wiz_atmoorb_unsupported') + '</option>';
|
||||
}
|
||||
|
||||
let lightAnnotation = "";
|
||||
if (orbIp !== "") {
|
||||
lightAnnotation = ': ' + orbIp + '<br>(' + orbHostname + ')';
|
||||
}
|
||||
|
||||
$('.lidsb').append(createTableRow([orbId + lightAnnotation, '<select id="orb_' + lightid + '" ' + enabled + ' class="orb_sel_watch form-control">'
|
||||
+ options
|
||||
+ '</select>', '<button class="btn btn-sm btn-primary btn-identify" ' + enabled + ' data-orb-id="' + orbId + '")>'
|
||||
+ $.i18n('wiz_identify_light', orbId) + '</button>']));
|
||||
}
|
||||
attachIdentifyButtonEvent();
|
||||
|
||||
$('.orb_sel_watch').on("change", function () {
|
||||
let cC = 0;
|
||||
for (const key in lights) {
|
||||
if ($('#orb_' + key).val() !== "disabled") {
|
||||
cC++;
|
||||
}
|
||||
}
|
||||
if (cC === 0 || window.readOnlyMode)
|
||||
$('#btn_wiz_save').prop("disabled", true);
|
||||
else
|
||||
$('#btn_wiz_save').prop("disabled", false);
|
||||
});
|
||||
$('.orb_sel_watch').trigger('change');
|
||||
}
|
||||
else {
|
||||
const noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights', 'AtmoOrbs') + '</p>';
|
||||
$('#wizp2_body').append(noLightsTxt);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
async function identify(orbId) {
|
||||
const disabled = $('#btn_wiz_save').is(':disabled');
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').prop('disabled', true);
|
||||
|
||||
const params = { id: orbId };
|
||||
await requestLedDeviceIdentification("atmoorb", params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').prop('disabled', disabled);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
start: function (e) {
|
||||
|
||||
//create html
|
||||
const atmoorb_title = 'wiz_atmoorb_title';
|
||||
const atmoorb_intro1 = 'wiz_atmoorb_intro1';
|
||||
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(atmoorb_title));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(atmoorb_title) + '</h4><p>' + $.i18n(atmoorb_intro1) + '</p>');
|
||||
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>'
|
||||
+ $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>'
|
||||
+ $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
|
||||
|
||||
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
|
||||
|
||||
$('#wizp2_body').append('<div id="orb_ids_t" style="display:none"><p style="font-weight:bold" id="orb_id_headline">' + $.i18n('wiz_atmoorb_desc2') + '</p></div>');
|
||||
|
||||
createTable("lidsh", "lidsb", "orb_ids_t");
|
||||
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'), $.i18n('wiz_pos'), $.i18n('wiz_identify')], true));
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'
|
||||
+ $.i18n('general_btn_save') + '</button><buttowindow.serverConfig.device = d;n type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'
|
||||
+ $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
if (getStorage("darkMode") == "on")
|
||||
$('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png');
|
||||
|
||||
//open modal
|
||||
$("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true });
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
begin();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export { atmoorbWizard };
|
||||
94
assets/webconfig/js/wizards/LedDevice_nanoleaf.js
Normal file
94
assets/webconfig/js/wizards/LedDevice_nanoleaf.js
Normal file
@@ -0,0 +1,94 @@
|
||||
//****************************
|
||||
// Wizard Nanoleaf
|
||||
//****************************
|
||||
|
||||
const nanoleafWizard = (() => {
|
||||
|
||||
const retryInterval = 2;
|
||||
|
||||
async function createNanoleafUserAuthorization() {
|
||||
const host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
const params = { host };
|
||||
let retryTime = 30;
|
||||
|
||||
const UserInterval = setInterval(async function () {
|
||||
retryTime -= retryInterval;
|
||||
$("#connectionTime").html(retryTime);
|
||||
|
||||
if (retryTime <= 0) {
|
||||
handleTimeout();
|
||||
} else {
|
||||
const res = await requestLedDeviceAddAuthorization('nanoleaf', params);
|
||||
handleResponse(res);
|
||||
}
|
||||
}, retryInterval * 1000);
|
||||
|
||||
function handleTimeout() {
|
||||
clearInterval(UserInterval);
|
||||
showNotification(
|
||||
'warning',
|
||||
$.i18n('wiz_nanoleaf_failure_auth_token'),
|
||||
$.i18n('wiz_nanoleaf_failure_auth_token_t')
|
||||
);
|
||||
resetWizard(true);
|
||||
}
|
||||
|
||||
function handleResponse(res) {
|
||||
if (res && !res.error) {
|
||||
const response = res.info;
|
||||
if (jQuery.isEmptyObject(response)) {
|
||||
debugMessage(`${retryTime}: Power On/Off button not pressed or device not reachable`);
|
||||
} else {
|
||||
const token = response.auth_token;
|
||||
if (token !== 'undefined') {
|
||||
conf_editor.getEditor("root.specificOptions.token").setValue(token);
|
||||
}
|
||||
clearInterval(UserInterval);
|
||||
resetWizard(true);
|
||||
}
|
||||
} else {
|
||||
clearInterval(UserInterval);
|
||||
resetWizard(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
start: function () {
|
||||
const nanoleaf_user_auth_title = 'wiz_nanoleaf_user_auth_title';
|
||||
const nanoleaf_user_auth_intro = 'wiz_nanoleaf_user_auth_intro';
|
||||
|
||||
$('#wiz_header').html(
|
||||
`<i class="fa fa-magic fa-fw"></i>${$.i18n(nanoleaf_user_auth_title)}`
|
||||
);
|
||||
$('#wizp1_body').html(
|
||||
`<h4 style="font-weight:bold;text-transform:uppercase;">${$.i18n(nanoleaf_user_auth_title)}</h4><p>${$.i18n(nanoleaf_user_auth_intro)}</p>`
|
||||
);
|
||||
$('#wizp1_footer').html(
|
||||
`<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>${$.i18n('general_btn_continue')}</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>${$.i18n('general_btn_cancel')}</button>`
|
||||
);
|
||||
$('#wizp3_body').html(
|
||||
`<span>${$.i18n('wiz_nanoleaf_press_onoff_button')}</span> <br /><br /><center><span id="connectionTime"></span><br /><i class="fa fa-cog fa-spin" style="font-size:100px"></i></center>`
|
||||
);
|
||||
|
||||
if (getStorage("darkMode") == "on") {
|
||||
$('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png');
|
||||
}
|
||||
|
||||
$("#wizard_modal").modal({
|
||||
backdrop: "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
});
|
||||
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
createNanoleafUserAuthorization();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp3').toggle(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export { nanoleafWizard };
|
||||
|
||||
996
assets/webconfig/js/wizards/LedDevice_philipshue.js
Normal file
996
assets/webconfig/js/wizards/LedDevice_philipshue.js
Normal file
@@ -0,0 +1,996 @@
|
||||
//****************************
|
||||
// Wizard Philips Hue
|
||||
//****************************
|
||||
|
||||
import { ledDeviceWizardUtils as utils } from './LedDevice_utils.js';
|
||||
|
||||
const philipshueWizard = (() => {
|
||||
|
||||
// External properties, 2-dimensional arry of [ledType][key]
|
||||
let devicesProperties = {};
|
||||
|
||||
let hueIPs = [];
|
||||
let hueIPsinc = 0;
|
||||
let hueLights = [];
|
||||
let hueEntertainmentConfigs = [];
|
||||
let hueEntertainmentServices = [];
|
||||
let groupLights = [];
|
||||
let groupChannels = [];
|
||||
let groupLightsLocations = [];
|
||||
let isAPIv2Ready = true;
|
||||
let isEntertainmentReady = true;
|
||||
|
||||
function checkHueBridge(cb, hueUser) {
|
||||
const usr = (typeof hueUser != "undefined") ? hueUser : 'config';
|
||||
if (usr === 'config') {
|
||||
$('#wiz_hue_discovered').html("");
|
||||
}
|
||||
|
||||
if (hueIPs[hueIPsinc]) {
|
||||
const host = hueIPs[hueIPsinc].host;
|
||||
const port = hueIPs[hueIPsinc].port;
|
||||
|
||||
if (usr != '') {
|
||||
getProperties(cb, decodeURIComponent(host), port, usr);
|
||||
}
|
||||
else {
|
||||
cb(false, usr);
|
||||
}
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
$('#port').val(443);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkBridgeResult(reply, usr) {
|
||||
if (reply) {
|
||||
//abort checking, first reachable result is used
|
||||
$('#wiz_hue_ipstate').html("");
|
||||
$('#host').val(hueIPs[hueIPsinc].host)
|
||||
$('#port').val(hueIPs[hueIPsinc].port)
|
||||
|
||||
$('#usrcont').toggle(true);
|
||||
|
||||
checkHueBridge(checkUserResult, $('#user').val());
|
||||
}
|
||||
else {
|
||||
$('#usrcont').toggle(false);
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
}
|
||||
};
|
||||
|
||||
function checkUserResult(reply, username) {
|
||||
$('#usrcont').toggle(true);
|
||||
|
||||
let hue_create_user = 'wiz_hue_e_create_user';
|
||||
if (!isEntertainmentReady) {
|
||||
hue_create_user = 'wiz_hue_create_user';
|
||||
$('#hue_client_key_r').toggle(false);
|
||||
} else {
|
||||
$('#hue_client_key_r').toggle(true);
|
||||
}
|
||||
|
||||
$('#wiz_hue_create_user').text($.i18n(hue_create_user));
|
||||
$('#wiz_hue_create_user').toggle(true);
|
||||
|
||||
if (reply) {
|
||||
$('#user').val(username);
|
||||
|
||||
if (isEntertainmentReady && $('#clientkey').val() == "") {
|
||||
$('#wiz_hue_usrstate').html($.i18n('wiz_hue_e_clientkey_needed'));
|
||||
$('#wiz_hue_create_user').toggle(true);
|
||||
} else {
|
||||
$('#wiz_hue_usrstate').html("");
|
||||
$('#wiz_hue_create_user').toggle(false);
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
$('#hue_id_headline').text($.i18n('wiz_hue_e_desc3'));
|
||||
$('#hue_grp_ids_t').toggle(true);
|
||||
|
||||
get_hue_groups(username);
|
||||
|
||||
} else {
|
||||
$('#hue_id_headline').text($.i18n('wiz_hue_desc2'));
|
||||
$('#hue_grp_ids_t').toggle(false);
|
||||
|
||||
get_hue_lights(username);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//abort checking, first reachable result is used
|
||||
$('#wiz_hue_usrstate').html($.i18n('wiz_hue_failure_user'));
|
||||
$('#wiz_hue_create_user').toggle(true);
|
||||
}
|
||||
};
|
||||
|
||||
function useGroupId(id, username) {
|
||||
$('#groupId').val(hueEntertainmentConfigs[id].id);
|
||||
if (isAPIv2Ready) {
|
||||
const group = hueEntertainmentConfigs[id];
|
||||
|
||||
groupLights = [];
|
||||
for (const light of group.light_services) {
|
||||
groupLights.push(light.rid);
|
||||
}
|
||||
|
||||
groupChannels = [];
|
||||
for (const channel of group.channels) {
|
||||
groupChannels.push(channel);
|
||||
}
|
||||
|
||||
groupLightsLocations = [];
|
||||
for (const location of group.locations.service_locations) {
|
||||
groupLightsLocations.push(location);
|
||||
}
|
||||
} else {
|
||||
//Ensure ligthIDs are strings
|
||||
groupLights = hueEntertainmentConfigs[id].lights.map(num => {
|
||||
return String(num);
|
||||
});
|
||||
|
||||
const lightLocations = hueEntertainmentConfigs[id].locations;
|
||||
for (const locationID in lightLocations) {
|
||||
let lightLocation = {};
|
||||
|
||||
let position = {
|
||||
x: lightLocations[locationID][0],
|
||||
y: lightLocations[locationID][1],
|
||||
z: lightLocations[locationID][2]
|
||||
};
|
||||
lightLocation.position = position;
|
||||
|
||||
groupLightsLocations.push(lightLocation);
|
||||
}
|
||||
}
|
||||
|
||||
get_hue_lights(username);
|
||||
}
|
||||
|
||||
function assignLightEntertainmentPos(isFocusCenter, position, name, id) {
|
||||
|
||||
let x = position.x;
|
||||
let z = position.z;
|
||||
|
||||
if (isFocusCenter) {
|
||||
// Map lights as in centered range -0.5 to 0.5
|
||||
if (x < -0.5) {
|
||||
x = -0.5;
|
||||
} else if (x > 0.5) {
|
||||
x = 0.5;
|
||||
}
|
||||
if (z < -0.5) {
|
||||
z = -0.5;
|
||||
} else if (z > 0.5) {
|
||||
z = 0.5;
|
||||
}
|
||||
} else {
|
||||
// Map lights as in full range -1 to 1
|
||||
x /= 2;
|
||||
z /= 2;
|
||||
}
|
||||
|
||||
const h = x + 0.5;
|
||||
const v = -z + 0.5;
|
||||
|
||||
const hmin = h - 0.05;
|
||||
const hmax = h + 0.05;
|
||||
const vmin = v - 0.05;
|
||||
const vmax = v + 0.05;
|
||||
|
||||
let layoutObject = {
|
||||
hmin: hmin < 0 ? 0 : hmin,
|
||||
hmax: hmax > 1 ? 1 : hmax,
|
||||
vmin: vmin < 0 ? 0 : vmin,
|
||||
vmax: vmax > 1 ? 1 : vmax,
|
||||
name: name
|
||||
};
|
||||
|
||||
if (id !== undefined && id !== null) {
|
||||
layoutObject.name += "_" + id;
|
||||
}
|
||||
return layoutObject;
|
||||
}
|
||||
|
||||
function assignSegmentedLightPos(segment, position, name) {
|
||||
let layoutObjects = [];
|
||||
|
||||
let segTotalLength = 0;
|
||||
for (const key in segment) {
|
||||
|
||||
segTotalLength += segment[key].length;
|
||||
}
|
||||
|
||||
let min;
|
||||
let max;
|
||||
let horizontal = true;
|
||||
|
||||
let layoutObject = utils.assignLightPos(position, name);
|
||||
if (position === "left" || position === "right") {
|
||||
// vertical distribution
|
||||
min = layoutObject.vmin;
|
||||
max = layoutObject.vmax;
|
||||
horizontal = false;
|
||||
|
||||
} else {
|
||||
// horizontal distribution
|
||||
min = layoutObject.hmin;
|
||||
max = layoutObject.hmax;
|
||||
}
|
||||
|
||||
const step = (max - min) / segTotalLength;
|
||||
let start = min;
|
||||
|
||||
for (const key in segment) {
|
||||
min = start;
|
||||
max = round(start + segment[key].length * step);
|
||||
|
||||
if (horizontal) {
|
||||
layoutObject.hmin = min;
|
||||
layoutObject.hmax = max;
|
||||
} else {
|
||||
layoutObject.vmin = min;
|
||||
layoutObject.vmax = max;
|
||||
}
|
||||
layoutObject.name = name + "_" + key;
|
||||
layoutObjects.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
|
||||
start = max;
|
||||
}
|
||||
|
||||
return layoutObjects;
|
||||
}
|
||||
|
||||
function updateBridgeDetails(properties) {
|
||||
const ledDeviceProperties = properties.config;
|
||||
|
||||
if (!jQuery.isEmptyObject(ledDeviceProperties)) {
|
||||
isEntertainmentReady = properties.isEntertainmentReady;
|
||||
isAPIv2Ready = properties.isAPIv2Ready;
|
||||
|
||||
if (ledDeviceProperties.name && ledDeviceProperties.bridgeid && ledDeviceProperties.modelid) {
|
||||
$('#wiz_hue_discovered').html(
|
||||
"Bridge: " + ledDeviceProperties.name +
|
||||
", Modelid: " + ledDeviceProperties.modelid +
|
||||
", Firmware: " + ledDeviceProperties.swversion + "<br/>" +
|
||||
"API-Version: " + ledDeviceProperties.apiversion +
|
||||
", Entertainment: " + (isEntertainmentReady ? "✓" : "-") +
|
||||
", APIv2: " + (isAPIv2Ready ? "✓" : "-")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function discover() {
|
||||
$('#wiz_hue_ipstate').html($.i18n('edt_dev_spec_devices_discovery_inprogress'));
|
||||
|
||||
// $('#wiz_hue_discovered').html("")
|
||||
const res = await requestLedDeviceDiscovery('philipshue');
|
||||
if (res && !res.error) {
|
||||
const r = res.info;
|
||||
|
||||
// Process devices returned by discovery
|
||||
if (r.devices.length == 0) {
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
$('#wiz_hue_discovered').html("")
|
||||
}
|
||||
else {
|
||||
hueIPs = [];
|
||||
hueIPsinc = 0;
|
||||
|
||||
let discoveryMethod = "ssdp";
|
||||
if (res.info.discoveryMethod) {
|
||||
discoveryMethod = res.info.discoveryMethod;
|
||||
}
|
||||
|
||||
for (const device of r.devices) {
|
||||
if (device) {
|
||||
let host;
|
||||
let port;
|
||||
if (discoveryMethod === "ssdp") {
|
||||
if (device.hostname && device.domain) {
|
||||
host = device.hostname + "." + device.domain;
|
||||
port = device.port;
|
||||
} else {
|
||||
host = device.ip;
|
||||
port = device.port;
|
||||
}
|
||||
} else {
|
||||
host = device.service;
|
||||
port = device.port;
|
||||
}
|
||||
if (host) {
|
||||
|
||||
if (!hueIPs.some(item => item.host === host)) {
|
||||
hueIPs.push({ host: host, port: port });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#wiz_hue_ipstate').html("");
|
||||
$('#host').val(hueIPs[hueIPsinc].host)
|
||||
$('#port').val(hueIPs[hueIPsinc].port)
|
||||
|
||||
$('#hue_bridge_select').html("");
|
||||
|
||||
for (const key in hueIPs) {
|
||||
$('#hue_bridge_select').append(createSelOpt(key, hueIPs[key].host));
|
||||
}
|
||||
|
||||
$('.hue_bridge_sel_watch').on("click", function () {
|
||||
hueIPsinc = $(this).val();
|
||||
|
||||
const name = $("#hue_bridge_select option:selected").text();
|
||||
$('#host').val(name);
|
||||
$('#port').val(hueIPs[hueIPsinc].port)
|
||||
|
||||
const usr = $('#user').val();
|
||||
if (usr != "") {
|
||||
checkHueBridge(checkUserResult, usr);
|
||||
} else {
|
||||
checkHueBridge(checkBridgeResult);
|
||||
}
|
||||
});
|
||||
|
||||
$('.hue_bridge_sel_watch').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getProperties(cb, hostAddress, port, username, resourceFilter) {
|
||||
let params = { host: hostAddress, username: username, filter: resourceFilter };
|
||||
if (port !== 'undefined') {
|
||||
params.port = parseInt(port);
|
||||
}
|
||||
|
||||
const ledType = 'philipshue';
|
||||
const key = hostAddress;
|
||||
|
||||
//Create ledType cache entry
|
||||
if (!devicesProperties[ledType]) {
|
||||
devicesProperties[ledType] = {};
|
||||
}
|
||||
|
||||
// Use device's properties, if properties in chache
|
||||
if (devicesProperties[ledType][key] && devicesProperties[ledType][key][username]) {
|
||||
updateBridgeDetails(devicesProperties[ledType][key]);
|
||||
cb(true, username);
|
||||
} else {
|
||||
const res = await requestLedDeviceProperties(ledType, params);
|
||||
if (res && !res.error) {
|
||||
const ledDeviceProperties = res.info.properties;
|
||||
if (!jQuery.isEmptyObject(ledDeviceProperties)) {
|
||||
|
||||
devicesProperties[ledType][key] = {};
|
||||
devicesProperties[ledType][key][username] = ledDeviceProperties;
|
||||
|
||||
isAPIv2Ready = res.info.isAPIv2Ready;
|
||||
devicesProperties[ledType][key].isAPIv2Ready = isAPIv2Ready;
|
||||
isEntertainmentReady = res.info.isEntertainmentReady;
|
||||
devicesProperties[ledType][key].isEntertainmentReady = isEntertainmentReady;
|
||||
|
||||
updateBridgeDetails(devicesProperties[ledType][key]);
|
||||
if (username === "config") {
|
||||
cb(true);
|
||||
} else {
|
||||
cb(true, username);
|
||||
}
|
||||
} else {
|
||||
cb(false, username);
|
||||
}
|
||||
} else {
|
||||
cb(false, username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function identify(hostAddress, port, username, name, id, id_v1) {
|
||||
const disabled = $('#btn_wiz_save').is(':disabled');
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').prop('disabled', true);
|
||||
|
||||
let params = { host: decodeURIComponent(hostAddress), username: username, lightName: decodeURIComponent(name), lightId: id, lightId_v1: id_v1 };
|
||||
|
||||
if (port !== 'undefined') {
|
||||
params.port = parseInt(port);
|
||||
}
|
||||
|
||||
await requestLedDeviceIdentification('philipshue', params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').prop('disabled', disabled);
|
||||
}
|
||||
}
|
||||
|
||||
function begin() {
|
||||
const usr = utils.eV("username");
|
||||
if (usr != "") {
|
||||
$('#user').val(usr);
|
||||
}
|
||||
|
||||
const clkey = utils.eV("clientkey");
|
||||
if (clkey != "") {
|
||||
$('#clientkey').val(clkey);
|
||||
}
|
||||
|
||||
//check if host is empty/reachable/search for bridge
|
||||
if (utils.eV("host") == "") {
|
||||
hueIPs = [];
|
||||
hueIPsinc = 0;
|
||||
|
||||
discover();
|
||||
}
|
||||
else {
|
||||
const host = utils.eV("host");
|
||||
$('#host').val(host);
|
||||
|
||||
const port = utils.eV("port");
|
||||
if (port > 0) {
|
||||
$('#port').val(port);
|
||||
}
|
||||
else {
|
||||
$('#port').val('');
|
||||
}
|
||||
hueIPs.push({ host: host, port: port });
|
||||
|
||||
if (usr != "") {
|
||||
checkHueBridge(checkUserResult, usr);
|
||||
} else {
|
||||
checkHueBridge(checkBridgeResult);
|
||||
}
|
||||
}
|
||||
|
||||
$('#retry_bridge').off().on('click', function () {
|
||||
const host = $('#host').val();
|
||||
const port = parseInt($('#port').val());
|
||||
|
||||
if (host != "") {
|
||||
|
||||
const idx = hueIPs.findIndex(item => item.host === host && item.port === port);
|
||||
if (idx === -1) {
|
||||
hueIPs.push({ host: host, port: port });
|
||||
hueIPsinc = hueIPs.length - 1;
|
||||
} else {
|
||||
hueIPsinc = idx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
discover();
|
||||
}
|
||||
|
||||
const usr = $('#user').val();
|
||||
if (usr != "") {
|
||||
checkHueBridge(checkUserResult, usr);
|
||||
} else {
|
||||
checkHueBridge(checkBridgeResult);
|
||||
}
|
||||
});
|
||||
|
||||
$('#retry_usr').off().on('click', function () {
|
||||
checkHueBridge(checkUserResult, $('#user').val());
|
||||
});
|
||||
|
||||
$('#wiz_hue_create_user').off().on('click', function () {
|
||||
createHueUser();
|
||||
});
|
||||
$('#btn_wiz_save').off().on("click", function () {
|
||||
let hueLedConfig = [];
|
||||
let finalLightIds = [];
|
||||
let channelNumber = 0;
|
||||
|
||||
//create hue led config
|
||||
for (const key in groupLights) {
|
||||
const lightId = groupLights[key];
|
||||
|
||||
if ($('#hue_' + lightId).val() != "disabled") {
|
||||
finalLightIds.push(lightId);
|
||||
|
||||
let lightName;
|
||||
if (isAPIv2Ready) {
|
||||
const light = hueLights.find(light => light.id === lightId);
|
||||
lightName = light.metadata.name;
|
||||
} else {
|
||||
lightName = hueLights[lightId].name;
|
||||
}
|
||||
|
||||
const position = $('#hue_' + lightId).val();
|
||||
const lightIdx = groupLights.indexOf(lightId);
|
||||
const lightLocation = groupLightsLocations[lightIdx];
|
||||
|
||||
let serviceID;
|
||||
if (isAPIv2Ready) {
|
||||
if (lightLocation) {
|
||||
serviceID = lightLocation.service.rid;
|
||||
}
|
||||
}
|
||||
|
||||
if (position.startsWith("entertainment")) {
|
||||
|
||||
// Layout per entertainment area definition at bridge
|
||||
let isFocusCenter = false;
|
||||
if (position === "entertainment_center") {
|
||||
isFocusCenter = true;
|
||||
}
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
|
||||
groupChannels.forEach((channel) => {
|
||||
if (channel.members[0].service.rid === serviceID) {
|
||||
const layoutObject = assignLightEntertainmentPos(isFocusCenter, channel.position, lightName, channel.channel_id);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
++channelNumber;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const layoutObject = assignLightEntertainmentPos(isFocusCenter, lightLocation.position, lightName);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Layout per manual settings
|
||||
let maxSegments = 1;
|
||||
|
||||
if (isAPIv2Ready && serviceID) {
|
||||
const service = hueEntertainmentServices.find(service => service.id === serviceID);
|
||||
maxSegments = service.segments.max_segments;
|
||||
}
|
||||
|
||||
if (maxSegments > 1) {
|
||||
const segment = service.segments.segments;
|
||||
const layoutObjects = assignSegmentedLightPos(segment, position, lightName);
|
||||
hueLedConfig.push(...layoutObjects);
|
||||
} else {
|
||||
const layoutObject = utils.assignLightPos(position, lightName);
|
||||
hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject)));
|
||||
}
|
||||
channelNumber += maxSegments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sc = window.serverConfig;
|
||||
sc.leds = hueLedConfig;
|
||||
|
||||
//Adjust gamma, brightness and compensation
|
||||
let c = sc.color.channelAdjustment[0];
|
||||
c.gammaBlue = 1.0;
|
||||
c.gammaRed = 1.0;
|
||||
c.gammaGreen = 1.0;
|
||||
c.brightness = 100;
|
||||
c.brightnessCompensation = 0;
|
||||
|
||||
//device config
|
||||
|
||||
//Start with a clean configuration
|
||||
let d = {};
|
||||
d.host = $('#host').val();
|
||||
d.port = parseInt($('#port').val());
|
||||
d.username = $('#user').val();
|
||||
d.type = 'philipshue';
|
||||
d.colorOrder = 'rgb';
|
||||
d.lightIds = finalLightIds;
|
||||
d.transitiontime = parseInt(utils.eV("transitiontime", 1));
|
||||
d.restoreOriginalState = utils.eV("restoreOriginalState", false);
|
||||
d.switchOffOnBlack = utils.eV("switchOffOnBlack", false);
|
||||
|
||||
d.blackLevel = parseFloat(utils.eV("blackLevel", 0.009));
|
||||
d.onBlackTimeToPowerOff = parseInt(utils.eV("onBlackTimeToPowerOff", 600));
|
||||
d.onBlackTimeToPowerOn = parseInt(utils.eV("onBlackTimeToPowerOn", 300));
|
||||
d.brightnessFactor = parseFloat(utils.eV("brightnessFactor", 1));
|
||||
|
||||
d.clientkey = $('#clientkey').val();
|
||||
d.groupId = $('#groupId').val();
|
||||
d.blackLightsTimeout = parseInt(utils.eV("blackLightsTimeout", 5000));
|
||||
d.brightnessMin = parseFloat(utils.eV("brightnessMin", 0));
|
||||
d.brightnessMax = parseFloat(utils.eV("brightnessMax", 1));
|
||||
d.brightnessThreshold = parseFloat(utils.eV("brightnessThreshold", 0.0001));
|
||||
d.handshakeTimeoutMin = parseInt(utils.eV("handshakeTimeoutMin", 300));
|
||||
d.handshakeTimeoutMax = parseInt(utils.eV("handshakeTimeoutMax", 1000));
|
||||
d.verbose = utils.eV("verbose");
|
||||
|
||||
d.autoStart = conf_editor.getEditor("root.generalOptions.autoStart").getValue();
|
||||
d.enableAttempts = parseInt(conf_editor.getEditor("root.generalOptions.enableAttempts").getValue());
|
||||
d.enableAttemptsInterval = parseInt(conf_editor.getEditor("root.generalOptions.enableAttemptsInterval").getValue());
|
||||
|
||||
d.useEntertainmentAPI = isEntertainmentReady && (d.groupId !== "");
|
||||
d.useAPIv2 = isAPIv2Ready;
|
||||
|
||||
if (d.useEntertainmentAPI) {
|
||||
d.hardwareLedCount = channelNumber;
|
||||
if (window.serverConfig.device.type !== d.type) {
|
||||
//smoothing on, if new device
|
||||
sc.smoothing = { enable: true };
|
||||
}
|
||||
} else {
|
||||
d.hardwareLedCount = finalLightIds.length;
|
||||
d.verbose = false;
|
||||
if (window.serverConfig.device.type !== d.type) {
|
||||
//smoothing off, if new device
|
||||
sc.smoothing = { enable: false };
|
||||
}
|
||||
}
|
||||
|
||||
window.serverConfig.device = d;
|
||||
|
||||
requestWriteConfig(sc, true);
|
||||
resetWizard();
|
||||
});
|
||||
|
||||
$('#btn_wiz_abort').off().on('click', resetWizard);
|
||||
}
|
||||
|
||||
function createHueUser() {
|
||||
const host = hueIPs[hueIPsinc].host;
|
||||
const port = hueIPs[hueIPsinc].port;
|
||||
|
||||
let params = { host: host };
|
||||
if (port !== 'undefined') {
|
||||
params.port = parseInt(port);
|
||||
}
|
||||
|
||||
let retryTime = 30;
|
||||
const retryInterval = 2;
|
||||
|
||||
const UserInterval = setInterval(function () {
|
||||
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(false);
|
||||
$('#wizp3').toggle(true);
|
||||
|
||||
(async () => {
|
||||
|
||||
retryTime -= retryInterval;
|
||||
$("#connectionTime").html(retryTime);
|
||||
if (retryTime <= 0) {
|
||||
abortConnection(UserInterval);
|
||||
clearInterval(UserInterval);
|
||||
}
|
||||
else {
|
||||
const res = await requestLedDeviceAddAuthorization('philipshue', params);
|
||||
if (res && !res.error) {
|
||||
const response = res.info;
|
||||
|
||||
if (jQuery.isEmptyObject(response)) {
|
||||
debugMessage(retryTime + ": link button not pressed or device not reachable");
|
||||
} else {
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
$('#wizp3').toggle(false);
|
||||
|
||||
const username = response.username;
|
||||
if (username != 'undefined') {
|
||||
$('#user').val(username);
|
||||
conf_editor.getEditor("root.specificOptions.username").setValue(username);
|
||||
conf_editor.getEditor("root.specificOptions.host").setValue(host);
|
||||
conf_editor.getEditor("root.specificOptions.port").setValue(port);
|
||||
}
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
const clientkey = response.clientkey;
|
||||
if (clientkey != 'undefined') {
|
||||
$('#clientkey').val(clientkey);
|
||||
conf_editor.getEditor("root.specificOptions.clientkey").setValue(clientkey);
|
||||
}
|
||||
}
|
||||
checkHueBridge(checkUserResult, username);
|
||||
clearInterval(UserInterval);
|
||||
}
|
||||
} else {
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
$('#wizp3').toggle(false);
|
||||
clearInterval(UserInterval);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
}, retryInterval * 1000);
|
||||
}
|
||||
|
||||
function get_hue_groups(username) {
|
||||
const host = hueIPs[hueIPsinc].host;
|
||||
|
||||
if (devicesProperties['philipshue'][host] && devicesProperties['philipshue'][host][username]) {
|
||||
const ledProperties = devicesProperties['philipshue'][host][username];
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
if (!jQuery.isEmptyObject(ledProperties.data)) {
|
||||
if (Object.keys(ledProperties.data).length > 0) {
|
||||
hueEntertainmentConfigs = ledProperties.data.filter(config => {
|
||||
return config.type === "entertainment_configuration";
|
||||
});
|
||||
hueEntertainmentServices = ledProperties.data.filter(config => {
|
||||
return (config.type === "entertainment" && config.renderer === true);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (!jQuery.isEmptyObject(ledProperties.groups)) {
|
||||
hueEntertainmentConfigs = [];
|
||||
let hueGroups = ledProperties.groups;
|
||||
for (const groupid in hueGroups) {
|
||||
if (hueGroups[groupid].type == 'Entertainment') {
|
||||
hueGroups[groupid].id = groupid;
|
||||
hueEntertainmentConfigs.push(hueGroups[groupid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(hueEntertainmentConfigs).length > 0) {
|
||||
|
||||
$('.lidsb').html("");
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
$('#hue_grp_ids_t').toggle(true);
|
||||
|
||||
for (const groupid in hueEntertainmentConfigs) {
|
||||
$('.gidsb').append(createTableRow([groupid + ' (' + hueEntertainmentConfigs[groupid].name + ')',
|
||||
'<button class="btn btn-sm btn-primary btn-group" data-groupid="' + groupid + '" data-username="' + username + '")>'
|
||||
+ $.i18n('wiz_hue_e_use_group') + '</button>']));
|
||||
}
|
||||
attachGroupButtonEvent();
|
||||
|
||||
} else {
|
||||
noAPISupport('wiz_hue_e_noegrpids', username);
|
||||
}
|
||||
}
|
||||
}
|
||||
function attachIdentifyButtonEvent() {
|
||||
$('#wizp2_body').on('click', '.btn-identify', function () {
|
||||
const hostname = $(this).data('hostname');
|
||||
const port = $(this).data('port');
|
||||
const user = $(this).data('user');
|
||||
const lightName = $(this).data('light-name');
|
||||
const lightId = $(this).data('light-id');
|
||||
const lightId_v1 = $(this).data('light-id-v1');
|
||||
|
||||
identify(hostname, port, user, lightName, lightId, lightId_v1);
|
||||
});
|
||||
}
|
||||
function attachGroupButtonEvent() {
|
||||
$('#wizp2_body').on('click', '.btn-group', function () {
|
||||
const groupid = $(this).data('groupid');
|
||||
const username = $(this).data('username');
|
||||
|
||||
useGroupId(groupid, username);
|
||||
});
|
||||
}
|
||||
|
||||
function noAPISupport(txt, username) {
|
||||
showNotification('danger', $.i18n('wiz_hue_e_title'), $.i18n('wiz_hue_e_noapisupport_hint'));
|
||||
conf_editor.getEditor("root.specificOptions.useEntertainmentAPI").setValue(false);
|
||||
$("#root_specificOptions_useEntertainmentAPI").trigger("change");
|
||||
$('#btn_wiz_holder').append('<div class="bs-callout bs-callout-danger" style="margin-top:0px">' + $.i18n('wiz_hue_e_noapisupport_hint') + '</div>');
|
||||
$('#hue_grp_ids_t').toggle(false);
|
||||
const errorMessage = txt ? $.i18n(txt) : $.i18n('wiz_hue_e_nogrpids');
|
||||
$('<p style="font-weight:bold;color:red;">' + errorMessage + '<br />' + $.i18n('wiz_hue_e_noapisupport') + '</p>').insertBefore('#wizp2_body #hue_ids_t');
|
||||
$('#hue_id_headline').html($.i18n('wiz_hue_desc2'));
|
||||
|
||||
get_hue_lights(username);
|
||||
}
|
||||
|
||||
function get_hue_lights(username) {
|
||||
const host = hueIPs[hueIPsinc].host;
|
||||
|
||||
if (devicesProperties['philipshue'][host] && devicesProperties['philipshue'][host][username]) {
|
||||
const ledProperties = devicesProperties['philipshue'][host][username];
|
||||
|
||||
if (isAPIv2Ready) {
|
||||
if (!jQuery.isEmptyObject(ledProperties.data)) {
|
||||
if (Object.keys(ledProperties.data).length > 0) {
|
||||
hueLights = ledProperties.data.filter(config => {
|
||||
return config.type === "light";
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (!jQuery.isEmptyObject(ledProperties.lights)) {
|
||||
hueLights = ledProperties.lights;
|
||||
}
|
||||
|
||||
if (Object.keys(hueLights).length > 0) {
|
||||
if (!isEntertainmentReady) {
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
}
|
||||
$('#hue_ids_t, #btn_wiz_save').toggle(true);
|
||||
|
||||
const lightOptions = [
|
||||
"top", "topleft", "topright",
|
||||
"bottom", "bottomleft", "bottomright",
|
||||
"left", "lefttop", "leftmiddle", "leftbottom",
|
||||
"right", "righttop", "rightmiddle", "rightbottom",
|
||||
"entire",
|
||||
"lightPosTopLeft112", "lightPosTopLeftNewMid", "lightPosTopLeft121",
|
||||
"lightPosBottomLeft14", "lightPosBottomLeft12", "lightPosBottomLeft34", "lightPosBottomLeft11",
|
||||
"lightPosBottomLeft112", "lightPosBottomLeftNewMid", "lightPosBottomLeft121"
|
||||
];
|
||||
|
||||
if (isEntertainmentReady && hueEntertainmentConfigs.length > 0) {
|
||||
lightOptions.unshift("entertainment_center");
|
||||
lightOptions.unshift("entertainment");
|
||||
} else {
|
||||
lightOptions.unshift("disabled");
|
||||
if (isAPIv2Ready) {
|
||||
for (const light in hueLights) {
|
||||
groupLights.push(hueLights[light].id);
|
||||
}
|
||||
} else {
|
||||
groupLights = Object.keys(hueLights);
|
||||
}
|
||||
}
|
||||
|
||||
$('.lidsb').html("");
|
||||
|
||||
let pos = "";
|
||||
for (const id in groupLights) {
|
||||
const lightId = groupLights[id];
|
||||
let lightId_v1 = "/lights/" + lightId;
|
||||
|
||||
let lightName;
|
||||
if (isAPIv2Ready) {
|
||||
const light = hueLights.find(light => light.id === lightId);
|
||||
lightName = light.metadata.name;
|
||||
lightId_v1 = light.id_v1;
|
||||
} else {
|
||||
lightName = hueLights[lightId].name;
|
||||
}
|
||||
|
||||
if (isEntertainmentReady) {
|
||||
let lightLocation = {};
|
||||
lightLocation = groupLightsLocations[id];
|
||||
if (lightLocation) {
|
||||
if (isAPIv2Ready) {
|
||||
pos = 0;
|
||||
} else {
|
||||
const x = lightLocation.position.x;
|
||||
const y = lightLocation.position.y;
|
||||
const z = lightLocation.position.z;
|
||||
|
||||
let xval = (x < 0) ? "left" : "right";
|
||||
if (z != 1 && x >= -0.25 && x <= 0.25) xval = "";
|
||||
switch (z) {
|
||||
case 1: // top / Ceiling height
|
||||
pos = "top" + xval;
|
||||
break;
|
||||
case 0: // middle / TV height
|
||||
pos = (xval == "" && y >= 0.75) ? "bottom" : xval + "middle";
|
||||
break;
|
||||
case -1: // bottom / Ground height
|
||||
pos = xval + "bottom";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let options = "";
|
||||
for (const opt in lightOptions) {
|
||||
const val = lightOptions[opt];
|
||||
const txt = (val != 'entire' && val != 'disabled') ? 'conf_leds_layout_cl_' : 'wiz_ids_';
|
||||
options += '<option value="' + val + '"';
|
||||
if (pos == val) options += ' selected="selected"';
|
||||
options += '>' + $.i18n(txt + val) + '</option>';
|
||||
}
|
||||
|
||||
$('.lidsb').append(createTableRow([id + ' (' + lightName + ')',
|
||||
'<select id="hue_' + lightId + '" class="hue_sel_watch form-control">'
|
||||
+ options
|
||||
+ '</select>',
|
||||
'<button class="btn btn-sm btn-primary btn-identify" data-hostname="' + encodeURIComponent($(" #host").val()) + '" data-port="' + $('#port').val() + '" data-user="' + $("#user").val() + '" data-light-name="' + encodeURIComponent(lightName) + '" data-light-id="' + lightId + '" data-light-id-v1="' + lightId_v1 + '">'
|
||||
+ $.i18n('wiz_hue_blinkblue', id)
|
||||
+ '</button>']));
|
||||
}
|
||||
attachIdentifyButtonEvent();
|
||||
|
||||
if (!isEntertainmentReady) {
|
||||
$('.hue_sel_watch').on("change", function () {
|
||||
let cC = 0;
|
||||
for (const key in hueLights) {
|
||||
if ($('#hue_' + key).val() != "disabled") {
|
||||
cC++;
|
||||
}
|
||||
}
|
||||
|
||||
(cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').prop("disabled", true) : $('#btn_wiz_save').prop("disabled", false);
|
||||
});
|
||||
}
|
||||
$('.hue_sel_watch').trigger('change');
|
||||
}
|
||||
else {
|
||||
const txt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_hue_noids') + '</p>';
|
||||
$('#wizp2_body').append(txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function abortConnection(UserInterval) {
|
||||
clearInterval(UserInterval);
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
$('#wizp3').toggle(false);
|
||||
$("#wiz_hue_usrstate").html($.i18n('wiz_hue_failure_connection'));
|
||||
}
|
||||
|
||||
return {
|
||||
start: function (e) {
|
||||
//create html
|
||||
const hue_title = 'wiz_hue_title';
|
||||
const hue_intro1 = 'wiz_hue_e_intro1';
|
||||
const hue_desc1 = 'wiz_hue_desc1';
|
||||
const hue_create_user = 'wiz_hue_create_user';
|
||||
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(hue_title));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(hue_title) + '</h4><p>' + $.i18n(hue_intro1) + '</p>');
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
|
||||
|
||||
let topContainer_html = '<p class="text-left" style="font-weight:bold">' + $.i18n(hue_desc1) + '</p>' +
|
||||
'<div class="row">' +
|
||||
'<div class="col-md-2">' +
|
||||
' <p class="text-left">' + $.i18n('wiz_hue_ip') + '</p></div>' +
|
||||
' <div class="col-md-7"><div class="input-group">' +
|
||||
' <span class="input-group-addon" id="retry_bridge" style="cursor:pointer"><i class="fa fa-refresh"></i></span>' +
|
||||
' <select id="hue_bridge_select" class="hue_bridge_sel_watch form-control">' + '</select>' + '</div></div>' +
|
||||
' <div class="col-md-7"><div class="input-group">' +
|
||||
' <span class="input-group-addon"><i class="fa fa-arrow-right"></i></span>' +
|
||||
' <input type="text" class="input-group form-control" id="host" placeholder="' + $.i18n('wiz_hue_ip') + '"></div></div>';
|
||||
|
||||
if (storedAccess === 'expert') {
|
||||
topContainer_html += '<div class="col-md-3"><div class="input-group">' +
|
||||
'<span class="input-group-addon">:</span>' +
|
||||
'<input type="text" class="input-group form-control" id="port" placeholder="' + $.i18n('edt_conf_general_port_title') + '"></div></div>';
|
||||
}
|
||||
|
||||
topContainer_html += '</div><p><span style="font-weight:bold;color:red" id="wiz_hue_ipstate"></span><span style="font-weight:bold;" id="wiz_hue_discovered"></span></p>';
|
||||
topContainer_html += '<div class="form-group" id="usrcont" style="display:none"></div>';
|
||||
|
||||
$('#wh_topcontainer').append(topContainer_html);
|
||||
|
||||
$('#usrcont').append('<div class="row"><div class="col-md-2"><p class="text-left">' + $.i18n('wiz_hue_username') + '</p ></div>' +
|
||||
'<div class="col-md-7">' +
|
||||
'<div class="input-group">' +
|
||||
' <span class="input-group-addon" id="retry_usr" style="cursor:pointer"><i class="fa fa-refresh"></i></span>' +
|
||||
' <input type="text" class="input-group form-control" id="user">' +
|
||||
'</div></div></div><br>' +
|
||||
'</div><input type="hidden" id="groupId">'
|
||||
);
|
||||
|
||||
$('#usrcont').append('<div id="hue_client_key_r" class="row"><div class="col-md-2"><p class="text-left">' + $.i18n('wiz_hue_clientkey') +
|
||||
'</p></div><div class="col-md-7"><input class="form-control" id="clientkey" type="text"></div></div><br>');
|
||||
|
||||
$('#usrcont').append('<p><span style="font-weight:bold;color:red" id="wiz_hue_usrstate"></span></p>' +
|
||||
'<button type="button" class="btn btn-primary" style="display:none" id="wiz_hue_create_user"> <i class="fa fa-fw fa-plus"></i>' + $.i18n(hue_create_user) + '</button>');
|
||||
|
||||
$('#wizp2_body').append('<div id="hue_grp_ids_t" style="display:none"><p class="text-left" style="font-weight:bold">' + $.i18n('wiz_hue_e_desc2') + '</p></div>');
|
||||
createTable("gidsh", "gidsb", "hue_grp_ids_t");
|
||||
$('.gidsh').append(createTableRow([$.i18n('edt_dev_spec_groupId_title'), ""], true));
|
||||
|
||||
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p class="text-left" style="font-weight:bold" id="hue_id_headline">' + $.i18n('wiz_hue_e_desc3') + '</p></div>');
|
||||
|
||||
createTable("lidsh", "lidsb", "hue_ids_t");
|
||||
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lightid_title'), $.i18n('wiz_pos'), $.i18n('wiz_identify')], true));
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>' + $.i18n('general_btn_save') + '</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
$('#wizp3_body').html('<span>' + $.i18n('wiz_hue_press_link') + '</span> <br /><br /><center><span id="connectionTime"></span><br /><i class="fa fa-cog fa-spin" style="font-size:100px"></i></center>');
|
||||
|
||||
if (getStorage("darkMode") == "on")
|
||||
$('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png');
|
||||
|
||||
//open modal
|
||||
$("#wizard_modal").modal({
|
||||
backdrop: "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
});
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
begin();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export { philipshueWizard }
|
||||
|
||||
60
assets/webconfig/js/wizards/LedDevice_utils.js
Normal file
60
assets/webconfig/js/wizards/LedDevice_utils.js
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
const ledDeviceWizardUtils = (() => {
|
||||
|
||||
// Layout positions
|
||||
const positionMap = {
|
||||
"top": { hmin: 0.15, hmax: 0.85, vmin: 0, vmax: 0.2 },
|
||||
"topleft": { hmin: 0, hmax: 0.15, vmin: 0, vmax: 0.15 },
|
||||
"topright": { hmin: 0.85, hmax: 1.0, vmin: 0, vmax: 0.15 },
|
||||
"bottom": { hmin: 0.15, hmax: 0.85, vmin: 0.8, vmax: 1.0 },
|
||||
"bottomleft": { hmin: 0, hmax: 0.15, vmin: 0.85, vmax: 1.0 },
|
||||
"bottomright": { hmin: 0.85, hmax: 1.0, vmin: 0.85, vmax: 1.0 },
|
||||
"left": { hmin: 0, hmax: 0.15, vmin: 0.15, vmax: 0.85 },
|
||||
"lefttop": { hmin: 0, hmax: 0.15, vmin: 0, vmax: 0.5 },
|
||||
"leftmiddle": { hmin: 0, hmax: 0.15, vmin: 0.25, vmax: 0.75 },
|
||||
"leftbottom": { hmin: 0, hmax: 0.15, vmin: 0.5, vmax: 1.0 },
|
||||
"right": { hmin: 0.85, hmax: 1.0, vmin: 0.15, vmax: 0.85 },
|
||||
"righttop": { hmin: 0.85, hmax: 1.0, vmin: 0, vmax: 0.5 },
|
||||
"rightmiddle": { hmin: 0.85, hmax: 1.0, vmin: 0.25, vmax: 0.75 },
|
||||
"rightbottom": { hmin: 0.85, hmax: 1.0, vmin: 0.5, vmax: 1.0 },
|
||||
"lightPosBottomLeft14": { hmin: 0, hmax: 0.25, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosBottomLeft12": { hmin: 0.25, hmax: 0.5, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosBottomLeft34": { hmin: 0.5, hmax: 0.75, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosBottomLeft11": { hmin: 0.75, hmax: 1, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosBottomLeft112": { hmin: 0, hmax: 0.5, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosBottomLeft121": { hmin: 0.5, hmax: 1, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosBottomLeftNewMid": { hmin: 0.25, hmax: 0.75, vmin: 0.85, vmax: 1.0 },
|
||||
"lightPosTopLeft112": { hmin: 0, hmax: 0.5, vmin: 0, vmax: 0.15 },
|
||||
"lightPosTopLeft121": { hmin: 0.5, hmax: 1, vmin: 0, vmax: 0.15 },
|
||||
"lightPosTopLeftNewMid": { hmin: 0.25, hmax: 0.75, vmin: 0, vmax: 0.15 },
|
||||
"lightPosEntire": { hmin: 0.0, hmax: 1.0, vmin: 0.0, vmax: 1.0 }
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
//return editor Value
|
||||
eV: function (vn, defaultVal = "") {
|
||||
let editor = null;
|
||||
if (vn) {
|
||||
editor = conf_editor.getEditor("root.specificOptions." + vn);
|
||||
}
|
||||
|
||||
if (editor === null) {
|
||||
return defaultVal;
|
||||
} else if (defaultVal !== "" && !isNaN(defaultVal) && isNaN(editor.getValue())) {
|
||||
return defaultVal;
|
||||
} else {
|
||||
return editor.getValue();
|
||||
}
|
||||
},
|
||||
assignLightPos: function (pos, name) {
|
||||
// Retrieve the corresponding position object from the positionMap
|
||||
const i = positionMap[pos] || positionMap["lightPosEntire"];
|
||||
i.name = name;
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
export { ledDeviceWizardUtils };
|
||||
300
assets/webconfig/js/wizards/LedDevice_yeelight.js
Normal file
300
assets/webconfig/js/wizards/LedDevice_yeelight.js
Normal file
@@ -0,0 +1,300 @@
|
||||
//****************************
|
||||
// Wizard Yeelight
|
||||
//****************************
|
||||
|
||||
import { ledDeviceWizardUtils as utils } from './LedDevice_utils.js';
|
||||
|
||||
const yeelightWizard = (() => {
|
||||
|
||||
const lights = [];
|
||||
let configuredLights = conf_editor.getEditor("root.specificOptions.lights").getValue();
|
||||
|
||||
function getHostInLights(hostname) {
|
||||
return lights.filter(
|
||||
function (lights) {
|
||||
return lights.host === hostname
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function begin() {
|
||||
discover();
|
||||
|
||||
$('#btn_wiz_save').off().on("click", function () {
|
||||
let ledConfig = [];
|
||||
let finalLights = [];
|
||||
|
||||
//create yeelight led config
|
||||
for (const key in lights) {
|
||||
if ($('#yee_' + key).val() !== "disabled") {
|
||||
|
||||
let name = lights[key].name;
|
||||
// Set Name to layout-position, if empty
|
||||
if (name === "") {
|
||||
name = lights[key].host;
|
||||
}
|
||||
|
||||
finalLights.push(lights[key]);
|
||||
|
||||
const idx_content = utils.assignLightPos($('#yee_' + key).val(), name);
|
||||
ledConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
||||
}
|
||||
}
|
||||
|
||||
//LED layout
|
||||
window.serverConfig.leds = ledConfig;
|
||||
|
||||
//LED device config
|
||||
const currentDeviceType = window.serverConfig.device.type;
|
||||
|
||||
//Start with a clean configuration
|
||||
let d = {};
|
||||
|
||||
d.type = 'yeelight';
|
||||
d.hardwareLedCount = finalLights.length;
|
||||
d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue();
|
||||
d.colorModel = parseInt(conf_editor.getEditor("root.specificOptions.colorModel").getValue());
|
||||
|
||||
d.transEffect = parseInt(conf_editor.getEditor("root.specificOptions.transEffect").getValue());
|
||||
d.transTime = parseInt(conf_editor.getEditor("root.specificOptions.transTime").getValue());
|
||||
d.extraTimeDarkness = parseInt(conf_editor.getEditor("root.specificOptions.extraTimeDarkness").getValue());
|
||||
|
||||
d.brightnessMin = parseInt(conf_editor.getEditor("root.specificOptions.brightnessMin").getValue());
|
||||
d.brightnessSwitchOffOnMinimum = JSON.parse(conf_editor.getEditor("root.specificOptions.brightnessSwitchOffOnMinimum").getValue());
|
||||
d.brightnessMax = parseInt(conf_editor.getEditor("root.specificOptions.brightnessMax").getValue());
|
||||
d.brightnessFactor = parseFloat(conf_editor.getEditor("root.specificOptions.brightnessFactor").getValue());
|
||||
|
||||
d.latchTime = parseInt(conf_editor.getEditor("root.specificOptions.latchTime").getValue());;
|
||||
d.debugLevel = parseInt(conf_editor.getEditor("root.specificOptions.debugLevel").getValue());
|
||||
|
||||
d.lights = finalLights;
|
||||
|
||||
window.serverConfig.device = d;
|
||||
|
||||
if (currentDeviceType !== d.type) {
|
||||
//smoothing off, if new device
|
||||
window.serverConfig.smoothing = { enable: false };
|
||||
}
|
||||
|
||||
requestWriteConfig(window.serverConfig, true);
|
||||
resetWizard();
|
||||
});
|
||||
|
||||
$('#btn_wiz_abort').off().on('click', resetWizard);
|
||||
}
|
||||
|
||||
async function discover() {
|
||||
// Get discovered lights
|
||||
const res = await requestLedDeviceDiscovery('yeelight');
|
||||
if (res && !res.error) {
|
||||
const r = res.info;
|
||||
|
||||
let discoveryMethod = "ssdp";
|
||||
if (res.info.discoveryMethod) {
|
||||
discoveryMethod = res.info.discoveryMethod;
|
||||
}
|
||||
|
||||
// Process devices returned by discovery
|
||||
for (const device of r.devices) {
|
||||
if (device.hostname !== "") {
|
||||
processDiscoverdDevice(device, discoveryMethod);
|
||||
}
|
||||
}
|
||||
|
||||
// Add additional items from configuration
|
||||
for (const configuredLight of configuredLights) {
|
||||
processConfiguredLight(configuredLight);
|
||||
}
|
||||
|
||||
assign_lights();
|
||||
}
|
||||
}
|
||||
|
||||
function processDiscoverdDevice(device, discoveryMethod) {
|
||||
if (getHostInLights(device.hostname).length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const light = {
|
||||
host: device.hostname
|
||||
};
|
||||
|
||||
if (discoveryMethod === "ssdp") {
|
||||
if (device.domain) {
|
||||
light.host += '.' + device.domain;
|
||||
}
|
||||
} else {
|
||||
light.host = device.service;
|
||||
light.name = device.name;
|
||||
}
|
||||
|
||||
light.port = device.port;
|
||||
|
||||
if (device.txt) {
|
||||
light.model = device.txt.md;
|
||||
light.port = 55443; // Yeelight default port
|
||||
} else {
|
||||
light.name = device.other.name;
|
||||
light.model = device.other.model;
|
||||
}
|
||||
|
||||
lights.push(light);
|
||||
}
|
||||
function processConfiguredLight(configuredLight) {
|
||||
const host = configuredLight.host;
|
||||
let port = configuredLight.port || 0;
|
||||
|
||||
if (host !== "" && getHostInLights(host).length === 0) {
|
||||
const light = {
|
||||
host: host,
|
||||
port: port,
|
||||
name: configuredLight.name,
|
||||
model: "color4"
|
||||
};
|
||||
|
||||
lights.push(light);
|
||||
}
|
||||
}
|
||||
|
||||
function attachIdentifyButtonEvent() {
|
||||
$('#wizp2_body').on('click', '.btn-identify', function () {
|
||||
const hostname = $(this).data('hostname');
|
||||
const port = $(this).data('port');
|
||||
identify(hostname, port);
|
||||
});
|
||||
}
|
||||
|
||||
function assign_lights() {
|
||||
// Model mappings, see https://www.home-assistant.io/integrations/yeelight/
|
||||
const models = ['color', 'color1', 'YLDP02YL', 'YLDP02YL', 'color2', 'YLDP06YL', 'color4', 'YLDP13YL', 'color6', 'YLDP13AYL', 'colorb', "YLDP005", 'colorc', "YLDP004-A", 'stripe', 'YLDD04YL', 'strip1', 'YLDD01YL', 'YLDD02YL', 'strip4', 'YLDD05YL', 'strip6', 'YLDD05YL'];
|
||||
|
||||
// If records are left for configuration
|
||||
if (Object.keys(lights).length > 0) {
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
$('#yee_ids_t, #btn_wiz_save').toggle(true);
|
||||
|
||||
const lightOptions = [
|
||||
"top", "topleft", "topright",
|
||||
"bottom", "bottomleft", "bottomright",
|
||||
"left", "lefttop", "leftmiddle", "leftbottom",
|
||||
"right", "righttop", "rightmiddle", "rightbottom",
|
||||
"entire",
|
||||
"lightPosTopLeft112", "lightPosTopLeftNewMid", "lightPosTopLeft121",
|
||||
"lightPosBottomLeft14", "lightPosBottomLeft12", "lightPosBottomLeft34", "lightPosBottomLeft11",
|
||||
"lightPosBottomLeft112", "lightPosBottomLeftNewMid", "lightPosBottomLeft121"
|
||||
];
|
||||
|
||||
lightOptions.unshift("disabled");
|
||||
|
||||
$('.lidsb').html("");
|
||||
let pos = "";
|
||||
|
||||
for (const lightid in lights) {
|
||||
const lightHostname = lights[lightid].host;
|
||||
const lightPort = lights[lightid].port;
|
||||
let lightName = lights[lightid].name;
|
||||
|
||||
if (lightName === "")
|
||||
lightName = $.i18n('edt_dev_spec_lights_itemtitle') + '(' + lightHostname + ')';
|
||||
|
||||
let options = "";
|
||||
for (const opt in lightOptions) {
|
||||
const val = lightOptions[opt];
|
||||
const txt = (val !== 'entire' && val !== 'disabled') ? 'conf_leds_layout_cl_' : 'wiz_ids_';
|
||||
options += '<option value="' + val + '"';
|
||||
if (pos === val) options += ' selected="selected"';
|
||||
options += '>' + $.i18n(txt + val) + '</option>';
|
||||
}
|
||||
|
||||
let enabled = 'enabled';
|
||||
if (!models.includes(lights[lightid].model)) {
|
||||
enabled = 'disabled';
|
||||
options = '<option value=disabled>' + $.i18n('wiz_yeelight_unsupported') + '</option>';
|
||||
}
|
||||
|
||||
$('.lidsb').append(createTableRow([(parseInt(lightid, 10) + 1) + '. ' + lightName, '<select id="yee_' + lightid + '" ' + enabled + ' class="yee_sel_watch form-control">'
|
||||
+ options
|
||||
+ '</select>', '<button class="btn btn-sm btn-primary btn-identify" data-hostname="' + lightHostname + '" data-port="' + lightPort + '")>'
|
||||
+ $.i18n('wiz_identify') + '</button>']));
|
||||
}
|
||||
attachIdentifyButtonEvent();
|
||||
|
||||
$('.yee_sel_watch').on("change", function () {
|
||||
let cC = 0;
|
||||
for (const key in lights) {
|
||||
if ($('#yee_' + key).val() !== "disabled") {
|
||||
cC++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cC === 0 || window.readOnlyMode)
|
||||
$('#btn_wiz_save').prop("disabled", true);
|
||||
else
|
||||
$('#btn_wiz_save').prop("disabled", false);
|
||||
});
|
||||
$('.yee_sel_watch').trigger('change');
|
||||
}
|
||||
else {
|
||||
const noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights', 'lights') + '</p>';
|
||||
$('#wizp2_body').append(noLightsTxt);
|
||||
}
|
||||
}
|
||||
|
||||
async function identify(host, port) {
|
||||
|
||||
const disabled = $('#btn_wiz_save').is(':disabled');
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').prop('disabled', true);
|
||||
|
||||
const params = { host: host, port: port };
|
||||
await requestLedDeviceIdentification("yeelight", params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').prop('disabled', disabled);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
start: function (e) {
|
||||
//create html
|
||||
const yeelight_title = 'wiz_yeelight_title';
|
||||
const yeelight_intro1 = 'wiz_yeelight_intro1';
|
||||
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(yeelight_title));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(yeelight_title) + '</h4><p>' + $.i18n(yeelight_intro1) + '</p>');
|
||||
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>'
|
||||
+ $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>'
|
||||
+ $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
|
||||
|
||||
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
|
||||
|
||||
$('#wizp2_body').append('<div id="yee_ids_t" style="display:none"><p style="font-weight:bold" id="yee_id_headline">' + $.i18n('wiz_yeelight_desc2') + '</p></div>');
|
||||
|
||||
createTable("lidsh", "lidsb", "yee_ids_t");
|
||||
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'), $.i18n('wiz_pos'), $.i18n('wiz_identify')], true));
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'
|
||||
+ $.i18n('general_btn_save') + '</button><buttowindow.serverConfig.device = d;n type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'
|
||||
+ $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
if (getStorage("darkMode") == "on")
|
||||
$('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png');
|
||||
|
||||
//open modal
|
||||
$("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true });
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
begin();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
}) ();
|
||||
|
||||
export { yeelightWizard };
|
||||
|
||||
485
assets/webconfig/js/wizards/colorCalibrationKodiWizard.js
Normal file
485
assets/webconfig/js/wizards/colorCalibrationKodiWizard.js
Normal file
@@ -0,0 +1,485 @@
|
||||
//****************************
|
||||
// Wizard Color calibration via Kodi
|
||||
//****************************
|
||||
const colorCalibrationKodiWizard = (() => {
|
||||
|
||||
let ws;
|
||||
const defaultKodiPort = 9090;
|
||||
|
||||
let kodiAddress = document.location.hostname;
|
||||
let kodiPort = defaultKodiPort;
|
||||
|
||||
const kodiUrl = new URL("ws://" + kodiAddress);
|
||||
kodiUrl.port = kodiPort;
|
||||
kodiUrl.pathname = "/jsonrpc/websocket";
|
||||
|
||||
let wiz_editor;
|
||||
let colorLength;
|
||||
let cobj;
|
||||
let step = 0;
|
||||
let withKodi = false;
|
||||
let profile = 0;
|
||||
let websAddress;
|
||||
let imgAddress;
|
||||
let picnr = 0;
|
||||
let id = 1;
|
||||
const vidAddress = "https://sourceforge.net/projects/hyperion-project/files/resources/vid/";
|
||||
const availVideos = ["Sweet_Cocoon", "Caminandes_2_GranDillama", "Caminandes_3_Llamigos"];
|
||||
|
||||
if (getStorage("kodiAddress") != null) {
|
||||
|
||||
kodiAddress = getStorage("kodiAddress");
|
||||
kodiUrl.host = kodiAddress;
|
||||
}
|
||||
|
||||
if (getStorage("kodiPort") != null) {
|
||||
kodiPort = getStorage("kodiPort");
|
||||
kodiUrl.port = kodiPort;
|
||||
}
|
||||
|
||||
$(window).on('beforeunload', function () {
|
||||
closeWebSocket();
|
||||
});
|
||||
|
||||
function closeWebSocket() {
|
||||
// Check if the WebSocket is open
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.close();
|
||||
}
|
||||
}
|
||||
|
||||
function sendToKodi(type, content) {
|
||||
let command;
|
||||
|
||||
switch (type) {
|
||||
case "msg":
|
||||
command = { "jsonrpc": "2.0", "method": "GUI.ShowNotification", "params": { "title": $.i18n('wiz_cc_title'), "message": content, "image": "info", "displaytime": 5000 }, "id": id };
|
||||
break;
|
||||
case "stop":
|
||||
command = { "jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": 2 }, "id": id };
|
||||
break;
|
||||
case "playP":
|
||||
content = imgAddress + content + '.png';
|
||||
command = { "jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "file": content } }, "id": id };
|
||||
break;
|
||||
case "playV":
|
||||
content = vidAddress + content;
|
||||
command = { "jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "file": content } }, "id": id };
|
||||
break;
|
||||
case "rotate":
|
||||
command = { "jsonrpc": "2.0", "method": "Player.Rotate", "params": { "playerid": 2 }, "id": id };
|
||||
break;
|
||||
default:
|
||||
console.error('Unknown Kodi command type: ', type);
|
||||
}
|
||||
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(JSON.stringify(command));
|
||||
++id;
|
||||
} else {
|
||||
console.error('WebSocket connection is not open. Unable to send command.');
|
||||
}
|
||||
}
|
||||
|
||||
function performAction() {
|
||||
let h;
|
||||
|
||||
if (step == 1) {
|
||||
$('#wiz_cc_desc').html($.i18n('wiz_cc_chooseid'));
|
||||
updateEditor(["id"]);
|
||||
$('#btn_wiz_back').prop("disabled", true);
|
||||
}
|
||||
else
|
||||
$('#btn_wiz_back').prop("disabled", false);
|
||||
|
||||
if (step == 2) {
|
||||
updateEditor(["white"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_white_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_white_title'));
|
||||
sendToKodi('playP', "white");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_white_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 3) {
|
||||
updateEditor(["gammaRed", "gammaGreen", "gammaBlue"]);
|
||||
h = '<p>' + $.i18n('wiz_cc_adjustgamma') + '</p>';
|
||||
if (withKodi) {
|
||||
sendToKodi('playP', "HGradient");
|
||||
h += '<button id="wiz_cc_btn_sp" class="btn btn-primary">' + $.i18n('wiz_cc_btn_switchpic') + '</button>';
|
||||
}
|
||||
else
|
||||
h += '<p>' + $.i18n('wiz_cc_lettvshowm', "grey_1, grey_2, grey_3, HGradient, VGradient") + '</p>';
|
||||
$('#wiz_cc_desc').html(h);
|
||||
$('#wiz_cc_btn_sp').off().on('click', function () {
|
||||
switchPicture(["VGradient", "grey_1", "grey_2", "grey_3", "HGradient"]);
|
||||
});
|
||||
}
|
||||
if (step == 4) {
|
||||
updateEditor(["red"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_red_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_red_title'));
|
||||
sendToKodi('playP', "red");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_red_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 5) {
|
||||
updateEditor(["green"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_green_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_green_title'));
|
||||
sendToKodi('playP', "green");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_green_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 6) {
|
||||
updateEditor(["blue"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_blue_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_blue_title'));
|
||||
sendToKodi('playP', "blue");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_blue_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 7) {
|
||||
updateEditor(["cyan"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_cyan_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_cyan_title'));
|
||||
sendToKodi('playP', "cyan");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_cyan_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 8) {
|
||||
updateEditor(["magenta"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_magenta_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_magenta_title'));
|
||||
sendToKodi('playP', "magenta");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_magenta_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 9) {
|
||||
updateEditor(["yellow"]);
|
||||
h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_yellow_title'));
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_yellow_title'));
|
||||
sendToKodi('playP', "yellow");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_yellow_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 10) {
|
||||
updateEditor(["backlightThreshold", "backlightColored"]);
|
||||
h = $.i18n('wiz_cc_backlight');
|
||||
if (withKodi) {
|
||||
h += '<br/>' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_black_title'));
|
||||
sendToKodi('playP', "black");
|
||||
}
|
||||
else
|
||||
h += '<br/>' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_black_title'));
|
||||
$('#wiz_cc_desc').html(h);
|
||||
}
|
||||
if (step == 11) {
|
||||
updateEditor([""], true);
|
||||
h = '<p>' + $.i18n('wiz_cc_testintro') + '</p>';
|
||||
if (withKodi) {
|
||||
h += '<p>' + $.i18n('wiz_cc_testintrok') + '</p>';
|
||||
sendToKodi('stop');
|
||||
availVideos.forEach(video => {
|
||||
const txt = video.replace(/_/g, " ");
|
||||
h += `<div><button id="${video}" class="btn btn-sm btn-primary videobtn"><i class="fa fa-fw fa-play"></i> ${txt}</button></div>`;
|
||||
});
|
||||
|
||||
h += '<div><button id="stop" class="btn btn-sm btn-danger videobtn" style="margin-bottom:15px"><i class="fa fa-fw fa-stop"></i> ' + $.i18n('wiz_cc_btn_stop') + '</button></div>';
|
||||
}
|
||||
else
|
||||
h += '<p>' + $.i18n('wiz_cc_testintrowok') + ' <a href="https://sourceforge.net/projects/hyperion-project/files/resources/vid/" target="_blank">' + $.i18n('wiz_cc_link') + '</a></p>';
|
||||
h += '<p>' + $.i18n('wiz_cc_summary') + '</p>';
|
||||
$('#wiz_cc_desc').html(h);
|
||||
|
||||
$('.videobtn').off().on('click', function (e) {
|
||||
if (e.target.id == "stop")
|
||||
sendToKodi("stop");
|
||||
else
|
||||
sendToKodi("playV", e.target.id + '.mp4');
|
||||
|
||||
$(this).prop("disabled", true);
|
||||
setTimeout(function () { $('.videobtn').prop("disabled", false) }, 10000);
|
||||
});
|
||||
|
||||
$('#btn_wiz_next').prop("disabled", true);
|
||||
$('#btn_wiz_save').toggle(true);
|
||||
window.readOnlyMode ? $('#btn_wiz_save').prop('disabled', true) : $('#btn_wiz_save').prop('disabled', false);
|
||||
}
|
||||
else {
|
||||
$('#btn_wiz_next').prop("disabled", false);
|
||||
$('#btn_wiz_save').toggle(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function switchPicture(pictures) {
|
||||
if (typeof pictures[picnr] === 'undefined')
|
||||
picnr = 0;
|
||||
|
||||
sendToKodi('playP', pictures[picnr]);
|
||||
picnr++;
|
||||
}
|
||||
|
||||
|
||||
function initializeWebSocket(cb) {
|
||||
if ("WebSocket" in window) {
|
||||
|
||||
if (kodiUrl.port === '') {
|
||||
kodiUrl.port = defaultKodiPort;
|
||||
}
|
||||
|
||||
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
||||
|
||||
// Establish WebSocket connection
|
||||
ws = new WebSocket(kodiUrl);
|
||||
|
||||
// WebSocket onopen event
|
||||
ws.onopen = function (event) {
|
||||
withKodi = true;
|
||||
cb("opened");
|
||||
};
|
||||
|
||||
// WebSocket onmessage event (handle incoming messages)
|
||||
ws.onmessage = function (event) {
|
||||
const response = JSON.parse(event.data);
|
||||
if (response.method === "System.OnQuit") {
|
||||
closeWebSocket();
|
||||
} else if (response.result != undefined) {
|
||||
if (response.result !== "OK") {
|
||||
cb("error");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// WebSocket onerror event
|
||||
ws.onerror = function (error) {
|
||||
cb("error");
|
||||
};
|
||||
|
||||
// WebSocket onclose event
|
||||
ws.onclose = function (event) {
|
||||
withKodi = false;
|
||||
if (event.code === 1006) {
|
||||
// Ignore error 1006 due to Kodi issue
|
||||
console.log("WebSocket closed with error code 1006. Ignoring due to Kodi bug.");
|
||||
}
|
||||
else {
|
||||
console.error("WebSocket closed with code:", event.code);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("WebSocket connection is already open.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("Kodi Access: WebSocket NOT supported by this browser");
|
||||
cb("error");
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
$('#btn_wiz_cancel').off().on('click', function () {
|
||||
stop(true);
|
||||
});
|
||||
$('#wiz_cc_kodiip').off().on('change', function () {
|
||||
|
||||
kodiAddress = encodeURIComponent($(this).val().trim());
|
||||
|
||||
$('#kodi_status').html('');
|
||||
if (kodiAddress !== "") {
|
||||
|
||||
if (!isValidHostnameOrIP(kodiAddress)) {
|
||||
|
||||
$('#kodi_status').html('<p style="color:red;font-weight:bold;margin-top:5px">' + $.i18n('edt_msgcust_error_hostname_ip') + '</p>');
|
||||
withKodi = false;
|
||||
|
||||
} else {
|
||||
|
||||
if (isValidIPv6(kodiAddress)) {
|
||||
kodiUrl.hostname = "[" + kodiAddress + "]";
|
||||
} else {
|
||||
kodiUrl.hostname = kodiAddress;
|
||||
}
|
||||
|
||||
$('#kodi_status').html('<p style="font-weight:bold;margin-top:5px">' + $.i18n('wiz_cc_try_connect') + '</p>');
|
||||
$('#btn_wiz_cont').prop('disabled', true);
|
||||
|
||||
closeWebSocket();
|
||||
initializeWebSocket(function (cb) {
|
||||
|
||||
if (cb == "opened") {
|
||||
setStorage("kodiAddress", kodiAddress);
|
||||
setStorage("kodiPort", defaultKodiPort);
|
||||
|
||||
$('#kodi_status').html('<p style="color:green;font-weight:bold;margin-top:5px">' + $.i18n('wiz_cc_kodicon') + '</p>');
|
||||
$('#btn_wiz_cont').prop('disabled', false);
|
||||
|
||||
if (withKodi) {
|
||||
sendToKodi("msg", $.i18n('wiz_cc_kodimsg_start'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#kodi_status').html('<p style="color:red;font-weight:bold;margin-top:5px">' + $.i18n('wiz_cc_kodidiscon') + '</p><p>' + $.i18n('wiz_cc_kodidisconlink') + ' <a href="https://sourceforge.net/projects/hyperion-project/files/resources/Hyperion_calibration_pictures.zip/download" target="_blank">' + $.i18n('wiz_cc_link') + '</p>');
|
||||
withKodi = false;
|
||||
}
|
||||
|
||||
$('#btn_wiz_cont').prop('disabled', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
begin();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
colorLength = window.serverConfig.color.channelAdjustment;
|
||||
cobj = window.schema.color.properties.channelAdjustment.items.properties;
|
||||
websAddress = document.location.hostname + ':' + window.serverConfig.webConfig.port;
|
||||
imgAddress = 'http://' + websAddress + '/img/cc/';
|
||||
setStorage("wizardactive", true);
|
||||
}
|
||||
|
||||
function initProfiles() {
|
||||
//check profile count
|
||||
if (colorLength.length > 1) {
|
||||
$('#multi_cali').html('<p style="font-weight:bold;">' + $.i18n('wiz_cc_morethanone') + '</p><select id="wiz_select" class="form-control" style="width:200px;margin:auto"></select>');
|
||||
for (let i = 0; i < colorLength.length; i++)
|
||||
$('#wiz_select').append(createSelOpt(i, i + 1 + ' (' + colorLength[i].id + ')'));
|
||||
|
||||
$('#wiz_select').off().on('change', function () {
|
||||
profile = $(this).val();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function createEditor() {
|
||||
wiz_editor = createJsonEditor('editor_container_wiz', {
|
||||
color: window.schema.color
|
||||
}, true, true);
|
||||
|
||||
$('#editor_container_wiz h4').toggle(false);
|
||||
$('#editor_container_wiz .btn-group').toggle(false);
|
||||
$('#editor_container_wiz [data-schemapath="root.color.imageToLedMappingType"]').toggle(false);
|
||||
$('#editor_container_wiz [data-schemapath="root.color.reducedPixelSetFactorFactor"]').toggle(false);
|
||||
for (let i = 0; i < colorLength.length; i++)
|
||||
$('#editor_container_wiz [data-schemapath*="root.color.channelAdjustment.' + i + '."]').toggle(false);
|
||||
}
|
||||
function updateEditor(el, all) {
|
||||
for (let key in cobj) {
|
||||
if (all === true || el[0] == key || el[1] == key || el[2] == key)
|
||||
$('#editor_container_wiz [data-schemapath*=".' + profile + '.' + key + '"]').toggle(true);
|
||||
else
|
||||
$('#editor_container_wiz [data-schemapath*=".' + profile + '.' + key + '"]').toggle(false);
|
||||
}
|
||||
}
|
||||
|
||||
function stop(reload) {
|
||||
if (withKodi) {
|
||||
sendToKodi("stop");
|
||||
}
|
||||
closeWebSocket();
|
||||
resetWizard(reload);
|
||||
}
|
||||
|
||||
function begin() {
|
||||
step = 0;
|
||||
|
||||
$('#btn_wiz_next').off().on('click', function () {
|
||||
step++;
|
||||
performAction();
|
||||
});
|
||||
|
||||
$('#btn_wiz_back').off().on('click', function () {
|
||||
step--;
|
||||
performAction();
|
||||
});
|
||||
|
||||
$('#btn_wiz_abort').off().on('click', function () {
|
||||
stop(true);
|
||||
});
|
||||
|
||||
$('#btn_wiz_save').off().on('click', function () {
|
||||
requestWriteConfig(wiz_editor.getValue());
|
||||
stop(true);
|
||||
});
|
||||
|
||||
wiz_editor.on("change", function (e) {
|
||||
const val = wiz_editor.getEditor('root.color.channelAdjustment.' + profile + '').getValue();
|
||||
const temp = JSON.parse(JSON.stringify(val));
|
||||
delete temp.leds
|
||||
requestAdjustment(JSON.stringify(temp), "", true);
|
||||
});
|
||||
|
||||
step++
|
||||
performAction();
|
||||
}
|
||||
|
||||
return {
|
||||
start: function () {
|
||||
//create html
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n('wiz_cc_title'));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n('wiz_cc_title') + '</h4>' +
|
||||
'<p>' + $.i18n('wiz_cc_intro1') + '</p>' +
|
||||
'<label>' + $.i18n('wiz_cc_kwebs') + '</label>' +
|
||||
'<input class="form-control" style="width:280px;margin:auto" id="wiz_cc_kodiip" type="text" placeholder="' + kodiAddress + '" value="' + kodiAddress + '" />' +
|
||||
'<span id="kodi_status"></span><span id="multi_cali"></span>'
|
||||
);
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont" disabled="disabled">' + '<i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button>' +
|
||||
'<button type="button" class="btn btn-danger" id="btn_wiz_cancel" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>'
|
||||
);
|
||||
$('#wizp2_body').html('<div id="wiz_cc_desc" style="font-weight:bold"></div><div id="editor_container_wiz"></div>'
|
||||
);
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_back">' + '<i class="fa fa-fw fa-chevron-left"></i>' + $.i18n('general_btn_back') + '</button>' +
|
||||
'<button type="button" class="btn btn-primary" id="btn_wiz_next">' + $.i18n('general_btn_next') + '<i style="margin-left:4px;"class="fa fa-fw fa-chevron-right"></i>' + '</button>' +
|
||||
'<button type="button" class="btn btn-warning" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>' + $.i18n('general_btn_save') + '</button>' +
|
||||
'<button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>'
|
||||
);
|
||||
|
||||
if (getStorage("darkMode") == "on")
|
||||
$('#wizard_logo').prop("src", 'img/hyperion/logo_negativ.png');
|
||||
|
||||
//open modal
|
||||
$("#wizard_modal").modal({
|
||||
backdrop: "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
});
|
||||
|
||||
setupEventListeners();
|
||||
$('#wiz_cc_kodiip').trigger("change");
|
||||
init();
|
||||
initProfiles();
|
||||
createEditor();
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export { colorCalibrationKodiWizard };
|
||||
143
assets/webconfig/js/wizards/rgbByteOrderWizard.js
Normal file
143
assets/webconfig/js/wizards/rgbByteOrderWizard.js
Normal file
@@ -0,0 +1,143 @@
|
||||
//****************************
|
||||
// Wizard RGB byte order
|
||||
//****************************
|
||||
|
||||
const rgbByteOrderWizard = (() => {
|
||||
|
||||
let wIntveralId;
|
||||
let new_rgb_order;
|
||||
|
||||
function changeColor() {
|
||||
let color = $("#wiz_canv_color").css('background-color');
|
||||
|
||||
if (color == 'rgb(255, 0, 0)') {
|
||||
$("#wiz_canv_color").css('background-color', 'rgb(0, 255, 0)');
|
||||
requestSetColor('0', '255', '0');
|
||||
}
|
||||
else {
|
||||
$("#wiz_canv_color").css('background-color', 'rgb(255, 0, 0)');
|
||||
requestSetColor('255', '0', '0');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function stopWizardRGB(reload) {
|
||||
console.log("stopWizardRGB - reload: ", reload);
|
||||
clearInterval(wIntveralId);
|
||||
resetWizard(reload);
|
||||
}
|
||||
|
||||
function beginWizardRGB() {
|
||||
$("#wiz_switchtime_select").off().on('change', function () {
|
||||
clearInterval(wIntveralId);
|
||||
const time = $("#wiz_switchtime_select").val();
|
||||
wIntveralId = setInterval(function () { changeColor(); }, time * 1000);
|
||||
});
|
||||
|
||||
$('.wselect').on("change", function () {
|
||||
let rgb_order = window.serverConfig.device.colorOrder.split("");
|
||||
const redS = $("#wiz_r_select").val();
|
||||
const greenS = $("#wiz_g_select").val();
|
||||
const blueS = rgb_order.toString().replace(/,/g, "").replace(redS, "").replace(greenS, "");
|
||||
|
||||
for (const color of rgb_order) {
|
||||
if (redS == color)
|
||||
$('#wiz_g_select option[value=' + color + ']').prop('disabled', true);
|
||||
else
|
||||
$('#wiz_g_select option[value=' + color + ']').prop('disabled', false);
|
||||
if (greenS == color)
|
||||
$('#wiz_r_select option[value=' + color + ']').prop('disabled', true);
|
||||
else
|
||||
$('#wiz_r_select option[value=' + color + ']').prop('disabled', false);
|
||||
}
|
||||
|
||||
if (redS != 'null' && greenS != 'null') {
|
||||
$('#btn_wiz_save').prop('disabled', false);
|
||||
|
||||
for (let i = 0; i < rgb_order.length; i++) {
|
||||
if (rgb_order[i] == "r")
|
||||
rgb_order[i] = redS;
|
||||
else if (rgb_order[i] == "g")
|
||||
rgb_order[i] = greenS;
|
||||
else
|
||||
rgb_order[i] = blueS;
|
||||
}
|
||||
|
||||
rgb_order = rgb_order.toString().replace(/,/g, "");
|
||||
|
||||
if (redS == "r" && greenS == "g") {
|
||||
$('#btn_wiz_save').toggle(false);
|
||||
$('#btn_wiz_checkok').toggle(true);
|
||||
|
||||
window.readOnlyMode ? $('#btn_wiz_checkok').prop('disabled', true) : $('#btn_wiz_checkok').prop('disabled', false);
|
||||
}
|
||||
else {
|
||||
$('#btn_wiz_save').toggle(true);
|
||||
window.readOnlyMode ? $('#btn_wiz_save').prop('disabled', true) : $('#btn_wiz_save').prop('disabled', false);
|
||||
|
||||
$('#btn_wiz_checkok').toggle(false);
|
||||
}
|
||||
new_rgb_order = rgb_order;
|
||||
}
|
||||
else
|
||||
$('#btn_wiz_save').prop('disabled', true);
|
||||
});
|
||||
|
||||
$("#wiz_switchtime_select").append(createSelOpt('5', '5'), createSelOpt('10', '10'), createSelOpt('15', '15'), createSelOpt('30', '30'));
|
||||
$("#wiz_switchtime_select").trigger('change');
|
||||
|
||||
$("#wiz_r_select").append(createSelOpt("null", ""), createSelOpt('r', $.i18n('general_col_red')), createSelOpt('g', $.i18n('general_col_green')), createSelOpt('b', $.i18n('general_col_blue')));
|
||||
$("#wiz_g_select").html($("#wiz_r_select").html());
|
||||
$("#wiz_r_select").trigger('change');
|
||||
|
||||
requestSetColor('255', '0', '0');
|
||||
setTimeout(requestSetSource, 100, 'auto');
|
||||
setStorage("wizardactive", true);
|
||||
|
||||
$('#btn_wiz_abort').off().on('click', function () { stopWizardRGB(true); });
|
||||
|
||||
$('#btn_wiz_checkok').off().on('click', function () {
|
||||
showInfoDialog('success', "", $.i18n('infoDialog_wizrgb_text'));
|
||||
stopWizardRGB();
|
||||
});
|
||||
|
||||
$('#btn_wiz_save').off().on('click', function () {
|
||||
stopWizardRGB();
|
||||
window.serverConfig.device.colorOrder = new_rgb_order;
|
||||
requestWriteConfig({ "device": window.serverConfig.device });
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
start: function () {
|
||||
//create html
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n('wiz_rgb_title'));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n('wiz_rgb_title') + '</h4><p>' + $.i18n('wiz_rgb_intro1') + '</p><p style="font-weight:bold;">' + $.i18n('wiz_rgb_intro2') + '</p>');
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
$('#wizp2_body').html('<p style="font-weight:bold">' + $.i18n('wiz_rgb_expl') + '</p>');
|
||||
$('#wizp2_body').append('<div class="form-group"><label>' + $.i18n('wiz_rgb_switchevery') + '</label><div class="input-group" style="width:100px"><select id="wiz_switchtime_select" class="form-control"></select><div class="input-group-addon">' + $.i18n('edt_append_s') + '</div></div></div>');
|
||||
$('#wizp2_body').append('<canvas id="wiz_canv_color" width="100" height="100" style="border-radius:60px;background-color:red; display:block; margin: 10px 0;border:4px solid grey;"></canvas><label>' + $.i18n('wiz_rgb_q') + '</label>');
|
||||
$('#wizp2_body').append('<table class="table borderless" style="width:200px"><tbody><tr><td class="ltd"><label>' + $.i18n('wiz_rgb_qrend') + '</label></td><td class="itd"><select id="wiz_r_select" class="form-control wselect"></select></td></tr><tr><td class="ltd"><label>' + $.i18n('wiz_rgb_qgend') + '</label></td><td class="itd"><select id="wiz_g_select" class="form-control wselect"></select></td></tr></tbody></table>');
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save"><i class="fa fa-fw fa-save"></i>' + $.i18n('general_btn_save') + '</button><button type="button" class="btn btn-primary" id="btn_wiz_checkok" style="display:none" data-dismiss="modal"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_ok') + '</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
if (getStorage("darkMode") == "on")
|
||||
$('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png');
|
||||
|
||||
//open modal
|
||||
$("#wizard_modal").modal({
|
||||
backdrop: "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
});
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
beginWizardRGB();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export { rgbByteOrderWizard };
|
||||
Reference in New Issue
Block a user