//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"); if (getStorage("kodiPort") != null) { kodiPort = getStorage("kodiPort"); } 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('' + $.i18n('wiz_rgb_title')); $('#wizp1_body').html('

' + $.i18n('wiz_rgb_title') + '

' + $.i18n('wiz_rgb_intro1') + '

' + $.i18n('wiz_rgb_intro2') + '

'); $('#wizp1_footer').html(''); $('#wizp2_body').html('

' + $.i18n('wiz_rgb_expl') + '

'); $('#wizp2_body').append('
' + $.i18n('edt_append_s') + '
'); $('#wizp2_body').append(''); $('#wizp2_body').append('
'); $('#wizp2_footer').html(''); if (getStorage("darkMode") == "on") $('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png'); //open modal $("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true }); //listen for continue $('#btn_wiz_cont').off().on('click', function () { beginWizardRGB(); $('#wizp1').toggle(false); $('#wizp2').toggle(true); }); } function beginWizardRGB() { $("#wiz_switchtime_select").off().on('change', function () { clearInterval(wIntveralId); var time = $("#wiz_switchtime_select").val(); wIntveralId = setInterval(function () { changeColor(); }, time * 1000); }); $('.wselect').on("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] + ']').prop('disabled', true); else $('#wiz_g_select option[value=' + rgb_order[i] + ']').prop('disabled', false); if (greenS == rgb_order[i]) $('#wiz_r_select option[value=' + rgb_order[i] + ']').prop('disabled', true); else $('#wiz_r_select option[value=' + rgb_order[i] + ']').prop('disabled', false); } if (redS != 'null' && greenS != 'null') { $('#btn_wiz_save').prop('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').prop('disabled', true) : $('#btn_wiz_checkok').prop('disabled', false); } else { $('#btn_wiz_save').toggle(true); window.readOnlyMode ? $('#btn_wiz_save').prop('disabled', true) : $('#btn_wiz_save').prop('disabled', false); $('#btn_wiz_checkok').toggle(false); } new_rgb_order = rgb_order; } else $('#btn_wiz_save').prop('disabled', true); }); $("#wiz_switchtime_select").append(createSelOpt('5', '5'), createSelOpt('10', '10'), createSelOpt('15', '15'), createSelOpt('30', '30')); $("#wiz_switchtime_select").trigger('change'); $("#wiz_r_select").append(createSelOpt("null", ""), createSelOpt('r', $.i18n('general_col_red')), createSelOpt('g', $.i18n('general_col_green')), createSelOpt('b', $.i18n('general_col_blue'))); $("#wiz_g_select").html($("#wiz_r_select").html()); $("#wiz_r_select").trigger('change'); requestSetColor('255', '0', '0'); setTimeout(requestSetSource, 100, 'auto'); setStorage("wizardactive", true); $('#btn_wiz_abort').off().on('click', function () { 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 const defaultKodiPort = 9090; var kodiAddress = document.location.hostname; var kodiPort = defaultKodiPort; var kodiUrl = new URL("ws://" + kodiAddress); kodiUrl.port = kodiPort; kodiUrl.pathname = "/jsonrpc/websocket"; 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"); kodiUrl.host = kodiAddress; } if (getStorage("kodiPort") != null) { kodiPort = getStorage("kodiPort"); kodiUrl.port = kodiPort; } 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) { if (kodiUrl.port === '') { kodiUrl.port = defaultKodiPort; } var ws = new WebSocket(kodiUrl); ws.onopen = function () { ws.send(JSON.stringify(command)); }; ws.onmessage = function (evt) { var response = JSON.parse(evt.data); if (response.method === "System.OnQuit") { ws.close(); } else { if (cb != undefined) { if (response.result != undefined) { if (response.result === "OK") { cb("success"); ws.close(); } else { cb("error"); ws.close(); } } } } }; ws.onerror = function (evt) { if (cb != undefined) { cb("error"); ws.close(); } }; ws.onclose = function (evt) { }; } 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').prop("disabled", true); } else $('#btn_wiz_back').prop("disabled", false); if (step == 2) { updateWEditor(["white"]); h = $.i18n('wiz_cc_adjustit', $.i18n('edt_conf_color_white_title')); if (withKodi) { h += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_white_title')); sendToKodi('playP', "white"); } else h += '
' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_white_title')); $('#wiz_cc_desc').html(h); } if (step == 3) { updateWEditor(["gammaRed", "gammaGreen", "gammaBlue"]); h = '

' + $.i18n('wiz_cc_adjustgamma') + '

'; if (withKodi) { sendToKodi('playP', "HGradient"); h += ''; } else h += '

' + $.i18n('wiz_cc_lettvshowm', "grey_1, grey_2, grey_3, HGradient, VGradient") + '

'; $('#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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_red_title')); sendToKodi('playP', "red"); } else h += '
' + $.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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_green_title')); sendToKodi('playP', "green"); } else h += '
' + $.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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_blue_title')); sendToKodi('playP', "blue"); } else h += '
' + $.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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_cyan_title')); sendToKodi('playP', "cyan"); } else h += '
' + $.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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_magenta_title')); sendToKodi('playP', "magenta"); } else h += '
' + $.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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_yellow_title')); sendToKodi('playP', "yellow"); } else h += '
' + $.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 += '
' + $.i18n('wiz_cc_kodishould', $.i18n('edt_conf_color_black_title')); sendToKodi('playP', "black"); } else h += '
' + $.i18n('wiz_cc_lettvshow', $.i18n('edt_conf_color_black_title')); $('#wiz_cc_desc').html(h); } if (step == 11) { updateWEditor([""], true); h = '

