//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); } } async function identify_hue_device(hostAddress, username, id) { // Take care that new record cannot be save during background process $('#btn_wiz_save').attr('disabled', true); let params = { host: hostAddress, user: username, lightId: id }; const res = await requestLedDeviceIdentification('philipshue', params); if (!window.readOnlyMode) { $('#btn_wiz_save').attr('disabled', false); } } 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); } } async function identify_wled(hostAddress) { // Take care that new record cannot be save during background process $('#btn_wiz_save').attr('disabled', true); let params = { host: hostAddress }; const res = await requestLedDeviceIdentification('wled', params); if (!window.readOnlyMode) { $('#btn_wiz_save').attr('disabled', false); } } //**************************** // 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); } } async function identify_yeelight_device(hostname, port) { // Take care that new record cannot be save during background process $('#btn_wiz_save').attr('disabled', true); let params = { hostname: hostname, port: port }; const res = await requestLedDeviceIdentification("yeelight", params); if (!window.readOnlyMode) { $('#btn_wiz_save').attr('disabled', false); } } //**************************** // 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); } } async function identify_atmoorb_device(orbId) { // Take care that new record cannot be save during background process $('#btn_wiz_save').attr('disabled', true); let params = { id: orbId }; const res = await requestLedDeviceIdentification("atmoorb", params); if (!window.readOnlyMode) { $('#btn_wiz_save').attr('disabled', false); } } //**************************** // 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); } } async function identify_nanoleaf(hostAddress, authToken) { // Take care that new record cannot be save during background process $('#btn_wiz_save').attr('disabled', true); let params = { host: hostAddress, token: authToken }; const res = await requestLedDeviceIdentification('nanoleaf', params); if (!window.readOnlyMode) { $('#btn_wiz_save').attr('disabled', false); } } //**************************** // 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.properties; if (Object.keys(coloLightProperties).length === 0) { alert($.i18n('wiz_cololight_noprops')); d.hardwareLedCount = 1; } else { d.hardwareLedCount = coloLightProperties.ledCount; } 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; } } async function identify_cololight_device(hostAddress) { // Take care that new record cannot be save during background process $('#btn_wiz_save').attr('disabled', true); let params = { host: hostAddress }; const res = await requestLedDeviceIdentification('cololight', params); if (!window.readOnlyMode) { $('#btn_wiz_save').attr('disabled', false); } } //**************************** // 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); } }