mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
efc2046ab5
* LedDevice - Address clang findings * Fix Windows Warnings * Ensure newInput is initialised * Clean-up unused elements for Plaform Capture * Fix initialization problem and spellings * Address clang findings and spelling corrections * LedDevice clean-ups * Cleanups * Align that getLedCount is int * Have "display" as default for Grabbers * Fix config during start-up for missing elements * Framegrabber Clean-up - Remove non supported grabbers from selection, filter valid options * Typo * Framegrabber.json - Fix property numbering * Preselect active Grabbertype * Sort Grabbernames * Align options with selected element * Fix deletion of pointer to incomplete type 'BonjourBrowserWrapper' * Address macOS compile warnings * Have default layout = 1 LED only to avoid errors as in #673 * Address lgtm findings * Address finding that params passed to LedDevice discovery were not considered * Cleanups after merging with latest master * Update Changelog * Address lgtm findings * Fix comment * Test Fix * Fix Python Warning * Handle Dummy Device assignment correctly * Address delete called on non-final 'commandline::Option' that has virtual functions but non-virtual destructor * Correct that QTimer.start accepts only int * Have Release Python GIL & reset threat state chnage downward compatible * Correct format specifier * LedDevice - add assertions * Readonly DB - Fix merge issue * Smoothing - Fix wrong defaults * LedDevice - correct assertion * Show smoothing config set# in debug and related values. * Suppress error on windows, if default file is "/dev/null" * CMAKE - Allow to define QT_BASE_DIR dynamically via environment-variable * Ignore Visual Studio specific files Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com>
2050 lines
72 KiB
JavaScript
2050 lines
72 KiB
JavaScript
//clear priority and other tasks if people reload the page or lost connection while a wizard was active
|
|
$(window.hyperion).one("ready", function (event) {
|
|
if (getStorage("wizardactive") === 'true') {
|
|
requestPriorityClear();
|
|
setStorage("wizardactive", false);
|
|
if (getStorage("kodiAddress") != null) {
|
|
kodiAddress = getStorage("kodiAddress");
|
|
sendToKodi("stop");
|
|
}
|
|
}
|
|
});
|
|
|
|
function resetWizard(reload) {
|
|
$("#wizard_modal").modal('hide');
|
|
clearInterval(wIntveralId);
|
|
requestPriorityClear();
|
|
setStorage("wizardactive", false);
|
|
$('#wizp1').toggle(true);
|
|
$('#wizp2').toggle(false);
|
|
$('#wizp3').toggle(false);
|
|
//cc
|
|
if (withKodi)
|
|
sendToKodi("stop");
|
|
step = 0;
|
|
if (!reload) location.reload();
|
|
}
|
|
|
|
//rgb byte order wizard
|
|
var wIntveralId;
|
|
var new_rgb_order;
|
|
|
|
function changeColor() {
|
|
var 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 startWizardRGB() {
|
|
//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>');
|
|
|
|
//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);
|
|
});
|
|
}
|
|
|
|
function beginWizardRGB() {
|
|
$("#wiz_switchtime_select").off().on('change', function () {
|
|
clearInterval(wIntveralId);
|
|
var time = $("#wiz_switchtime_select").val();
|
|
wIntveralId = setInterval(function () { changeColor(); }, time * 1000);
|
|
});
|
|
|
|
$('.wselect').change(function () {
|
|
var rgb_order = window.serverConfig.device.colorOrder.split("");
|
|
var redS = $("#wiz_r_select").val();
|
|
var greenS = $("#wiz_g_select").val();
|
|
var blueS = rgb_order.toString().replace(/,/g, "").replace(redS, "").replace(greenS, "");
|
|
|
|
for (var i = 0; i < rgb_order.length; i++) {
|
|
if (redS == rgb_order[i])
|
|
$('#wiz_g_select option[value=' + rgb_order[i] + ']').attr('disabled', true);
|
|
else
|
|
$('#wiz_g_select option[value=' + rgb_order[i] + ']').attr('disabled', false);
|
|
if (greenS == rgb_order[i])
|
|
$('#wiz_r_select option[value=' + rgb_order[i] + ']').attr('disabled', true);
|
|
else
|
|
$('#wiz_r_select option[value=' + rgb_order[i] + ']').attr('disabled', false);
|
|
}
|
|
|
|
if (redS != 'null' && greenS != 'null') {
|
|
$('#btn_wiz_save').attr('disabled', false);
|
|
|
|
for (var 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').attr('disabled', true) : $('#btn_wiz_checkok').attr('disabled', false);
|
|
}
|
|
else {
|
|
$('#btn_wiz_save').toggle(true);
|
|
window.readOnlyMode ? $('#btn_wiz_save').attr('disabled', true) : $('#btn_wiz_save').attr('disabled', false);
|
|
|
|
$('#btn_wiz_checkok').toggle(false);
|
|
}
|
|
new_rgb_order = rgb_order;
|
|
}
|
|
else
|
|
$('#btn_wiz_save').attr('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 () { resetWizard(true); });
|
|
|
|
$('#btn_wiz_checkok').off().on('click', function () {
|
|
showInfoDialog('success', "", $.i18n('infoDialog_wizrgb_text'));
|
|
resetWizard();
|
|
});
|
|
|
|
$('#btn_wiz_save').off().on('click', function () {
|
|
resetWizard();
|
|
window.serverConfig.device.colorOrder = new_rgb_order;
|
|
requestWriteConfig({ "device": window.serverConfig.device });
|
|
});
|
|
}
|
|
|
|
$('#btn_wizard_byteorder').off().on('click', startWizardRGB);
|
|
|
|
//color calibration wizard
|
|
|
|
var kodiHost = document.location.hostname;
|
|
var kodiPort = 9090;
|
|
var kodiAddress = kodiHost;
|
|
|
|
var wiz_editor;
|
|
var colorLength;
|
|
var cobj;
|
|
var step = 0;
|
|
var withKodi = false;
|
|
var profile = 0;
|
|
var websAddress;
|
|
var imgAddress;
|
|
var vidAddress = "https://sourceforge.net/projects/hyperion-project/files/resources/vid/";
|
|
var picnr = 0;
|
|
var availVideos = ["Sweet_Cocoon", "Caminandes_2_GranDillama", "Caminandes_3_Llamigos"];
|
|
|
|
if (getStorage("kodiAddress") != null) {
|
|
|
|
kodiAddress = getStorage("kodiAddress");
|
|
[kodiHost, kodiPort] = kodiAddress.split(":", 2);
|
|
|
|
// Ensure that Kodi's default REST-API port is not used, as now the Web-Socket port is used
|
|
if (kodiPort === "8080") {
|
|
kodiAddress = kodiHost;
|
|
kodiPort = undefined;
|
|
setStorage("kodiAddress", kodiAddress);
|
|
}
|
|
}
|
|
|
|
function switchPicture(pictures) {
|
|
if (typeof pictures[picnr] === 'undefined')
|
|
picnr = 0;
|
|
|
|
sendToKodi('playP', pictures[picnr]);
|
|
picnr++;
|
|
}
|
|
|
|
function sendToKodi(type, content, cb) {
|
|
var 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": "1" };
|
|
break;
|
|
case "stop":
|
|
command = { "jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": 2 }, "id": "1" };
|
|
break;
|
|
case "playP":
|
|
content = imgAddress + content + '.png';
|
|
command = { "jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "file": content } }, "id": "1" };
|
|
break;
|
|
case "playV":
|
|
content = vidAddress + content;
|
|
command = { "jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "file": content } }, "id": "1" };
|
|
break;
|
|
case "rotate":
|
|
command = { "jsonrpc": "2.0", "method": "Player.Rotate", "params": { "playerid": 2 }, "id": "1" };
|
|
break;
|
|
default:
|
|
if (cb != undefined) {
|
|
cb("error");
|
|
}
|
|
}
|
|
|
|
if ("WebSocket" in window) {
|
|
//Add kodi default web-socket port, in case port has been explicitly provided
|
|
if (kodiPort == undefined) {
|
|
kodiPort = 9090;
|
|
}
|
|
|
|
var ws = new WebSocket("ws://" + kodiHost + ":" + kodiPort + "/jsonrpc/websocket");
|
|
|
|
ws.onopen = function () {
|
|
ws.send(JSON.stringify(command));
|
|
};
|
|
|
|
ws.onmessage = function (evt) {
|
|
var response = JSON.parse(evt.data);
|
|
|
|
if (cb != undefined) {
|
|
if (response.result != undefined) {
|
|
if (response.result === "OK") {
|
|
cb("success");
|
|
} else {
|
|
cb("error");
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
ws.onerror = function (evt) {
|
|
if (cb != undefined) {
|
|
cb("error");
|
|
}
|
|
};
|
|
}
|
|
else {
|
|
console.log("Kodi Access: WebSocket NOT supported by this browser");
|
|
cb("error");
|
|
}
|
|
}
|
|
|
|
function performAction() {
|
|
var h;
|
|
|
|
if (step == 1) {
|
|
$('#wiz_cc_desc').html($.i18n('wiz_cc_chooseid'));
|
|
updateWEditor(["id"]);
|
|
$('#btn_wiz_back').attr("disabled", true);
|
|
}
|
|
else
|
|
$('#btn_wiz_back').attr("disabled", false);
|
|
|
|
if (step == 2) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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', "gey_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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor(["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) {
|
|
updateWEditor([""], true);
|
|
h = '<p>' + $.i18n('wiz_cc_testintro') + '</p>';
|
|
if (withKodi) {
|
|
h += '<p>' + $.i18n('wiz_cc_testintrok') + '</p>';
|
|
sendToKodi('stop');
|
|
for (var i = 0; i < availVideos.length; i++) {
|
|
var txt = availVideos[i].replace(/_/g, " ");
|
|
h += '<div><button id="' + availVideos[i] + '" 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).attr("disabled", true);
|
|
setTimeout(function () { $('.videobtn').attr("disabled", false) }, 10000);
|
|
});
|
|
|
|
$('#btn_wiz_next').attr("disabled", true);
|
|
$('#btn_wiz_save').toggle(true);
|
|
window.readOnlyMode ? $('#btn_wiz_save').attr('disabled', true) : $('#btn_wiz_save').attr('disabled', false);
|
|
}
|
|
else {
|
|
$('#btn_wiz_next').attr("disabled", false);
|
|
$('#btn_wiz_save').toggle(false);
|
|
}
|
|
}
|
|
|
|
function updateWEditor(el, all) {
|
|
for (var 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 startWizardCC() {
|
|
|
|
// Ensure that Kodi's default REST-API port is not used, as now the Web-Socket port is used
|
|
[kodiHost, kodiPort] = kodiAddress.split(":", 2);
|
|
if (kodiPort === "8080") {
|
|
kodiAddress = kodiHost;
|
|
kodiPort = undefined;
|
|
}
|
|
//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:170px;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" 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>');
|
|
|
|
//open modal
|
|
$("#wizard_modal").modal({
|
|
backdrop: "static",
|
|
keyboard: false,
|
|
show: true
|
|
});
|
|
|
|
$('#wiz_cc_kodiip').off().on('change', function () {
|
|
|
|
kodiAddress = $(this).val().trim();
|
|
$('#wizp1_body').find("kodiAddress").val(kodiAddress);
|
|
|
|
$('#kodi_status').html('');
|
|
|
|
// Remove Kodi's default Web-Socket port (9090) from display and ensure Kodi's default REST-API port (8080) is mapped to web-socket port to ease migration
|
|
if (kodiAddress !== "") {
|
|
[kodiHost, kodiPort] = kodiAddress.split(":", 2);
|
|
if (kodiPort === "9090" || kodiPort === "8080") {
|
|
kodiAddress = kodiHost;
|
|
kodiPort = undefined;
|
|
}
|
|
sendToKodi("msg", $.i18n('wiz_cc_kodimsg_start'), function (cb) {
|
|
if (cb == "error") {
|
|
$('#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;
|
|
}
|
|
else {
|
|
setStorage("kodiAddress", kodiAddress);
|
|
|
|
$('#kodi_status').html('<p style="color:green;font-weight:bold;margin-top:5px">' + $.i18n('wiz_cc_kodicon') + '</p>');
|
|
withKodi = true;
|
|
}
|
|
|
|
$('#btn_wiz_cont').attr('disabled', false);
|
|
});
|
|
}
|
|
});
|
|
|
|
//listen for continue
|
|
$('#btn_wiz_cont').off().on('click', function () {
|
|
beginWizardCC();
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
});
|
|
|
|
$('#wiz_cc_kodiip').trigger("change");
|
|
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);
|
|
|
|
//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 (var 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();
|
|
});
|
|
}
|
|
|
|
//prepare editor
|
|
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);
|
|
for (var i = 0; i < colorLength.length; i++)
|
|
$('#editor_container_wiz [data-schemapath*="root.color.channelAdjustment.' + i + '."]').toggle(false);
|
|
}
|
|
|
|
function beginWizardCC() {
|
|
$('#btn_wiz_next').off().on('click', function () {
|
|
step++;
|
|
performAction();
|
|
});
|
|
|
|
$('#btn_wiz_back').off().on('click', function () {
|
|
step--;
|
|
performAction();
|
|
});
|
|
|
|
$('#btn_wiz_abort').off().on('click', resetWizard);
|
|
|
|
$('#btn_wiz_save').off().on('click', function () {
|
|
requestWriteConfig(wiz_editor.getValue());
|
|
resetWizard();
|
|
});
|
|
|
|
wiz_editor.on("change", function (e) {
|
|
var val = wiz_editor.getEditor('root.color.channelAdjustment.' + profile + '').getValue();
|
|
var temp = JSON.parse(JSON.stringify(val));
|
|
delete temp.leds
|
|
requestAdjustment(JSON.stringify(temp), "", true);
|
|
});
|
|
|
|
step++
|
|
performAction();
|
|
}
|
|
|
|
$('#btn_wizard_colorcalibration').off().on('click', startWizardCC);
|
|
|
|
// Layout positions
|
|
var lightPosTop = { hmin: 0.15, hmax: 0.85, vmin: 0, vmax: 0.2 };
|
|
var lightPosTopLeft = { hmin: 0, hmax: 0.15, vmin: 0, vmax: 0.15 };
|
|
var lightPosTopRight = { hmin: 0.85, hmax: 1.0, vmin: 0, vmax: 0.15 };
|
|
var lightPosBottom = { hmin: 0.15, hmax: 0.85, vmin: 0.8, vmax: 1.0 };
|
|
var lightPosBottomLeft = { hmin: 0, hmax: 0.15, vmin: 0.85, vmax: 1.0 };
|
|
var lightPosBottomRight = { hmin: 0.85, hmax: 1.0, vmin: 0.85, vmax: 1.0 };
|
|
var lightPosLeft = { hmin: 0, hmax: 0.15, vmin: 0.15, vmax: 0.85 };
|
|
var lightPosLeftTop = { hmin: 0, hmax: 0.15, vmin: 0, vmax: 0.5 };
|
|
var lightPosLeftMiddle = { hmin: 0, hmax: 0.15, vmin: 0.25, vmax: 0.75 };
|
|
var lightPosLeftBottom = { hmin: 0, hmax: 0.15, vmin: 0.5, vmax: 1.0 };
|
|
var lightPosRight = { hmin: 0.85, hmax: 1.0, vmin: 0.15, vmax: 0.85 };
|
|
var lightPosRightTop = { hmin: 0.85, hmax: 1.0, vmin: 0, vmax: 0.5 };
|
|
var lightPosRightMiddle = { hmin: 0.85, hmax: 1.0, vmin: 0.25, vmax: 0.75 };
|
|
var lightPosRightBottom = { hmin: 0.85, hmax: 1.0, vmin: 0.5, vmax: 1.0 };
|
|
var lightPosEntire = { hmin: 0.0, hmax: 1.0, vmin: 0.0, vmax: 1.0 };
|
|
|
|
function assignLightPos(id, pos, name) {
|
|
var i = null;
|
|
|
|
if (pos === "top")
|
|
i = lightPosTop;
|
|
else if (pos === "topleft")
|
|
i = lightPosTopLeft;
|
|
else if (pos === "topright")
|
|
i = lightPosTopRight;
|
|
else if (pos === "bottom")
|
|
i = lightPosBottom;
|
|
else if (pos === "bottomleft")
|
|
i = lightPosBottomLeft;
|
|
else if (pos === "bottomright")
|
|
i = lightPosBottomRight;
|
|
else if (pos === "left")
|
|
i = lightPosLeft;
|
|
else if (pos === "lefttop")
|
|
i = lightPosLeftTop;
|
|
else if (pos === "leftmiddle")
|
|
i = lightPosLeftMiddle;
|
|
else if (pos === "leftbottom")
|
|
i = lightPosLeftBottom;
|
|
else if (pos === "right")
|
|
i = lightPosRight;
|
|
else if (pos === "righttop")
|
|
i = lightPosRightTop;
|
|
else if (pos === "rightmiddle")
|
|
i = lightPosRightMiddle;
|
|
else if (pos === "rightbottom")
|
|
i = lightPosRightBottom;
|
|
else
|
|
i = lightPosEntire;
|
|
|
|
i.name = name;
|
|
return i;
|
|
}
|
|
|
|
function getHostInLights(hostname) {
|
|
return lights.filter(
|
|
function (lights) {
|
|
return lights.host === hostname
|
|
}
|
|
);
|
|
}
|
|
|
|
function getIpInLights(ip) {
|
|
return lights.filter(
|
|
function (lights) {
|
|
return lights.ip === ip
|
|
}
|
|
);
|
|
}
|
|
|
|
function getIdInLights(id) {
|
|
return lights.filter(
|
|
function (lights) {
|
|
return lights.id === id
|
|
}
|
|
);
|
|
}
|
|
|
|
//****************************
|
|
// Wizard Philips Hue
|
|
//****************************
|
|
|
|
var hueIPs = [];
|
|
var hueIPsinc = 0;
|
|
var lightIDs = null;
|
|
var groupIDs = null;
|
|
var lightLocation = [];
|
|
var groupLights = [];
|
|
var groupLightsLocations = [];
|
|
var hueType = "philipshue";
|
|
|
|
function startWizardPhilipsHue(e) {
|
|
if (typeof e.data.type != "undefined") hueType = e.data.type;
|
|
|
|
//create html
|
|
|
|
var hue_title = 'wiz_hue_title';
|
|
var hue_intro1 = 'wiz_hue_intro1';
|
|
var hue_desc1 = 'wiz_hue_desc1';
|
|
var hue_create_user = 'wiz_hue_create_user';
|
|
if (hueType == 'philipshueentertainment') {
|
|
hue_title = 'wiz_hue_e_title';
|
|
hue_intro1 = 'wiz_hue_e_intro1';
|
|
hue_desc1 = 'wiz_hue_e_desc1';
|
|
hue_create_user = 'wiz_hue_e_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>');
|
|
$('#wh_topcontainer').append('<p style="font-weight:bold">' + $.i18n(hue_desc1) + '</p><div class="form-group"><label>' + $.i18n('wiz_hue_ip') + '</label><div class="input-group" style="width:175px"><input type="text" class="input-group form-control" id="ip"><span class="input-group-addon" id="retry_bridge" style="cursor:pointer"><i class="fa fa-refresh"></i></span></div></div><span style="font-weight:bold;color:red" id="wiz_hue_ipstate"></span><span style="font-weight:bold;" class="component-on" id="wiz_hue_discovered"></span>');
|
|
$('#wh_topcontainer').append();
|
|
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
|
|
if (hueType == 'philipshue') {
|
|
$('#usrcont').append('<label>' + $.i18n('wiz_hue_username') + '</label><div class="input-group" style="width:250px"><input type="text" class="form-control" id="user"><span class="input-group-addon" id="retry_usr" style="cursor:pointer"><i class="fa fa-refresh"></i></span></div>');
|
|
}
|
|
if (hueType == 'philipshueentertainment') {
|
|
$('#usrcont').append('<label>' + $.i18n('wiz_hue_username') + '</label><div class="input-group" style="width:250px"><input type="text" class="form-control" id="user"></div><label>' + $.i18n('wiz_hue_clientkey') + '</label><div class="input-group" style="width:250px"><input type="text" class="form-control" id="clientkey"><span class="input-group-addon" id="retry_usr" style="cursor:pointer"><i class="fa fa-refresh"></i></span></div><input type="hidden" id="groupId">');
|
|
}
|
|
$('#usrcont').append('<span style="font-weight:bold;color:red" id="wiz_hue_usrstate"></span><br><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>');
|
|
if (hueType == 'philipshueentertainment') {
|
|
$('#wizp2_body').append('<div id="hue_grp_ids_t" style="display:none"><p 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'), $.i18n('wiz_hue_e_use_group')], true));
|
|
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold" id="hue_id_headline">' + $.i18n('wiz_hue_e_desc3') + '</p></div>');
|
|
}
|
|
else {
|
|
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold" id="hue_id_headline">' + $.i18n('wiz_hue_desc2') + '</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>');
|
|
|
|
//open modal
|
|
$("#wizard_modal").modal({
|
|
backdrop: "static",
|
|
keyboard: false,
|
|
show: true
|
|
});
|
|
|
|
//listen for continue
|
|
$('#btn_wiz_cont').off().on('click', function () {
|
|
beginWizardHue();
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
});
|
|
}
|
|
|
|
function checkHueBridge(cb, hueUser) {
|
|
var usr = (typeof hueUser != "undefined") ? hueUser : 'config';
|
|
if (usr == 'config') $('#wiz_hue_discovered').html("");
|
|
$.ajax({
|
|
url: 'http://' + hueIPs[hueIPsinc].internalipaddress + '/api/' + usr,
|
|
type: "GET",
|
|
dataType: "json",
|
|
success: function (json) {
|
|
if (json.config) {
|
|
cb(true, usr);
|
|
} else if (json.name && json.bridgeid && json.modelid) {
|
|
$('#wiz_hue_discovered').html("Bridge: " + json.name + ", Modelid: " + json.modelid + ", API-Version: " + json.apiversion);
|
|
cb(true);
|
|
} else {
|
|
cb(false);
|
|
}
|
|
},
|
|
timeout: 2500
|
|
}).fail(function () {
|
|
cb(false);
|
|
});
|
|
}
|
|
|
|
function checkBridgeResult(reply, usr) {
|
|
if (reply) {
|
|
//abort checking, first reachable result is used
|
|
$('#wiz_hue_ipstate').html("");
|
|
$('#ip').val(hueIPs[hueIPsinc].internalipaddress)
|
|
|
|
//now check hue user on this bridge
|
|
$('#usrcont').toggle(true);
|
|
checkHueBridge(checkUserResult, $('#user').val() ? $('#user').val() : "newdeveloper");
|
|
}
|
|
else {
|
|
//increment and check again
|
|
if (hueIPs.length - 1 > hueIPsinc) {
|
|
hueIPsinc++;
|
|
checkHueBridge(checkBridgeResult);
|
|
}
|
|
else {
|
|
$('#usrcont').toggle(false);
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
|
}
|
|
}
|
|
};
|
|
|
|
function checkUserResult(reply, usr) {
|
|
if (reply) {
|
|
$('#user').val(usr);
|
|
if (hueType == 'philipshueentertainment' && $('#clientkey').val() == "") {
|
|
$('#usrcont').toggle(true);
|
|
$('#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 (hueType == 'philipshue') {
|
|
get_hue_lights();
|
|
}
|
|
if (hueType == 'philipshueentertainment') {
|
|
get_hue_groups();
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$('#wiz_hue_usrstate').html($.i18n('wiz_hue_failure_user'));
|
|
$('#wiz_hue_create_user').toggle(true);
|
|
}
|
|
};
|
|
|
|
function identHueId(id, off, oState) {
|
|
if (off !== true) {
|
|
setTimeout(identHueId, 1500, id, true, oState);
|
|
var put_data = '{"on":true,"bri":254,"hue":47000,"sat":254}';
|
|
}
|
|
else {
|
|
var put_data = '{"on":' + oState.on + ',"bri":' + oState.bri + ',"hue":' + oState.hue + ',"sat":' + oState.sat + '}';
|
|
}
|
|
|
|
$.ajax({
|
|
url: 'http://' + $('#ip').val() + '/api/' + $('#user').val() + '/lights/' + id + '/state',
|
|
type: 'PUT',
|
|
timeout: 2000,
|
|
data: put_data
|
|
})
|
|
}
|
|
|
|
function useGroupId(id) {
|
|
$('#groupId').val(id);
|
|
groupLights = groupIDs[id].lights;
|
|
groupLightsLocations = groupIDs[id].locations;
|
|
get_hue_lights();
|
|
}
|
|
|
|
async function discover_hue_bridges() {
|
|
const res = await requestLedDeviceDiscovery('philipshue');
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info;
|
|
|
|
// Process devices returned by discovery
|
|
console.log(r);
|
|
|
|
if (r.devices.length == 0)
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
|
else {
|
|
for (const device of r.devices) {
|
|
console.log("Device:", device);
|
|
|
|
var ip = device.hostname + ":" + device.port;
|
|
console.log("Host:", ip);
|
|
|
|
hueIPs.push({ internalipaddress: ip });
|
|
}
|
|
var usr = $('#user').val();
|
|
if (usr != "") {
|
|
checkHueBridge(checkUserResult, usr);
|
|
} else {
|
|
checkHueBridge(checkBridgeResult);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function getProperties_hue_bridge(hostAddress, username, resourceFilter) {
|
|
let params = { host: hostAddress, user: username, filter: resourceFilter };
|
|
|
|
const res = await requestLedDeviceProperties('philipshue', params);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process properties returned
|
|
console.log(r);
|
|
}
|
|
}
|
|
|
|
function identify_hue_device(hostAddress, username, id) {
|
|
let params = { host: hostAddress, user: username, lightId: id };
|
|
requestLedDeviceIdentification("philipshue", params);
|
|
}
|
|
|
|
function getHueIPs() {
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_searchb'));
|
|
$.ajax({
|
|
url: 'https://discovery.meethue.com',
|
|
crossDomain: true,
|
|
type: 'GET',
|
|
timeout: 3000
|
|
})
|
|
.done(function (data, textStatus, jqXHR) {
|
|
if (data.length == 0) {
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
|
} else {
|
|
hueIPs = data;
|
|
checkHueBridge(checkBridgeResult);
|
|
}
|
|
})
|
|
.fail(function (jqXHR, textStatus) {
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
|
});
|
|
};
|
|
|
|
//return editor Value
|
|
function eV(vn) {
|
|
return (vn) ? conf_editor.getEditor("root.specificOptions." + vn).getValue() : "";
|
|
}
|
|
|
|
function beginWizardHue() {
|
|
var usr = eV("username");
|
|
if (usr != "") {
|
|
$('#user').val(usr);
|
|
}
|
|
|
|
if (hueType == 'philipshueentertainment') {
|
|
var clkey = eV("clientkey");
|
|
if (clkey != "") {
|
|
$('#clientkey').val(clkey);
|
|
}
|
|
}
|
|
//check if ip is empty/reachable/search for bridge
|
|
if (eV("output") == "") {
|
|
//getHueIPs();
|
|
discover_hue_bridges();
|
|
}
|
|
else {
|
|
var ip = eV("output");
|
|
$('#ip').val(ip);
|
|
hueIPs.unshift({ internalipaddress: ip });
|
|
if (usr != "") {
|
|
checkHueBridge(checkUserResult, usr);
|
|
} else {
|
|
checkHueBridge(checkBridgeResult);
|
|
}
|
|
}
|
|
|
|
$('#retry_bridge').off().on('click', function () {
|
|
if ($('#ip').val() != "") {
|
|
hueIPs.unshift({ internalipaddress: $('#ip').val() })
|
|
hueIPsinc = 0;
|
|
}
|
|
else discover_hue_bridges();
|
|
|
|
var usr = $('#user').val();
|
|
if (usr != "") {
|
|
checkHueBridge(checkUserResult, usr);
|
|
} else {
|
|
checkHueBridge(checkBridgeResult);
|
|
}
|
|
});
|
|
|
|
$('#retry_usr').off().on('click', function () {
|
|
checkHueBridge(checkUserResult, $('#user').val() ? $('#user').val() : "newdeveloper");
|
|
});
|
|
|
|
$('#wiz_hue_create_user').off().on('click', function () {
|
|
if ($('#ip').val() != "") hueIPs.unshift({ internalipaddress: $('#ip').val() });
|
|
createHueUser();
|
|
});
|
|
|
|
$('#btn_wiz_save').off().on("click", function () {
|
|
var hueLedConfig = [];
|
|
var finalLightIds = [];
|
|
|
|
//create hue led config
|
|
for (var key in lightIDs) {
|
|
if (hueType == 'philipshueentertainment') {
|
|
if (groupLights.indexOf(key) == -1) continue;
|
|
}
|
|
if ($('#hue_' + key).val() != "disabled") {
|
|
finalLightIds.push(key);
|
|
var idx_content = assignLightPos(key, $('#hue_' + key).val(), lightIDs[key].name);
|
|
hueLedConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
|
}
|
|
}
|
|
|
|
var sc = window.serverConfig;
|
|
sc.leds = hueLedConfig;
|
|
|
|
//Adjust gamma, brightness and compensation
|
|
var 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
|
|
var d = {};
|
|
d.output = $('#ip').val();
|
|
d.username = $('#user').val();
|
|
d.type = 'philipshue';
|
|
d.colorOrder = 'rgb';
|
|
d.lightIds = finalLightIds;
|
|
d.latchTime = 0;
|
|
d.transitiontime = parseInt(eV("transitiontime"));
|
|
d.restoreOriginalState = (eV("restoreOriginalState") == true);
|
|
d.switchOffOnBlack = (eV("switchOffOnBlack") == true);
|
|
d.brightnessFactor = parseFloat(eV("brightnessFactor"));
|
|
|
|
d.clientkey = $('#clientkey').val();
|
|
d.groupId = parseInt($('#groupId').val());
|
|
d.blackLightsTimeout = parseInt(eV("blackLightsTimeout"));
|
|
d.brightnessMin = parseFloat(eV("brightnessMin"));
|
|
d.brightnessMax = parseFloat(eV("brightnessMax"));
|
|
d.brightnessThreshold = parseFloat(eV("brightnessThreshold"));
|
|
d.sslReadTimeout = parseInt(eV("sslReadTimeout"));
|
|
d.sslHSTimeoutMin = parseInt(eV("sslHSTimeoutMin"));
|
|
d.sslHSTimeoutMax = parseInt(eV("sslHSTimeoutMax"));
|
|
d.verbose = (eV("verbose") == true);
|
|
d.debugStreamer = (eV("debugStreamer") == true);
|
|
d.debugLevel = (eV("debugLevel"));
|
|
|
|
if (hueType == 'philipshue') {
|
|
d.useEntertainmentAPI = false;
|
|
d.hardwareLedCount = finalLightIds.length;
|
|
d.rewriteTime = 0;
|
|
d.verbose = false;
|
|
//smoothing off
|
|
sc.smoothing.enable = false;
|
|
}
|
|
|
|
if (hueType == 'philipshueentertainment') {
|
|
d.useEntertainmentAPI = true;
|
|
d.hardwareLedCount = groupLights.length;
|
|
d.rewriteTime = 20;
|
|
//smoothing on
|
|
sc.smoothing.enable = true;
|
|
}
|
|
|
|
window.serverConfig.device = d;
|
|
|
|
requestWriteConfig(sc, true);
|
|
resetWizard();
|
|
});
|
|
|
|
$('#btn_wiz_abort').off().on('click', resetWizard);
|
|
}
|
|
|
|
function createHueUser() {
|
|
var connectionRetries = 30;
|
|
var data = { "devicetype": "hyperion#" + Date.now() }
|
|
if (hueType == 'philipshueentertainment') {
|
|
data = { "devicetype": "hyperion#" + Date.now(), "generateclientkey": true }
|
|
}
|
|
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) {
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(false);
|
|
$('#wizp3').toggle(true);
|
|
|
|
connectionRetries--;
|
|
$("#connectionTime").html(connectionRetries);
|
|
if (connectionRetries == 0) {
|
|
abortConnection(UserInterval);
|
|
}
|
|
else {
|
|
if (typeof r[0].error != 'undefined') {
|
|
console.log(connectionRetries + ": link not pressed");
|
|
}
|
|
if (typeof r[0].success != 'undefined') {
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
$('#wizp3').toggle(false);
|
|
if (r[0].success.username != 'undefined') {
|
|
$('#user').val(r[0].success.username);
|
|
conf_editor.getEditor("root.specificOptions.username").setValue(r[0].success.username);
|
|
}
|
|
if (hueType == 'philipshueentertainment') {
|
|
if (r[0].success.clientkey != 'undefined') {
|
|
$('#clientkey').val(r[0].success.clientkey);
|
|
conf_editor.getEditor("root.specificOptions.clientkey").setValue(r[0].success.clientkey);
|
|
}
|
|
}
|
|
checkHueBridge(checkUserResult, r[0].success.username);
|
|
clearInterval(UserInterval);
|
|
}
|
|
}
|
|
},
|
|
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
$('#wizp3').toggle(false);
|
|
clearInterval(UserInterval);
|
|
}
|
|
});
|
|
}, 1000);
|
|
}
|
|
|
|
function get_hue_groups() {
|
|
$.ajax({
|
|
type: "GET",
|
|
url: 'http://' + $("#ip").val() + '/api/' + $("#user").val() + '/groups',
|
|
processData: false,
|
|
contentType: 'application/json',
|
|
success: function (r) {
|
|
if (Object.keys(r).length > 0) {
|
|
$('#wh_topcontainer').toggle(false);
|
|
$('#hue_grp_ids_t').toggle(true);
|
|
|
|
groupIDs = r;
|
|
|
|
var gC = 0;
|
|
for (var groupid in r) {
|
|
if (r[groupid].type == 'Entertainment') {
|
|
$('.gidsb').append(createTableRow([groupid + ' (' + r[groupid].name + ')', '<button class="btn btn-sm btn-primary" onClick=useGroupId(' + groupid + ')>' + $.i18n('wiz_hue_e_use_groupid', groupid) + '</button>']));
|
|
gC++;
|
|
}
|
|
}
|
|
if (gC == 0) {
|
|
noAPISupport('wiz_hue_e_noegrpids');
|
|
}
|
|
}
|
|
else {
|
|
noAPISupport('wiz_hue_e_nogrpids');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function noAPISupport(txt) {
|
|
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);
|
|
var txt = (txt) ? $.i18n(txt) : $.i18n('wiz_hue_e_nogrpids');
|
|
$('<p style="font-weight:bold;color:red;">' + txt + '<br />' + $.i18n('wiz_hue_e_noapisupport') + '</p>').insertBefore('#wizp2_body #hue_ids_t');
|
|
$('#hue_id_headline').html($.i18n('wiz_hue_desc2'));
|
|
hueType = 'philipshue';
|
|
get_hue_lights();
|
|
}
|
|
|
|
function get_light_state(id) {
|
|
$.ajax({
|
|
type: "GET",
|
|
url: 'http://' + $("#ip").val() + '/api/' + $("#user").val() + '/lights/' + id,
|
|
processData: false,
|
|
contentType: 'application/json',
|
|
success: function (r) {
|
|
if (Object.keys(r).length > 0) {
|
|
identHueId(id, false, r['state']);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function get_hue_lights() {
|
|
$.ajax({
|
|
type: "GET",
|
|
url: 'http://' + $("#ip").val() + '/api/' + $("#user").val() + '/lights',
|
|
processData: false,
|
|
contentType: 'application/json',
|
|
success: function (r) {
|
|
if (Object.keys(r).length > 0) {
|
|
if (hueType == 'philipshue') {
|
|
$('#wh_topcontainer').toggle(false);
|
|
}
|
|
$('#hue_ids_t, #btn_wiz_save').toggle(true);
|
|
lightIDs = r;
|
|
var lightOptions = [
|
|
"top", "topleft", "topright",
|
|
"bottom", "bottomleft", "bottomright",
|
|
"left", "lefttop", "leftmiddle", "leftbottom",
|
|
"right", "righttop", "rightmiddle", "rightbottom",
|
|
"entire"
|
|
];
|
|
|
|
if (hueType == 'philipshue') {
|
|
lightOptions.unshift("disabled");
|
|
}
|
|
|
|
$('.lidsb').html("");
|
|
var pos = "";
|
|
for (var lightid in r) {
|
|
if (hueType == 'philipshueentertainment') {
|
|
if (groupLights.indexOf(lightid) == -1) continue;
|
|
|
|
if (groupLightsLocations.hasOwnProperty(lightid)) {
|
|
lightLocation = groupLightsLocations[lightid];
|
|
var x = lightLocation[0];
|
|
var y = lightLocation[1];
|
|
var z = lightLocation[2];
|
|
var 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;
|
|
}
|
|
}
|
|
}
|
|
var options = "";
|
|
for (var opt in lightOptions) {
|
|
var val = lightOptions[opt];
|
|
var 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([lightid + ' (' + r[lightid].name + ')', '<select id="hue_' + lightid + '" class="hue_sel_watch form-control">'
|
|
+ options
|
|
+ '</select>', '<button class="btn btn-sm btn-primary" onClick=identify_hue_device("' + $("#ip").val() + '","' + $("#user").val() + '",' + lightid + ')>' + $.i18n('wiz_hue_blinkblue', lightid) + '</button>']));
|
|
}
|
|
|
|
if (hueType != 'philipshueentertainment') {
|
|
$('.hue_sel_watch').bind("change", function () {
|
|
var cC = 0;
|
|
for (var key in lightIDs) {
|
|
if ($('#hue_' + key).val() != "disabled") {
|
|
cC++;
|
|
}
|
|
}
|
|
|
|
(cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').attr("disabled", true) : $('#btn_wiz_save').attr("disabled", false);
|
|
|
|
});
|
|
}
|
|
$('.hue_sel_watch').trigger('change');
|
|
}
|
|
else {
|
|
var 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'));
|
|
}
|
|
|
|
//****************************
|
|
// Wizard WLED
|
|
//****************************
|
|
var lights = null;
|
|
function startWizardWLED(e) {
|
|
//create html
|
|
|
|
var wled_title = 'wiz_wled_title';
|
|
var wled_intro1 = 'wiz_wled_intro1';
|
|
|
|
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(wled_title));
|
|
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(wled_title) + '</h4><p>' + $.i18n(wled_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="hue_ids_t" style="display:none"><p style="font-weight:bold" id="hue_id_headline">'+$.i18n('wiz_wled_desc2')+'</p></div>');
|
|
|
|
createTable("lidsh", "lidsb", "hue_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><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
|
|
*/
|
|
//open modal
|
|
$("#wizard_modal").modal({
|
|
backdrop: "static",
|
|
keyboard: false,
|
|
show: true
|
|
});
|
|
|
|
//listen for continue
|
|
$('#btn_wiz_cont').off().on('click', function () {
|
|
/* For testing only
|
|
|
|
discover_wled();
|
|
|
|
var hostAddress = conf_editor.getEditor("root.specificOptions.host").getValue();
|
|
if(hostAddress != "")
|
|
{
|
|
getProperties_wled(hostAddress,"info");
|
|
identify_wled(hostAddress)
|
|
}
|
|
|
|
For testing only */
|
|
});
|
|
}
|
|
|
|
async function discover_wled() {
|
|
const res = await requestLedDeviceDiscovery('wled');
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process devices returned by discovery
|
|
console.log(r);
|
|
|
|
if (r.devices.length == 0)
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
|
else {
|
|
for (const device of r.devices) {
|
|
console.log("Device:", device);
|
|
|
|
var ip = device.hostname + ":" + device.port;
|
|
console.log("Host:", ip);
|
|
|
|
//wledIPs.push({internalipaddress : ip});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function getProperties_wled(hostAddress, resourceFilter) {
|
|
let params = { host: hostAddress, filter: resourceFilter };
|
|
|
|
const res = await requestLedDeviceProperties('wled', params);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process properties returned
|
|
console.log(r);
|
|
}
|
|
}
|
|
|
|
function identify_wled(hostAddress) {
|
|
let params = { host: hostAddress };
|
|
requestLedDeviceIdentification("wled", params);
|
|
}
|
|
|
|
//****************************
|
|
// Wizard Yeelight
|
|
//****************************
|
|
var lights = null;
|
|
function startWizardYeelight(e) {
|
|
//create html
|
|
|
|
var yeelight_title = 'wiz_yeelight_title';
|
|
var 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>');
|
|
|
|
//open modal
|
|
$("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true });
|
|
|
|
//listen for continue
|
|
$('#btn_wiz_cont').off().on('click', function () {
|
|
beginWizardYeelight();
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
});
|
|
}
|
|
|
|
function beginWizardYeelight() {
|
|
lights = [];
|
|
configuredLights = conf_editor.getEditor("root.specificOptions.lights").getValue();
|
|
|
|
discover_yeelight_lights();
|
|
|
|
$('#btn_wiz_save').off().on("click", function () {
|
|
var yeelightLedConfig = [];
|
|
var finalLights = [];
|
|
|
|
//create yeelight led config
|
|
for (var key in lights) {
|
|
if ($('#yee_' + key).val() !== "disabled") {
|
|
//delete lights[key].model;
|
|
|
|
// Set Name to layout-position, if empty
|
|
if (lights[key].name === "") {
|
|
lights[key].name = $.i18n('conf_leds_layout_cl_' + $('#yee_' + key).val());
|
|
}
|
|
|
|
finalLights.push(lights[key]);
|
|
|
|
var name = lights[key].host;
|
|
if (lights[key].name !== "")
|
|
name += '_' + lights[key].name;
|
|
|
|
var idx_content = assignLightPos(key, $('#yee_' + key).val(), name);
|
|
yeelightLedConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
|
}
|
|
}
|
|
|
|
//LED layout
|
|
window.serverConfig.leds = yeelightLedConfig;
|
|
|
|
//LED device config
|
|
//Start with a clean configuration
|
|
var 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;
|
|
|
|
//smoothing off
|
|
window.serverConfig.smoothing.enable = false;
|
|
|
|
requestWriteConfig(window.serverConfig, true);
|
|
resetWizard();
|
|
});
|
|
|
|
$('#btn_wiz_abort').off().on('click', resetWizard);
|
|
}
|
|
|
|
async function discover_yeelight_lights() {
|
|
var light = {};
|
|
// Get discovered lights
|
|
const res = await requestLedDeviceDiscovery('yeelight');
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info;
|
|
|
|
// Process devices returned by discovery
|
|
for (const device of r.devices) {
|
|
//console.log("Device:", device);
|
|
|
|
if (device.hostname !== "") {
|
|
if (getHostInLights(device.hostname).length === 0) {
|
|
var light = {};
|
|
light.host = device.hostname;
|
|
light.port = device.port;
|
|
light.name = device.other.name;
|
|
light.model = device.other.model;
|
|
lights.push(light);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add additional items from configuration
|
|
for (var keyConfig in configuredLights) {
|
|
var [host, port] = configuredLights[keyConfig].host.split(":", 2);
|
|
|
|
//In case port has been explicitly provided, overwrite port given as part of hostname
|
|
if (configuredLights[keyConfig].port !== 0)
|
|
port = configuredLights[keyConfig].port;
|
|
|
|
if (host !== "")
|
|
if (getHostInLights(host).length === 0) {
|
|
var light = {};
|
|
light.host = host;
|
|
light.port = port;
|
|
light.name = configuredLights[keyConfig].name;
|
|
light.model = "color4";
|
|
lights.push(light);
|
|
}
|
|
}
|
|
|
|
assign_yeelight_lights();
|
|
}
|
|
}
|
|
|
|
function assign_yeelight_lights() {
|
|
var models = ['color', 'color1', 'color2', 'color4', 'stripe', 'strip1'];
|
|
|
|
// If records are left for configuration
|
|
if (Object.keys(lights).length > 0) {
|
|
$('#wh_topcontainer').toggle(false);
|
|
$('#yee_ids_t, #btn_wiz_save').toggle(true);
|
|
|
|
var lightOptions = [
|
|
"top", "topleft", "topright",
|
|
"bottom", "bottomleft", "bottomright",
|
|
"left", "lefttop", "leftmiddle", "leftbottom",
|
|
"right", "righttop", "rightmiddle", "rightbottom",
|
|
"entire"
|
|
];
|
|
|
|
lightOptions.unshift("disabled");
|
|
|
|
$('.lidsb').html("");
|
|
var pos = "";
|
|
|
|
for (var lightid in lights) {
|
|
var lightHostname = lights[lightid].host;
|
|
var lightPort = lights[lightid].port;
|
|
var lightName = lights[lightid].name;
|
|
|
|
if (lightName === "")
|
|
lightName = $.i18n('edt_dev_spec_lights_itemtitle');
|
|
|
|
var options = "";
|
|
for (var opt in lightOptions) {
|
|
var val = lightOptions[opt];
|
|
var 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>';
|
|
}
|
|
|
|
var enabled = 'enabled';
|
|
if (!models.includes(lights[lightid].model)) {
|
|
var enabled = 'disabled';
|
|
options = '<option value=disabled>' + $.i18n('wiz_yeelight_unsupported') + '</option>';
|
|
}
|
|
|
|
$('.lidsb').append(createTableRow([(parseInt(lightid, 10) + 1) + '. ' + lightName + '<br>(' + lightHostname + ')', '<select id="yee_' + lightid + '" ' + enabled + ' class="yee_sel_watch form-control">'
|
|
+ options
|
|
+ '</select>', '<button class="btn btn-sm btn-primary" onClick=identify_yeelight_device("' + lightHostname + '",' + lightPort + ')>'
|
|
+ $.i18n('wiz_identify_light', lightName) + '</button>']));
|
|
}
|
|
|
|
$('.yee_sel_watch').bind("change", function () {
|
|
var cC = 0;
|
|
for (var key in lights) {
|
|
if ($('#yee_' + key).val() !== "disabled") {
|
|
cC++;
|
|
}
|
|
}
|
|
|
|
if (cC === 0 || window.readOnlyMode)
|
|
$('#btn_wiz_save').attr("disabled", true);
|
|
else
|
|
$('#btn_wiz_save').attr("disabled", false);
|
|
});
|
|
$('.yee_sel_watch').trigger('change');
|
|
}
|
|
else {
|
|
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','Yeelights') + '</p>';
|
|
$('#wizp2_body').append(noLightsTxt);
|
|
}
|
|
}
|
|
|
|
async function getProperties_yeelight(hostname, port) {
|
|
let params = { hostname: hostname, port: port };
|
|
|
|
const res = await requestLedDeviceProperties('yeelight', params);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process properties returned
|
|
console.log(r);
|
|
}
|
|
}
|
|
|
|
function identify_yeelight_device(hostname, port) {
|
|
let params = { hostname: hostname, port: port };
|
|
requestLedDeviceIdentification("yeelight", params);
|
|
}
|
|
|
|
//****************************
|
|
// Wizard AtmoOrb
|
|
//****************************
|
|
var lights = null;
|
|
function startWizardAtmoOrb(e) {
|
|
//create html
|
|
|
|
var atmoorb_title = 'wiz_atmoorb_title';
|
|
var 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>');
|
|
|
|
//open modal
|
|
$("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true });
|
|
|
|
//listen for continue
|
|
$('#btn_wiz_cont').off().on('click', function () {
|
|
beginWizardAtmoOrb();
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
});
|
|
}
|
|
|
|
function beginWizardAtmoOrb() {
|
|
lights = [];
|
|
configuredLights = [];
|
|
|
|
var configruedOrbIds = conf_editor.getEditor("root.specificOptions.orbIds").getValue().trim();
|
|
if (configruedOrbIds.length !== 0) {
|
|
configuredLights = configruedOrbIds.split(",").map(Number);
|
|
}
|
|
|
|
var multiCastGroup = conf_editor.getEditor("root.specificOptions.output").getValue();
|
|
var multiCastPort = parseInt(conf_editor.getEditor("root.specificOptions.port").getValue());
|
|
|
|
discover_atmoorb_lights(multiCastGroup, multiCastPort);
|
|
|
|
$('#btn_wiz_save').off().on("click", function () {
|
|
var atmoorbLedConfig = [];
|
|
var finalLights = [];
|
|
|
|
//create atmoorb led config
|
|
for (var 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);
|
|
|
|
var name = lights[key].id;
|
|
if (lights[key].host !== "")
|
|
name += ':' + lights[key].host;
|
|
|
|
var idx_content = assignLightPos(key, $('#orb_' + key).val(), name);
|
|
atmoorbLedConfig.push(JSON.parse(JSON.stringify(idx_content)));
|
|
}
|
|
}
|
|
|
|
//LED layout
|
|
window.serverConfig.leds = atmoorbLedConfig;
|
|
|
|
//LED device config
|
|
//Start with a clean configuration
|
|
var d = {};
|
|
|
|
d.type = 'atmoorb';
|
|
d.hardwareLedCount = finalLights.length;
|
|
d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue();
|
|
|
|
d.orbIds = finalLights.toString();
|
|
d.useOrbSmoothing = (eV("useOrbSmoothing") == true);
|
|
|
|
d.output = conf_editor.getEditor("root.specificOptions.output").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_atmoorb_lights(multiCastGroup, multiCastPort) {
|
|
var light = {};
|
|
|
|
var params = {};
|
|
if (multiCastGroup !== "")
|
|
{
|
|
params.multiCastGroup = multiCastGroup;
|
|
}
|
|
|
|
if (multiCastPort !== 0)
|
|
{
|
|
params.multiCastPort = multiCastPort;
|
|
}
|
|
|
|
// Get discovered lights
|
|
const res = await requestLedDeviceDiscovery('atmoorb', params);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info;
|
|
|
|
// Process devices returned by discovery
|
|
for (const device of r.devices) {
|
|
if (device.id !== "") {
|
|
if (getIdInLights(device.id).length === 0) {
|
|
var light = {};
|
|
light.id = device.id;
|
|
light.ip = device.ip;
|
|
light.host = device.hostname;
|
|
lights.push(light);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add additional items from configuration
|
|
for (const keyConfig in configuredLights) {
|
|
if (configuredLights[keyConfig] !== "" && !isNaN(configuredLights[keyConfig])) {
|
|
if (getIdInLights(configuredLights[keyConfig]).length === 0) {
|
|
var light = {};
|
|
light.id = configuredLights[keyConfig];
|
|
light.ip = "";
|
|
light.host = "";
|
|
lights.push(light);
|
|
}
|
|
}
|
|
}
|
|
|
|
lights.sort((a, b) => (a.id > b.id) ? 1 : -1);
|
|
|
|
assign_atmoorb_lights();
|
|
}
|
|
}
|
|
|
|
function assign_atmoorb_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);
|
|
|
|
var lightOptions = [
|
|
"top", "topleft", "topright",
|
|
"bottom", "bottomleft", "bottomright",
|
|
"left", "lefttop", "leftmiddle", "leftbottom",
|
|
"right", "righttop", "rightmiddle", "rightbottom",
|
|
"entire"
|
|
];
|
|
|
|
lightOptions.unshift("disabled");
|
|
|
|
$('.lidsb').html("");
|
|
var pos = "";
|
|
|
|
for (var lightid in lights) {
|
|
var orbId = lights[lightid].id;
|
|
var orbIp = lights[lightid].ip;
|
|
var orbHostname = lights[lightid].host;
|
|
|
|
if (orbHostname === "")
|
|
orbHostname = $.i18n('edt_dev_spec_lights_itemtitle');
|
|
|
|
var options = "";
|
|
for (var opt in lightOptions) {
|
|
var val = lightOptions[opt];
|
|
var 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>';
|
|
}
|
|
|
|
var enabled = 'enabled';
|
|
if (orbId < 1 || orbId > 255) {
|
|
enabled = 'disabled';
|
|
options = '<option value=disabled>' + $.i18n('wiz_atmoorb_unsupported') + '</option>';
|
|
}
|
|
|
|
var 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" ' + enabled + ' onClick=identify_atmoorb_device(' + orbId + ')>'
|
|
+ $.i18n('wiz_identify_light', orbId) + '</button>']));
|
|
}
|
|
|
|
$('.orb_sel_watch').bind("change", function () {
|
|
var cC = 0;
|
|
for (var key in lights) {
|
|
if ($('#orb_' + key).val() !== "disabled") {
|
|
cC++;
|
|
}
|
|
}
|
|
if (cC === 0 || window.readOnlyMode)
|
|
$('#btn_wiz_save').attr("disabled", true);
|
|
else
|
|
$('#btn_wiz_save').attr("disabled", false);
|
|
});
|
|
$('.orb_sel_watch').trigger('change');
|
|
}
|
|
else {
|
|
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','AtmoOrbs') + '</p>';
|
|
$('#wizp2_body').append(noLightsTxt);
|
|
}
|
|
}
|
|
|
|
function identify_atmoorb_device(orbId) {
|
|
let params = { id: orbId };
|
|
requestLedDeviceIdentification("atmoorb", params);
|
|
}
|
|
|
|
//****************************
|
|
// Wizard/Routines Nanoleaf
|
|
//****************************
|
|
async function discover_nanoleaf() {
|
|
const res = await requestLedDeviceDiscovery('nanoleaf');
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process devices returned by discovery
|
|
console.log(r);
|
|
|
|
if (r.devices.length == 0)
|
|
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
|
else {
|
|
for (const device of r.devices) {
|
|
console.log("Device:", device);
|
|
|
|
var ip = device.hostname + ":" + device.port;
|
|
console.log("Host:", ip);
|
|
|
|
//nanoleafIPs.push({internalipaddress : ip});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function getProperties_nanoleaf(hostAddress, authToken, resourceFilter) {
|
|
let params = { host: hostAddress, token: authToken, filter: resourceFilter };
|
|
|
|
const res = await requestLedDeviceProperties('nanoleaf', params);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process properties returned
|
|
console.log(r);
|
|
}
|
|
}
|
|
|
|
function identify_nanoleaf(hostAddress, authToken) {
|
|
let params = { host: hostAddress, token: authToken };
|
|
requestLedDeviceIdentification("nanoleaf", params);
|
|
}
|
|
|
|
//****************************
|
|
// Wizard Cololight
|
|
//****************************
|
|
var lights = null;
|
|
var selectedLightId = null;
|
|
|
|
function startWizardCololight(e) {
|
|
//create html
|
|
|
|
var cololight_title = 'wiz_cololight_title';
|
|
var cololight_intro1 = 'wiz_cololight_intro1';
|
|
|
|
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(cololight_title));
|
|
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(cololight_title) + '</h4><p>' + $.i18n(cololight_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="colo_ids_t" style="display:none"><p style="font-weight:bold" id="colo_id_headline">' + $.i18n('wiz_cololight_desc2') + '</p></div>');
|
|
|
|
createTable("lidsh", "lidsb", "colo_ids_t");
|
|
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'), $.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>');
|
|
|
|
//open modal
|
|
$("#wizard_modal").modal({
|
|
backdrop: "static",
|
|
keyboard: false,
|
|
show: true
|
|
});
|
|
|
|
//listen for continue
|
|
$('#btn_wiz_cont').off().on('click', function () {
|
|
beginWizardCololight();
|
|
$('#wizp1').toggle(false);
|
|
$('#wizp2').toggle(true);
|
|
});
|
|
}
|
|
|
|
function beginWizardCololight() {
|
|
lights = [];
|
|
|
|
discover_cololights();
|
|
|
|
$('#btn_wiz_save').off().on("click", function () {
|
|
//LED device config
|
|
//Start with a clean configuration
|
|
var d = {};
|
|
|
|
d.type = 'cololight';
|
|
|
|
//Cololight does not resolve into stable hostnames (as devices named the same), therefore use IP
|
|
if (!lights[selectedLightId].ip) {
|
|
d.host = lights[selectedLightId].host;
|
|
} else {
|
|
d.host = lights[selectedLightId].ip;
|
|
}
|
|
|
|
var coloLightProperties = lights[selectedLightId].props;
|
|
if (Object.keys(coloLightProperties).length === 0) {
|
|
alert($.i18n('wiz_cololight_noprops'));
|
|
d.hardwareLedCount = 1;
|
|
} else {
|
|
if (coloLightProperties.ledCount > 0) {
|
|
d.hardwareLedCount = coloLightProperties.ledCount;
|
|
} else if (coloLightProperties.modelType === "Strip")
|
|
d.hardwareLedCount = 120;
|
|
}
|
|
|
|
d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue();
|
|
d.latchTime = parseInt(conf_editor.getEditor("root.specificOptions.latchTime").getValue());;
|
|
|
|
window.serverConfig.device = d;
|
|
|
|
//LED layout - have initial layout prepared matching the LED-count
|
|
|
|
var coloLightLedConfig = [];
|
|
|
|
if (coloLightProperties.modelType === "Strip") {
|
|
coloLightLedConfig = createClassicLedLayoutSimple(d.hardwareLedCount / 2, d.hardwareLedCount / 4, d.hardwareLedCount / 4, 0, d.hardwareLedCount / 4 * 3, false);
|
|
} else {
|
|
coloLightLedConfig = createClassicLedLayoutSimple(0, 0, 0, d.hardwareLedCount, 0, true);
|
|
}
|
|
|
|
window.serverConfig.leds = coloLightLedConfig;
|
|
|
|
//smoothing off
|
|
window.serverConfig.smoothing.enable = false;
|
|
|
|
requestWriteConfig(window.serverConfig, true);
|
|
|
|
resetWizard();
|
|
});
|
|
|
|
$('#btn_wiz_abort').off().on('click', resetWizard);
|
|
}
|
|
|
|
async function discover_cololights() {
|
|
const res = await requestLedDeviceDiscovery('cololight');
|
|
|
|
if (res && !res.error) {
|
|
const r = res.info;
|
|
|
|
// Process devices returned by discovery
|
|
for (const device of r.devices) {
|
|
if (device.ip !== "") {
|
|
if (getIpInLights(device.ip).length === 0) {
|
|
var light = {};
|
|
light.ip = device.ip;
|
|
light.host = device.hostname;
|
|
light.name = device.name;
|
|
light.type = device.type;
|
|
lights.push(light);
|
|
}
|
|
}
|
|
}
|
|
assign_cololight_lights();
|
|
}
|
|
}
|
|
|
|
function assign_cololight_lights() {
|
|
// If records are left for configuration
|
|
if (Object.keys(lights).length > 0) {
|
|
$('#wh_topcontainer').toggle(false);
|
|
$('#colo_ids_t, #btn_wiz_save').toggle(true);
|
|
|
|
$('.lidsb').html("");
|
|
|
|
var options = "";
|
|
|
|
for (var lightid in lights) {
|
|
lights[lightid].id = lightid;
|
|
|
|
var lightHostname = lights[lightid].host;
|
|
var lightIP = lights[lightid].ip;
|
|
|
|
var val = lightHostname + " (" + lightIP + ")";
|
|
options += '<option value="' + lightid + '">' + val + '</option>';
|
|
}
|
|
|
|
var enabled = 'enabled';
|
|
|
|
$('.lidsb').append(createTableRow(['<select id="colo_select_id" ' + enabled + ' class="colo_sel_watch form-control">'
|
|
+ options
|
|
+ '</select>', '<button id="wiz_identify_btn" class="btn btn-sm btn-primary">'
|
|
+ $.i18n('wiz_identify') + '</button>']));
|
|
|
|
$('.colo_sel_watch').bind("change", function () {
|
|
selectedLightId = $('#colo_select_id').val();
|
|
var lightIP = lights[selectedLightId].ip;
|
|
|
|
$('#wiz_identify_btn').unbind().bind('click', function (event) { identify_cololight_device(lightIP); });
|
|
|
|
if (!lights[selectedLightId].props) {
|
|
getProperties_cololight(lightIP);
|
|
}
|
|
});
|
|
$('.colo_sel_watch').trigger('change');
|
|
}
|
|
else {
|
|
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','Cololights') + '</p>';
|
|
$('#wizp2_body').append(noLightsTxt);
|
|
}
|
|
}
|
|
|
|
async function getProperties_cololight(ip) {
|
|
let params = { host: ip };
|
|
|
|
const res = await requestLedDeviceProperties('cololight', params);
|
|
|
|
if (res && !res.error) {
|
|
var coloLightProperties = res.info;
|
|
|
|
//Store properties along light with given IP-address
|
|
var id = getIpInLights(ip)[0].id;
|
|
lights[id].props = coloLightProperties;
|
|
}
|
|
}
|
|
|
|
function identify_cololight_device(hostAddress) {
|
|
let params = { host: hostAddress };
|
|
requestLedDeviceIdentification("cololight", params);
|
|
}
|
|
|
|
//****************************
|
|
// Wizard/Routines RS232-Devices
|
|
//****************************
|
|
async function discover_providerRs232(rs232Type) {
|
|
const res = await requestLedDeviceDiscovery(rs232Type);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process serialPorts returned by discover
|
|
console.log(r);
|
|
}
|
|
}
|
|
|
|
//****************************
|
|
// Wizard/Routines HID (USB)-Devices
|
|
//****************************
|
|
async function discover_providerHid(hidType) {
|
|
const res = await requestLedDeviceDiscovery(hidType);
|
|
|
|
// TODO: error case unhandled
|
|
// res can be: false (timeout) or res.error (not found)
|
|
if (res && !res.error) {
|
|
const r = res.info
|
|
|
|
// Process HID returned by discover
|
|
console.log(r);
|
|
}
|
|
}
|