' + $.i18n('wiz_cc_testintro') + '

'; if (withKodi) { h += '

' + $.i18n('wiz_cc_testintrok') + '

'; sendToKodi('stop'); for (var i = 0; i < availVideos.length; i++) { var txt = availVideos[i].replace(/_/g, " "); h += '
'; } h += '
'; } else h += '

' + $.i18n('wiz_cc_testintrowok') + ' ' + $.i18n('wiz_cc_link') + '

'; h += '

' + $.i18n('wiz_cc_summary') + '

'; $('#wiz_cc_desc').html(h); $('.videobtn').off().on('click', function (e) { if (e.target.id == "stop") sendToKodi("stop"); else sendToKodi("playV", e.target.id + '.mp4'); $(this).prop("disabled", true); setTimeout(function () { $('.videobtn').prop("disabled", false) }, 10000); }); $('#btn_wiz_next').prop("disabled", true); $('#btn_wiz_save').toggle(true); window.readOnlyMode ? $('#btn_wiz_save').prop('disabled', true) : $('#btn_wiz_save').prop('disabled', false); } else { $('#btn_wiz_next').prop("disabled", false); $('#btn_wiz_save').toggle(false); } } function 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() { //create html $('#wiz_header').html('' + $.i18n('wiz_cc_title')); $('#wizp1_body').html('

' + $.i18n('wiz_cc_title') + '

' + '

' + $.i18n('wiz_cc_intro1') + '

' + '' + '' + '' ); $('#wizp1_footer').html('' + '' ); $('#wizp2_body').html('
' ); $('#wizp2_footer').html('' + '' + '' + '' ); if (getStorage("darkMode") == "on") $('#wizard_logo').prop("src", 'img/hyperion/logo_negativ.png'); //open modal $("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true }); $('#wiz_cc_kodiip').off().on('change', function () { kodiAddress = encodeURIComponent($(this).val().trim()); $('#kodi_status').html(''); if (kodiAddress !== "") { if (!isValidHostnameOrIP(kodiAddress)) { $('#kodi_status').html('

' + $.i18n('edt_msgcust_error_hostname_ip') + '

'); withKodi = false; } else { if (isValidIPv6(kodiAddress)) { kodiUrl.hostname = "[" + kodiAddress + "]"; } else { kodiUrl.hostname = kodiAddress; } $('#kodi_status').html('

' + $.i18n('wiz_cc_try_connect') + '

'); $('#btn_wiz_cont').prop('disabled', true); sendToKodi("msg", $.i18n('wiz_cc_kodimsg_start'), function (cb) { if (cb == "error") { $('#kodi_status').html('

' + $.i18n('wiz_cc_kodidiscon') + '

' + $.i18n('wiz_cc_kodidisconlink') + ' ' + $.i18n('wiz_cc_link') + '

'); withKodi = false; } else { setStorage("kodiAddress", kodiAddress); setStorage("kodiPort", defaultKodiPort); $('#kodi_status').html('

' + $.i18n('wiz_cc_kodicon') + '

'); withKodi = true; } $('#btn_wiz_cont').prop('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('

' + $.i18n('wiz_cc_morethanone') + '

'); 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 }; var lightPosBottomLeft14 = { hmin: 0, hmax: 0.25, vmin: 0.85, vmax: 1.0 }; var lightPosBottomLeft12 = { hmin: 0.25, hmax: 0.5, vmin: 0.85, vmax: 1.0 }; var lightPosBottomLeft34 = { hmin: 0.5, hmax: 0.75, vmin: 0.85, vmax: 1.0 }; var lightPosBottomLeft11 = { hmin: 0.75, hmax: 1, vmin: 0.85, vmax: 1.0 }; var lightPosBottomLeft112 = { hmin: 0, hmax: 0.5, vmin: 0.85, vmax: 1.0 }; var lightPosBottomLeft121 = { hmin: 0.5, hmax: 1, vmin: 0.85, vmax: 1.0 }; var lightPosBottomLeftNewMid = { hmin: 0.25, hmax: 0.75, vmin: 0.85, vmax: 1.0 }; var lightPosTopLeft112 = { hmin: 0, hmax: 0.5, vmin: 0, vmax: 0.15 }; var lightPosTopLeft121 = { hmin: 0.5, hmax: 1, vmin: 0, vmax: 0.15 }; var lightPosTopLeftNewMid = { hmin: 0.25, hmax: 0.75, vmin: 0, vmax: 0.15 }; function assignLightPos(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 if (pos === "lightPosBottomLeft14") i = lightPosBottomLeft14; else if (pos === "lightPosBottomLeft12") i = lightPosBottomLeft12; else if (pos === "lightPosBottomLeft34") i = lightPosBottomLeft34; else if (pos === "lightPosBottomLeft11") i = lightPosBottomLeft11; else if (pos === "lightPosBottomLeft112") i = lightPosBottomLeft112; else if (pos === "lightPosBottomLeft121") i = lightPosBottomLeft121; else if (pos === "lightPosBottomLeftNewMid") i = lightPosBottomLeftNewMid; else if (pos === "lightPosTopLeft112") i = lightPosTopLeft112; else if (pos === "lightPosTopLeft121") i = lightPosTopLeft121; else if (pos === "lightPosTopLeftNewMid") i = lightPosTopLeftNewMid; 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 } ); } // External properties properties, 2-dimensional arry of [ledType][key] devicesProperties = {}; //**************************** // Wizard Philips Hue //**************************** var hueIPs = []; var hueIPsinc = 0; var hueLights = []; var hueEntertainmentConfigs = []; var hueEntertainmentServices = []; var lightLocation = []; var groupLights = []; var groupChannels = []; var groupLightsLocations = []; var isAPIv2Ready = true; var isEntertainmentReady = true; function startWizardPhilipsHue(e) { //create html var hue_title = 'wiz_hue_title'; var hue_intro1 = 'wiz_hue_e_intro1'; var hue_desc1 = 'wiz_hue_desc1'; var hue_create_user = 'wiz_hue_create_user'; $('#wiz_header').html('' + $.i18n(hue_title)); $('#wizp1_body').html('

' + $.i18n(hue_title) + '

' + $.i18n(hue_intro1) + '

'); $('#wizp1_footer').html(''); $('#wizp2_body').html('
'); var topContainer_html = '

' + $.i18n(hue_desc1) + '

' + '
' + '
' + '

' + $.i18n('wiz_hue_ip') + '

' + '
' + ' ' + ' ' + '
' + '
' + ' ' + '
'; if (storedAccess === 'expert') { topContainer_html += '
' + ':' + '
'; } topContainer_html += '

'; topContainer_html += ''; $('#wh_topcontainer').append(topContainer_html); $('#usrcont').append('

' + $.i18n('wiz_hue_username') + '

' + '
' + '
' + ' ' + ' ' + '

' + '' ); $('#usrcont').append('

' + $.i18n('wiz_hue_clientkey') + '


'); $('#usrcont').append('

<\p>' + ''); $('#wizp2_body').append('

'); createTable("gidsh", "gidsb", "hue_grp_ids_t"); $('.gidsh').append(createTableRow([$.i18n('edt_dev_spec_groupId_title'), ""], true)); $('#wizp2_body').append(''); 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(''); $('#wizp3_body').html('' + $.i18n('wiz_hue_press_link') + '


'); if (getStorage("darkMode") == "on") $('#wizard_logo').attr("src", 'img/hyperion/logo_negativ.png'); //open modal $("#wizard_modal").modal({ backdrop: "static", keyboard: false, show: true }); //listen for continue $('#btn_wiz_cont').off().on('click', function () { 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(""); } if (hueIPs[hueIPsinc]) { var host = hueIPs[hueIPsinc].host; var port = hueIPs[hueIPsinc].port; if (usr != '') { getProperties_hue_bridge(cb, decodeURIComponent(host), port, usr); } else { cb(false, usr); } if (isAPIv2Ready) { $('#port').val(443); } } } function checkBridgeResult(reply, usr) { if (reply) { //abort checking, first reachable result is used $('#wiz_hue_ipstate').html(""); $('#host').val(hueIPs[hueIPsinc].host) $('#port').val(hueIPs[hueIPsinc].port) $('#usrcont').toggle(true); checkHueBridge(checkUserResult, $('#user').val()); } else { $('#usrcont').toggle(false); $('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip')); } }; function checkUserResult(reply, username) { $('#usrcont').toggle(true); var hue_create_user = 'wiz_hue_e_create_user'; if (!isEntertainmentReady) { hue_create_user = 'wiz_hue_create_user'; $('#hue_client_key_r').toggle(false); } else { $('#hue_client_key_r').toggle(true); } $('#wiz_hue_create_user').text($.i18n(hue_create_user)); $('#wiz_hue_create_user').toggle(true); if (reply) { $('#user').val(username); if (isEntertainmentReady && $('#clientkey').val() == "") { $('#wiz_hue_usrstate').html($.i18n('wiz_hue_e_clientkey_needed')); $('#wiz_hue_create_user').toggle(true); } else { $('#wiz_hue_usrstate').html(""); $('#wiz_hue_create_user').toggle(false); if (isEntertainmentReady) { $('#hue_id_headline').text($.i18n('wiz_hue_e_desc3')); $('#hue_grp_ids_t').toggle(true); get_hue_groups(username); } else { $('#hue_id_headline').text($.i18n('wiz_hue_desc2')); $('#hue_grp_ids_t').toggle(false); get_hue_lights(username); } } } else { //abort checking, first reachable result is used $('#wiz_hue_usrstate').html($.i18n('wiz_hue_failure_user')); $('#wiz_hue_create_user').toggle(true); } }; function useGroupId(id, username) { $('#groupId').val(hueEntertainmentConfigs[id].id); if (isAPIv2Ready) { var group = hueEntertainmentConfigs[id]; groupLights = []; for (const light of group.light_services) { groupLights.push(light.rid); } groupChannels = []; for (const channel of group.channels) { groupChannels.push(channel); } groupLightsLocations = []; for (const location of group.locations.service_locations) { groupLightsLocations.push(location); } } else { //Ensure ligthIDs are strings groupLights = hueEntertainmentConfigs[id].lights.map(num => { return String(num); }); var lightLocations = hueEntertainmentConfigs[id].locations; for (var locationID in lightLocations) { var lightLocation = {}; let position = { x: lightLocations[locationID][0], y: lightLocations[locationID][1], z: lightLocations[locationID][2] }; lightLocation.position = position; groupLightsLocations.push(lightLocation); } } get_hue_lights(username); } function updateBridgeDetails(properties) { var ledDeviceProperties = properties.config; if (!jQuery.isEmptyObject(ledDeviceProperties)) { isEntertainmentReady = properties.isEntertainmentReady; isAPIv2Ready = properties.isAPIv2Ready; if (ledDeviceProperties.name && ledDeviceProperties.bridgeid && ledDeviceProperties.modelid) { $('#wiz_hue_discovered').html( "Bridge: " + ledDeviceProperties.name + ", Modelid: " + ledDeviceProperties.modelid + ", Firmware: " + ledDeviceProperties.swversion + "
" + "API-Version: " + ledDeviceProperties.apiversion + ", Entertainment: " + (isEntertainmentReady ? "✓" : "-") + ", APIv2: " + (isAPIv2Ready ? "✓" : "-") ); } } } async function discover_hue_bridges() { $('#wiz_hue_ipstate').html($.i18n('edt_dev_spec_devices_discovery_inprogress')); // $('#wiz_hue_discovered').html("") const res = await requestLedDeviceDiscovery('philipshue'); if (res && !res.error) { const r = res.info; // Process devices returned by discovery if (r.devices.length == 0) { $('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip')); $('#wiz_hue_discovered').html("") } else { hueIPs = []; hueIPsinc = 0; var discoveryMethod = "ssdp"; if (res.info.discoveryMethod) { discoveryMethod = res.info.discoveryMethod; } for (const device of r.devices) { if (device) { var host; var port; if (discoveryMethod === "ssdp") { if (device.hostname && device.domain) { host = device.hostname + "." + device.domain; port = device.port; } else { host = device.ip; port = device.port; } } else { host = device.service; port = device.port; } if (host) { if (!hueIPs.some(item => item.host === host)) { hueIPs.push({ host: host, port: port }); } } } } $('#wiz_hue_ipstate').html(""); $('#host').val(hueIPs[hueIPsinc].host) $('#port').val(hueIPs[hueIPsinc].port) $('#hue_bridge_select').html(""); for (var key in hueIPs) { $('#hue_bridge_select').append(createSelOpt(key, hueIPs[key].host)); } $('.hue_bridge_sel_watch').on("click", function () { hueIPsinc = $(this).val(); var name = $("#hue_bridge_select option:selected").text(); $('#host').val(name); $('#port').val(hueIPs[hueIPsinc].port) var usr = $('#user').val(); if (usr != "") { checkHueBridge(checkUserResult, usr); } else { checkHueBridge(checkBridgeResult); } }); $('.hue_bridge_sel_watch').click(); } } } async function getProperties_hue_bridge(cb, hostAddress, port, username, resourceFilter) { let params = { host: hostAddress, username: username, filter: resourceFilter }; if (port !== 'undefined') { params.port = parseInt(port); } var ledType = 'philipshue'; var key = hostAddress; //Create ledType cache entry if (!devicesProperties[ledType]) { devicesProperties[ledType] = {}; } // Use device's properties, if properties in chache if (devicesProperties[ledType][key] && devicesProperties[ledType][key][username]) { updateBridgeDetails(devicesProperties[ledType][key]); cb(true, username); } else { const res = await requestLedDeviceProperties(ledType, params); if (res && !res.error) { var ledDeviceProperties = res.info.properties; if (!jQuery.isEmptyObject(ledDeviceProperties)) { devicesProperties[ledType][key] = {}; devicesProperties[ledType][key][username] = ledDeviceProperties; isAPIv2Ready = res.info.isAPIv2Ready; devicesProperties[ledType][key].isAPIv2Ready = isAPIv2Ready; isEntertainmentReady = res.info.isEntertainmentReady; devicesProperties[ledType][key].isEntertainmentReady = isEntertainmentReady; updateBridgeDetails(devicesProperties[ledType][key]); if (username === "config") { cb(true); } else { cb(true, username); } } else { cb(false, username); } } else { cb(false, username); } } } async function identify_hue_device(hostAddress, port, username, name, id, id_v1) { var disabled = $('#btn_wiz_save').is(':disabled'); // Take care that new record cannot be save during background process $('#btn_wiz_save').prop('disabled', true); let params = { host: decodeURIComponent(hostAddress), username: username, lightName: decodeURIComponent(name), lightId: id, lightId_v1: id_v1 }; if (port !== 'undefined') { params.port = parseInt(port); } await requestLedDeviceIdentification('philipshue', params); if (!window.readOnlyMode) { $('#btn_wiz_save').prop('disabled', disabled); } } //return editor Value function eV(vn, defaultVal = "") { var editor = (vn) ? conf_editor.getEditor("root.specificOptions." + vn) : null; return (editor == null) ? defaultVal : ((defaultVal != "" && !isNaN(defaultVal) && isNaN(editor.getValue())) ? defaultVal : editor.getValue()); } function beginWizardHue() { var usr = eV("username"); if (usr != "") { $('#user').val(usr); } var clkey = eV("clientkey"); if (clkey != "") { $('#clientkey').val(clkey); } //check if host is empty/reachable/search for bridge if (eV("host") == "") { hueIPs = []; hueIPsinc = 0; discover_hue_bridges(); } else { var host = eV("host"); $('#host').val(host); var port = eV("port"); if (port > 0) { $('#port').val(port); } else { $('#port').val(''); } hueIPs.push({ host: host, port: port }); if (usr != "") { checkHueBridge(checkUserResult, usr); } else { checkHueBridge(checkBridgeResult); } } $('#retry_bridge').off().on('click', function () { var host = $('#host').val(); var port = parseInt($('#port').val()); if (host != "") { var idx = hueIPs.findIndex(item => item.host === host && item.port === port); if (idx === -1) { hueIPs.push({ host: host, port: port }); hueIPsinc = hueIPs.length - 1; } else { hueIPsinc = idx; } } else { discover_hue_bridges(); } var usr = $('#user').val(); if (usr != "") { checkHueBridge(checkUserResult, usr); } else { checkHueBridge(checkBridgeResult); } }); $('#retry_usr').off().on('click', function () { checkHueBridge(checkUserResult, $('#user').val()); }); $('#wiz_hue_create_user').off().on('click', function () { createHueUser(); }); function assignLightEntertainmentPos(isFocusCenter, position, name, id) { var x = position.x; var z = position.z; if (isFocusCenter) { // Map lights as in centered range -0.5 to 0.5 if (x < -0.5) { x = -0.5; } else if (x > 0.5) { x = 0.5; } if (z < -0.5) { z = -0.5; } else if (z > 0.5) { z = 0.5; } } else { // Map lights as in full range -1 to 1 x /= 2; z /= 2; } var h = x + 0.5; var v = -z + 0.5; var hmin = h - 0.05; var hmax = h + 0.05; var vmin = v - 0.05; var vmax = v + 0.05; let layoutObject = { hmin: hmin < 0 ? 0 : hmin, hmax: hmax > 1 ? 1 : hmax, vmin: vmin < 0 ? 0 : vmin, vmax: vmax > 1 ? 1 : vmax, name: name }; if (id) { layoutObject.name += "_" + id; } return layoutObject; } function assignSegmentedLightPos(segment, position, name) { var layoutObjects = []; var segTotalLength = 0; for (var key in segment) { segTotalLength += segment[key].length; } var min; var max; var horizontal = true; var layoutObject = assignLightPos(position, name); if (position === "left" || position === "right") { // vertical distribution min = layoutObject.vmin; max = layoutObject.vmax; horizontal = false; } else { // horizontal distribution min = layoutObject.hmin; max = layoutObject.hmax; } var step = (max - min) / segTotalLength; var start = min; for (var key in segment) { min = start; max = round(start + segment[key].length * step); if (horizontal) { layoutObject.hmin = min; layoutObject.hmax = max; } else { layoutObject.vmin = min; layoutObject.vmax = max; } layoutObject.name = name + "_" + key; layoutObjects.push(JSON.parse(JSON.stringify(layoutObject))); start = max; } return layoutObjects; } $('#btn_wiz_save').off().on("click", function () { var hueLedConfig = []; var finalLightIds = []; var channelNumber = 0; //create hue led config for (var key in groupLights) { var lightId = groupLights[key]; if ($('#hue_' + lightId).val() != "disabled") { finalLightIds.push(lightId); var lightName; if (isAPIv2Ready) { var light = hueLights.find(light => light.id === lightId); lightName = light.metadata.name; } else { lightName = hueLights[lightId].name; } var position = $('#hue_' + lightId).val(); var lightIdx = groupLights.indexOf(lightId); var lightLocation = groupLightsLocations[lightIdx]; var serviceID; if (isAPIv2Ready) { serviceID = lightLocation.service.rid; } if (position.startsWith("entertainment")) { // Layout per entertainment area definition at bridge var isFocusCenter = false; if (position === "entertainment_center") { isFocusCenter = true; } if (isAPIv2Ready) { groupChannels.forEach((channel) => { if (channel.members[0].service.rid === serviceID) { var layoutObject = assignLightEntertainmentPos(isFocusCenter, channel.position, lightName, channel.channel_id); hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject))); ++channelNumber; } }); } else { var layoutObject = assignLightEntertainmentPos(isFocusCenter, lightLocation.position, lightName); hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject))); } } else { // Layout per manual settings var maxSegments = 1; if (isAPIv2Ready) { var service = hueEntertainmentServices.find(service => service.id === serviceID); maxSegments = service.segments.max_segments; } if (maxSegments > 1) { var segment = service.segments.segments; var layoutObjects = assignSegmentedLightPos(segment, position, lightName); hueLedConfig.push(...layoutObjects); } else { var layoutObject = assignLightPos(position, lightName); hueLedConfig.push(JSON.parse(JSON.stringify(layoutObject))); } channelNumber += maxSegments; } } } 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.host = $('#host').val(); d.port = parseInt($('#port').val()); d.username = $('#user').val(); d.type = 'philipshue'; d.colorOrder = 'rgb'; d.lightIds = finalLightIds; d.transitiontime = parseInt(eV("transitiontime", 1)); d.restoreOriginalState = (eV("restoreOriginalState", false) == true); d.switchOffOnBlack = (eV("switchOffOnBlack", false) == true); d.blackLevel = parseFloat(eV("blackLevel", 0.009)); d.onBlackTimeToPowerOff = parseInt(eV("onBlackTimeToPowerOff", 600)); d.onBlackTimeToPowerOn = parseInt(eV("onBlackTimeToPowerOn", 300)); d.brightnessFactor = parseFloat(eV("brightnessFactor", 1)); d.clientkey = $('#clientkey').val(); d.groupId = $('#groupId').val(); d.blackLightsTimeout = parseInt(eV("blackLightsTimeout", 5000)); d.brightnessMin = parseFloat(eV("brightnessMin", 0)); d.brightnessMax = parseFloat(eV("brightnessMax", 1)); d.brightnessThreshold = parseFloat(eV("brightnessThreshold", 0.0001)); d.handshakeTimeoutMin = parseInt(eV("handshakeTimeoutMin", 300)); d.handshakeTimeoutMax = parseInt(eV("handshakeTimeoutMax", 1000)); d.verbose = (eV("verbose") == true); d.autoStart = conf_editor.getEditor("root.generalOptions.autoStart").getValue(); d.enableAttempts = parseInt(conf_editor.getEditor("root.generalOptions.enableAttempts").getValue()); d.enableAttemptsInterval = parseInt(conf_editor.getEditor("root.generalOptions.enableAttemptsInterval").getValue()); d.useEntertainmentAPI = isEntertainmentReady; d.useAPIv2 = isAPIv2Ready; if (isEntertainmentReady) { d.hardwareLedCount = channelNumber; if (window.serverConfig.device.type !== d.type) { //smoothing on, if new device sc.smoothing = { enable: true }; } } else { d.hardwareLedCount = finalLightIds.length; d.verbose = false; if (window.serverConfig.device.type !== d.type) { //smoothing off, if new device sc.smoothing = { enable: false }; } } window.serverConfig.device = d; requestWriteConfig(sc, true); resetWizard(); }); $('#btn_wiz_abort').off().on('click', resetWizard); } function createHueUser() { var host = hueIPs[hueIPsinc].host; var port = hueIPs[hueIPsinc].port; let params = { host: host }; if (port !== 'undefined') { params.port = parseInt(port); } var retryTime = 30; var retryInterval = 2; var UserInterval = setInterval(function () { $('#wizp1').toggle(false); $('#wizp2').toggle(false); $('#wizp3').toggle(true); (async () => { retryTime -= retryInterval; $("#connectionTime").html(retryTime); if (retryTime <= 0) { abortConnection(UserInterval); clearInterval(UserInterval); } else { const res = await requestLedDeviceAddAuthorization('philipshue', params); if (res && !res.error) { var response = res.info; if (jQuery.isEmptyObject(response)) { debugMessage(retryTime + ": link button not pressed or device not reachable"); } else { $('#wizp1').toggle(false); $('#wizp2').toggle(true); $('#wizp3').toggle(false); var username = response.username; if (username != 'undefined') { $('#user').val(username); conf_editor.getEditor("root.specificOptions.username").setValue(username); conf_editor.getEditor("root.specificOptions.host").setValue(host); conf_editor.getEditor("root.specificOptions.port").setValue(port); } if (isEntertainmentReady) { var clientkey = response.clientkey; if (clientkey != 'undefined') { $('#clientkey').val(clientkey); conf_editor.getEditor("root.specificOptions.clientkey").setValue(clientkey); } } checkHueBridge(checkUserResult, username); clearInterval(UserInterval); } } else { $('#wizp1').toggle(false); $('#wizp2').toggle(true); $('#wizp3').toggle(false); clearInterval(UserInterval); } } })(); }, retryInterval * 1000); } function get_hue_groups(username) { var host = hueIPs[hueIPsinc].host; if (devicesProperties['philipshue'][host] && devicesProperties['philipshue'][host][username]) { var ledProperties = devicesProperties['philipshue'][host][username]; if (isAPIv2Ready) { if (!jQuery.isEmptyObject(ledProperties.data)) { if (Object.keys(ledProperties.data).length > 0) { hueEntertainmentConfigs = ledProperties.data.filter(config => { return config.type === "entertainment_configuration"; }); hueEntertainmentServices = ledProperties.data.filter(config => { return (config.type === "entertainment" && config.renderer === true); }); } } } else { if (!jQuery.isEmptyObject(ledProperties.groups)) { hueEntertainmentConfigs = []; var hueGroups = ledProperties.groups; for (var groupid in hueGroups) { if (hueGroups[groupid].type == 'Entertainment') { hueGroups[groupid].id = groupid; hueEntertainmentConfigs.push(hueGroups[groupid]); } } } } if (Object.keys(hueEntertainmentConfigs).length > 0) { $('.lidsb').html(""); $('#wh_topcontainer').toggle(false); $('#hue_grp_ids_t').toggle(true); for (var groupid in hueEntertainmentConfigs) { $('.gidsb').append(createTableRow([groupid + ' (' + hueEntertainmentConfigs[groupid].name + ')', ''])); } } else { noAPISupport('wiz_hue_e_noegrpids', username); } } } function noAPISupport(txt, username) { showNotification('danger', $.i18n('wiz_hue_e_title'), $.i18n('wiz_hue_e_noapisupport_hint')); conf_editor.getEditor("root.specificOptions.useEntertainmentAPI").setValue(false); $("#root_specificOptions_useEntertainmentAPI").trigger("change"); $('#btn_wiz_holder').append('
' + $.i18n('wiz_hue_e_noapisupport_hint') + '
'); $('#hue_grp_ids_t').toggle(false); var txt = (txt) ? $.i18n(txt) : $.i18n('wiz_hue_e_nogrpids'); $('

' + txt + '
' + $.i18n('wiz_hue_e_noapisupport') + '

').insertBefore('#wizp2_body #hue_ids_t'); $('#hue_id_headline').html($.i18n('wiz_hue_desc2')); get_hue_lights(username); } function get_hue_lights(username) { var host = hueIPs[hueIPsinc].host; if (devicesProperties['philipshue'][host] && devicesProperties['philipshue'][host][username]) { var ledProperties = devicesProperties['philipshue'][host][username]; if (isAPIv2Ready) { if (!jQuery.isEmptyObject(ledProperties.data)) { if (Object.keys(ledProperties.data).length > 0) { hueLights = ledProperties.data.filter(config => { return config.type === "light"; }); } } } else { if (!jQuery.isEmptyObject(ledProperties.lights)) { hueLights = ledProperties.lights; } } if (Object.keys(hueLights).length > 0) { if (!isEntertainmentReady) { $('#wh_topcontainer').toggle(false); } $('#hue_ids_t, #btn_wiz_save').toggle(true); var lightOptions = [ "top", "topleft", "topright", "bottom", "bottomleft", "bottomright", "left", "lefttop", "leftmiddle", "leftbottom", "right", "righttop", "rightmiddle", "rightbottom", "entire", "lightPosTopLeft112", "lightPosTopLeftNewMid", "lightPosTopLeft121", "lightPosBottomLeft14", "lightPosBottomLeft12", "lightPosBottomLeft34", "lightPosBottomLeft11", "lightPosBottomLeft112", "lightPosBottomLeftNewMid", "lightPosBottomLeft121" ]; if (isEntertainmentReady) { lightOptions.unshift("entertainment_center"); lightOptions.unshift("entertainment"); } else { lightOptions.unshift("disabled"); groupLights = Object.keys(hueLights); } $('.lidsb').html(""); var pos = ""; for (var id in groupLights) { var lightId = groupLights[id]; var lightId_v1 = "/lights/" + lightId; var lightName; if (isAPIv2Ready) { var light = hueLights.find(light => light.id === lightId); lightName = light.metadata.name; lightId_v1 = light.id_v1; } else { lightName = hueLights[lightId].name; } if (isEntertainmentReady) { var lightLocation = {}; lightLocation = groupLightsLocations[id]; if (lightLocation) { if (isAPIv2Ready) { pos = 0; } else { var x = lightLocation.position.x; var y = lightLocation.position.y; var z = lightLocation.position.z; 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 += '