UNPKG

iobroker.netatmo-energy

Version:
800 lines (716 loc) 47.7 kB
<html> <head> <!-- Load ioBroker scripts and styles--> <link rel="stylesheet" type="text/css" href="../../css/adapter.css"> <link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css"> <script type="text/javascript" src="../../lib/js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="../../socket.io/socket.io.js"></script> <script type="text/javascript" src="../../js/translate.js"></script> <script type="text/javascript" src="../../lib/js/materialize.js"></script> <script type="text/javascript" src="../../js/adapter-settings.js"></script> <script type="text/javascript">var noConfigDialog = true;</script><!-- Deactivate buttons --> <!-- Load our own files --> <link rel="stylesheet" type="text/css" href="style.css"> <script type="text/javascript" src="words.js"></script> <script type="text/javascript"> const namespace = `netatmo-energy.${instance}`; //Load page function load(settings, onChange) { $(document).ready(function() { //if (M) M.Tabs.init($('.tabs')); if (M) M.Modal.init($('.modal'), {}); }); GetValves() .then(valves => { showValves(valves); }) .catch(() => { //error during searching for rooms); }); onChange(false); $('#netatmo_energy_close_all').hide(); $('#netatmo_energy_refresh').on('click', () => { var $sel = $('#messages'); const wait_html=`<div style="float: left;"> <img src="img/progress.gif" width="65px" onerror="this.onerror=null;this.src='img/noimage.png';"> </div> <div class="col"> <h6 class="translate">Refreshing data in progress</h6> </div>`; $sel.html(wait_html); $('#netatmo_energy_close_all').show(); translateAll(); GetValves() .then(valves => { showValves(valves); }) .catch(() => { var $sel = $('#messages'); $sel.html(''); translateAll(); }); }); $('#netatmo_energy_homesdata').on('click', () => { CreateRequest('getHomesdata', {}); }); $('#netatmo_energy_close_all').on('click', () => { CloseMessage(); }); $('#netatmo_energy_save_all').on('click', () => { CreateRequest('applyChanges', {}); }); $('#netatmo_energy_home_mode').on('click', () => { setRoomMode(); }); } //check if it is an array function isArray(it) { if (typeof Array.isArray === 'function') return Array.isArray(it); return Object.prototype.toString.call(it) === '[object Array]'; } /* Change Modes */ function setRoomMode() { let sel_class = '.NRV'; let elements = $(sel_class); let myRooms = []; for (element in elements) { sel_element = elements[element]; if (sel_element && sel_element.id && sel_element.id != "") { let folder = $(sel_element).attr('data_folder'); const result = myRooms.find((element) => element.folder == folder); if (!result) { myRooms.push({folder: folder}); CreateRequest('homeMode', {folder: folder}); } } else { break; } }; } /* Change temperature*/ function setTempValve(value, obj) { let set_val_html = '<b>' + translateWord('Target temperature:') + ' </b>' + value; let set_val = 7; let setTempArray = []; try{ set_val_html = '<b>' + translateWord('Target temperature:') + ' </b>' + Number(value).toFixed(1); } catch(e) { //error } try{ set_val = Number(value); } catch(e) { //error } //Temp set const temp_id = obj.id.substring(0, obj.id.indexOf('_')); let sel_class = '.' + temp_id + '_setTemp_Class'; let elements = $(sel_class); for (element in elements) { sel_element = elements[element]; if (sel_element && sel_element.id && sel_element.id != "") { let oldTemp = $(sel_element).attr('data_point'); $(sel_element).html((oldTemp) ? (set_val_html + ' [' + oldTemp + ']') : set_val_html); } else { break; } }; //Slider value let datapoint = null; let sel_class_slider = '.' + temp_id + '_slider_Class'; let elements_slider = $(sel_class_slider); for (element in elements_slider) { sel_element = elements_slider[element]; if (sel_element && sel_element.id && sel_element.id != "") { datapoint = $(sel_element).attr('data_point'); $(sel_element).val(set_val); } else { break; } }; if (datapoint) CreateRequest('saveTemperature', {datapoint: datapoint, temp: set_val}); } /* Close messages */ function CloseMessage() { const $sel = $('#messages'); $sel.html(''); $('#netatmo_energy_close_all').hide(); } /* Send request */ function SendMessageToInstance(myFunction, senddata) { return new Promise( function(resolve,reject) { sendTo(namespace, myFunction, senddata, function (msg) { let message = []; if (isArray(msg)) { message = msg; //valves = Object.assign(valves, _valves); } resolve(message); }); } ); } /* Get homesdata */ function CreateRequest(myFunction, senddata) { SendMessageToInstance(myFunction, senddata) .then(messages => { var $sel = $('#messages'); let wait_html = ''; for (let message of messages) { wait_html = `<div style="float: left"> <img src="img/check.png" width="65px" onerror="this.onerror=null;this.src='img/noimage.png';"> </div> <div class="col"> <h6 class="translate">${message.msgtxt}</h6> </div>`; } $sel.html(wait_html); $('#netatmo_energy_close_all').show(); translateAll(); }) .catch(() => { var $sel = $('#messages'); $sel.html(''); translateAll(); }); } /* Get valves function */ function GetValves() { return new Promise( function(resolve,reject) { sendTo(namespace, 'getValves', {}, function (msg) { let valves = []; if (isArray(msg)) { valves = msg; //valves = Object.assign(valves, _valves); } resolve(valves); }); } ); } //get battery infos function getBatteryCls(value) { if (value) { if (value == 'very_low') return {color: 'icon-red', icon: 'battery_alert', text: 'very low'} else if (value == 'low') return {color: 'icon-red', icon: 'battery_alert', text: 'low'} else if (value == 'medium') return {color: 'icon-orange', icon: 'battery_charging_full', text: 'medium'}; else if (value == 'high') return {color: 'icon-green', icon: 'battery_std', text: 'high'}; else return {color: 'icon-green', icon: 'battery_std', text: 'full'}; } return undefined; } //get window infos function getWindowCls(value) { if (value != undefined && value != null) { if (value == true) return {color: 'icon-red', icon: 'lock_open', text: 'Window open'}; else return {color: 'icon-green', icon: 'lock_outline', text: 'Window closed'}; } return undefined; } //get network infos function getNetworkCls(value) { if (value != undefined && value != null) { if (value == true) return {color: 'icon-green', icon: 'leak_add', text: 'connected'}; else return {color: 'icon-red', icon: 'leak_remove', text: 'disconnected'}; } return undefined; } //get heating infos function getHeaterCls(value) { if (value != undefined && value != null) { if (value > 0) return {color: 'icon-orange', icon: 'whatshot', text: 'heating requested'}; else return {color: 'icon-grey', icon: 'whatshot', text: 'heating not necessary'}; } return undefined; } //get anticipating infos function getAnticipatingCls(value) { if (value != undefined && value != null) { if (value == true) return {color: 'icon-orange', icon: 'notifications_active', text: 'anticipate'}; else return {color: 'icon-grey', icon: 'notifications_off', text: 'not anticipating'}; } return undefined; } //get boiler cable function getBoilerCableCls(value) { if (value != undefined && value != null) { if (value == true) return {color: 'icon-green', icon: 'done', text: 'Boiler cable used', value: value}; else return {color: 'icon-red', icon: 'not_interested', text: 'Boiler cable not used', value: value}; } return undefined; } //get boiler connected function getBoilerConnectedCls(value) { if (value != undefined && value != null) { if (value >0) return {color: 'icon-green', icon: 'done', text: 'Plug is connected to boiler', value: value}; else return {color: 'icon-red', icon: 'cancel', text: 'Plug is not connected to boiler', value: value}; } return undefined; } //get temp mode function getTempModeCls(value) { if (value != undefined && value != null) { switch (value) { case 'manual': return {color: 'icon-orange', icon: 'edit', text: 'manually'}; case 'max': return {color: 'icon-aqua', icon: 'keyboard_arrow_up', text: 'max'}; case 'off': return {color: 'icon-black', icon: 'highlight_off', text: 'off'}; case 'away': return {color: 'icon-grey', icon: 'directions_walk', text: 'away'}; case 'hg': return {color: 'icon-red', icon: 'card_travel', text: 'Frost guardian'}; case 'schedule': return {color: 'icon-green', icon: 'av_timer', text: 'Scheduled'}; default: return null; } } return undefined; } //get boiler infos function getBoilerCls(value, value_request) { if (value != undefined && value != null) { if (value == true) return 'style="background-color: #ebbe6c;"'; else return ''; } else { if (value_request != undefined && value_request != null) { if (value_request > 0) return 'style="background-color: #f7e2ad;"'; else return ''; } } return ''; } //get device infos function getImage(value) { let images = { "images": [ {"type":"NAPlug","img":"img/plug.png"}, {"type":"NATherm1","img":"img/thermostat.png"}, {"type":"NRV","img":"img/valve.png"}, ]}; let image = images.images.find( record => record.type === value); if (image) return image; else return {"type":"unknown","img":"img/netatmo.png"}; } //show valves infos function showValves(valves) { var $sel = $('#valves'); let cards = ""; let bridges = []; if (valves.length != 0) { for (let valve of valves) { if (valve.type == 'NAPlug') { bridges.push({id: valve.module_id, name: valve.deviceName}); } } for (let valve of valves) { let id = valve.val; let friendlyName = ''; if (valve.roomName) friendlyName = valve.roomName + ' (' + valve.deviceName + ')'; else friendlyName = valve.deviceName; let DeviceName = valve.deviceName; let DeviceName_ID = valve.ModuleName_ID; let schedules = valve.schedule_programs; let sub_menus_schedules = ''; if (schedules) { for (let schedule of schedules) { sub_menus_schedules = sub_menus_schedules + `<li><a href="#!" class="black-text text-darken-3 start-api-request" data-api-request="${schedule.request}"><i class="material-icons icon-orange translateT">room_service</i>${schedule.name}</a></li>`; } } let thermmodes = valve.thermmode_programs; let sub_menus_thermmodes = ''; if (thermmodes) { for (let thermmode of thermmodes) { sub_menus_thermmodes = sub_menus_thermmodes + `<li><a href="#!" class="black-text text-darken-3 start-api-request" data-api-request="${thermmode.request}"><i class="material-icons icon-green translateT">room_service</i>${thermmode.name}</a></li>`; } } let plan_active = valve.active_schedule; let thermmode_active = valve.active_thermmode; let temp_act = valve.therm_measured_temperature; let temp_set = valve.therm_setpoint_temperature; let temp_mode = valve.therm_setpoint_mode; let temp_mode_cls = getTempModeCls(temp_mode); let anticipating = valve.anticipating; let anticipating_cls = getAnticipatingCls(anticipating); let open_window = valve.open_window; let open_window_cls = getWindowCls(open_window); let reachable = valve.reachable; let reachable_cls = getNetworkCls(reachable); let battery_state = valve.battery_state; let battery_state_cls = getBatteryCls(battery_state); let battery_level = valve.battery_level; let heating_power_request = valve.heating_power_request; let heating_power_request_cls = getHeaterCls(heating_power_request); let img_src = getImage(valve.type); let module_id = valve.module_id; let bridge = valve.bridge; let name_of_home = valve.myHome; let firmware_revision = valve.firmware_revision; let rf_strength = valve.rf_strength; let BoilerStatus = getBoilerCls(valve.boiler_status, valve.heating_power_request); let boiler_valve_comfort = valve.boiler_valve_comfort_boost; let wifi_strength = valve.wifi_strength; let plug_connected_boiler = getBoilerConnectedCls(valve.plug_connected_boiler); let hardware_version = valve.hardware_version; let boiler_cable = getBoilerCableCls(valve.boiler_cable); let act_date = new Date(); let act_date_text = act_date.toLocaleString(); let setTemp = valve.Set_Temp; let setMode = valve.Set_Mode; let setMode_Home = ''; let sub_menus_modes = ''; if (valve.type == 'NRV' && temp_mode != 'schedule') { setMode_Home = valve.Set_Mode_Home; let setMode_Home_Text = valve.Set_Mode_Home_Text; if (setMode_Home) { sub_menus_modes = sub_menus_modes + `<li><a href="#!" class="black-text text-darken-3 start-api-request-home-mode" data-api-request="${setMode_Home}"><i class="material-icons icon-red">room_service</i>${setMode_Home_Text}</a></li>`; } } let id_bridge = bridge; if (valve.type == 'NAPlug') { id_bridge = module_id; } let bridge_devicename = ''; for (let bridge_name of bridges) { if (bridge_name.id == id_bridge) { bridge_devicename = bridge_name.name; break; } } let mod_id_internal = module_id.replace(/:/g, ''); //${battery_icon} var card = `<div id="${mod_id_internal}" class="valve" data-friendly-name="${friendlyName}" data-device-name_id="${DeviceName_ID}" data-device-name="${DeviceName}"> <div class="card dcard" ${BoilerStatus}> <div class="card-content"> <div class="card-header"> <div style="height: 100%;"> ${img_src.img != undefined && img_src.img!= null ? ` <img src="${img_src.img}" width="65px" onerror="this.onerror=null;this.src='img/noimage.png';"> ` : ''} </div> <div class="info"> ${temp_mode_cls != undefined && temp_mode_cls!= null ? ` <div id="${mod_id_internal}_schedule" class="col el"> <a id="temp_mode_icon" class="tooltipped translateT" title="${temp_mode_cls.text}"> <i class="material-icons ${temp_mode_cls.color}" style="font-size: 24px;padding:left=5px">${temp_mode_cls.icon}</i> </a> </div>` : ''} ${boiler_valve_comfort != undefined && boiler_valve_comfort != null && boiler_valve_comfort == true ? ` <div id="${mod_id_internal}_boiler_valve_comfort" class="col el"> <a id="boiler_valve_icon" class="tooltipped translateT" title="Comfort boost requested"> <i class="material-icons icon-green" style="font-size: 24px;padding:left=5px">mood</i> </a> </div>` : ''} ${battery_state != undefined ? ` <div id="${mod_id_internal}_battery" class="col el"> <a id="battery_icon" class="tooltipped translateT" title="${battery_state_cls.text}"> <i class="material-icons ${battery_state_cls.color}" style="font-size: 24px;padding:left=5px">${battery_state_cls.icon}</i> </a> </div>` : ''} ${reachable != undefined ? ` <div id="${mod_id_internal}_network" class="col el"> <a id="reachable_icon" class="tooltipped translateT" title="${reachable_cls.text}"> <i class="material-icons ${reachable_cls.color}" style="font-size: 24px;padding:left=5px">${reachable_cls.icon}</i> </a> </div>` : ''} ${open_window != undefined ? ` <div id="${mod_id_internal}_window" class="col el"> <a id="open_window_icon" class="tooltipped translateT" title="${open_window_cls.text}"> <i class="material-icons ${open_window_cls.color}" style="font-size: 24px;padding:left=5px">${open_window_cls.icon}</i> </a> </div>` : ''} ${anticipating != undefined ? ` <div id="${mod_id_internal}_antizipation" class="col el"> <a id="anticipating_icon" class="tooltipped translateT" title="${anticipating_cls.text}"> <i class="material-icons ${anticipating_cls.color}" style="font-size: 24px;padding:left=5px">${anticipating_cls.icon}</i> </a> </div>` : ''} ${heating_power_request != undefined ? ` <div id="${mod_id_internal}_heater" class="col el"> <a id="heating_power_icon" class="tooltipped translateT" title="${heating_power_request_cls.text}"> <i class="material-icons ${heating_power_request_cls.color}" style="font-size: 24px;padding:left=5px">${heating_power_request_cls.icon}</i> </a> </div>` : ''} ${boiler_cable != undefined ? ` <div id="${mod_id_internal}_boiler_cable" class="col el"> <a id="boiler_cable_icon" class="tooltipped translateT" title="${boiler_cable.text}"> <i class="material-icons ${boiler_cable.color}" style="font-size: 24px;padding:left=5px">${boiler_cable.icon}</i> </a> </div>` : ''} ${plug_connected_boiler != undefined ? ` <div id="${mod_id_internal}_boiler_connected" class="col el"> <a id="plug_connected_boiler_icon" class="tooltipped translateT" title="${plug_connected_boiler.text}"> <i class="material-icons ${plug_connected_boiler.color}" style="font-size: 24px;padding:left=5px">${plug_connected_boiler.icon}</i> </a> </div>` : ''} </div> </div> <div class="card-details"> ${friendlyName != undefined && friendlyName!= null ? ` <div id="friendly_name" class="card-title truncate" style="margin-right: 5px;">${friendlyName} </div> ` : ''} ${temp_act != undefined && temp_act!= null ? ` <ul style="margin: 0px;"><b class="translate">Actual temperature:</b> ${temp_act.toFixed(1)}</ul> ` : ''} ${temp_set != undefined && temp_set!= null ? ` <ul id="${mod_id_internal}_setTemp_TempValve" data_point="${temp_set.toFixed(1)}" data_folder="${setMode}" class="${id}_setTemp_Class ${valve.type}" style="margin: 0px;"> <b class="translate">Target temperature:</b> ${temp_set.toFixed(1)} </ul> ` : ''} ${temp_set != undefined && temp_set!= null ? ` <input id="${id}_setTemp" data_point="${setTemp}" type="range" min="7" max="30" step="0.5" value="${temp_set}" class="myNewSlider ${id}_slider_Class" onchange="setTempValve(this.value, this)"> ` : ''} ${plan_active != undefined && plan_active!= null ? ` <ul style="margin: 0px;"><b class="translate">Heating Plan:</b> ${plan_active}</ul> ` : ''} ${thermmode_active != undefined && thermmode_active!= null ? ` <ul style="margin: 0px;"><b class="translate">Mode:</b> ${thermmode_active}</ul> ` : ''} ${plug_connected_boiler != undefined && plug_connected_boiler!= null ? ((plug_connected_boiler.value > 0) ? `<ul style="margin: 0px;"><b class="translate">Plug is connected to boiler</b></ul>` : `<ul style="margin: 0px;"><b class="translate">Plug is not connected to boiler</b></ul>`) : ''} ${boiler_cable != undefined && boiler_cable!= null ? ((boiler_cable.value == true) ? `<ul style="margin: 0px;"><b class="translate">Boiler cable used</b></ul>` : `<ul style="margin: 0px;"><b class="translate">Boiler cable not used</b></ul>`) : ''} </div> </div> <div class="card-action"> <div style="margin-left: auto;"> <span class="card-title activator grey-text text-darken-4"> <b class="tooltipped translateT" style="margin-right: 5px;" title="Bridge">${bridge_devicename}</b> <a id="footer_bridge" class="right tooltipped translateT" style="margin-right: 1px;" title="More details"> <i class="material-icons icon-grey" style="margin-right: 1px;">more_vert</i> </a> </span> </div> </div> <div class="card-reveal"> <div> <div class="card-title card-header"> <div style="height: 100%;"> <img src="${img_src.img}" width="65px" onerror="this.onerror=null;this.src='img/noimage.png';"> </div> <div id="friendly_name" class="card-title truncate" style="margin-right: 5px;">${friendlyName}</div> <div style="margin-left: auto;"> <i class="material-icons right">close</i> </div> </div> <div> <div style="flex-grow: 1; margin-left: 10px;"> ${name_of_home != undefined && name_of_home!= null ? ` <ul style="margin: 0px;"><b class="translate">Home:</b> ${name_of_home}</ul> ` : ''} ${id != undefined && id!= null ? ` <ul style="margin: 0px;"><b class="translate">Roomnumber:</b> ${id}</ul> ` : ''} ${module_id != undefined && module_id!= null ? ` <ul style="margin: 0px;"><b class="translate">Module ID:</b> ${module_id}</ul> ` : ''} ${bridge != undefined && bridge!= null ? ` <ul style="margin: 0px;"><b class="translate">Bridge:</b> ${bridge}</ul> ` : ''} ${firmware_revision != undefined && firmware_revision!= null ? ` <ul style="margin: 0px;"><b class="translate">Firmware:</b> ${firmware_revision}</ul> ` : ''} ${hardware_version != undefined && hardware_version!= null ? ` <ul style="margin: 0px;"><b class="translate">Hardware version:</b> ${hardware_version}</ul> ` : ''} ${rf_strength != undefined && rf_strength!= null ? ` <ul style="margin: 0px;"><b class="translate">Signal strength:</b> ${rf_strength}</ul> ` : ''} ${wifi_strength != undefined && wifi_strength!= null ? ` <ul style="margin: 0px;"><b class="translate">Wifi strength:</b> ${wifi_strength}</ul> ` : ''} ${battery_level != undefined && battery_level!= null ? ` <ul style="margin: 0px;"><b class="translate">Battery voltage:</b> ${battery_level} V</ul> ` : ''} </div> </div> <div class="card-footer"> <i class="material-icons icon-green" style="font-size: 18px;float: left">refresh</i> <div class="translate"> Refreshed: </div> <div style="float: left"> ${act_date_text}</div> ${sub_menus_thermmodes != '' ? ` <div style="margin-left: auto; float: left;"> <!-- Dropdown Trigger --> ${sub_menus_thermmodes != undefined && sub_menus_thermmodes!= null ? ` <a href="#" class="dropdown-trigger grey-text text-darken-4 tooltipped" title="${thermmode_active}" data-target="dropdown_thermmode_${mod_id_internal}"> <i class="material-icons icon-green">ac_unit</i> </a> ` : ``} </div> <!-- Dropdown Structure --> <ul id="dropdown_thermmode_${mod_id_internal}" class="dropdown-content"> ${sub_menus_thermmodes} </ul> ` : ''} ${sub_menus_schedules != '' ? ` <div style="margin-left: auto; float: left;"> <!-- Dropdown Trigger --> ${plan_active != undefined && plan_active!= null ? ` <a href="#" class="dropdown-trigger grey-text text-darken-4 tooltipped" title="${plan_active}" data-target="dropdown_schedule_${mod_id_internal}"> <i class="material-icons icon-orange">timelapse</i> </a> ` : ` <a href="#" class="dropdown-trigger grey-text text-darken-4" data-target="dropdown_schedule_${mod_id_internal}"> <i class="material-icons">more_vert</i> </a> `} </div> <!-- Dropdown Structure --> <ul id="dropdown_schedule_${mod_id_internal}" class="dropdown-content"> ${sub_menus_schedules} </ul> ` : ''} ${sub_menus_modes != '' ? ` <div style="margin-left: auto; float: left;"> <!-- Dropdown Trigger --> ${setMode_Home != undefined && setMode_Home != null ? ` <a href="#" class="dropdown-trigger grey-text text-darken-4 tooltipped" title="Home Mode" data-target="dropdown_homemode_${mod_id_internal}"> <i class="material-icons icon-grey">home</i> </a> ` : ``} </div> <!-- Dropdown Structure --> <ul id="dropdown_homemode_${mod_id_internal}" class="dropdown-content"> ${sub_menus_modes} </ul> ` : ''} </div> </div> </div> </div> </div>`; cards = cards + card; } } $sel.html(cards); var $sel = $('#messages'); let messages = ""; $sel.html(messages); $('#netatmo_energy_close_all').hide(); if (M) M.Dropdown.init($('.dropdown-trigger'), {coverTrigger: false}); $(`a.start-api-request-home-mode`).click(function (event) { const $trigger = $(event.target); const id = $trigger.data('api-request'); sendTo(namespace, 'homeModeSingle', { id }, function (data) { }); var $sel = $('#messages'); let wait_html = ''; wait_html = `<div style="float: left"> <img src="img/check.png" width="65px" onerror="this.onerror=null;this.src='img/noimage.png';"> </div> <div class="col"> <h6 class="translate">Request was sent to Netatmo Cloud</h6> </div>`; $sel.html(wait_html); $('#netatmo_energy_close_all').show(); translateAll(); }); /* Start API Requests */ $(`a.start-api-request`).click(function (event) { const $trigger = $(event.target); const id = $trigger.data('api-request'); sendTo(namespace, id, {id}, function (data) {}); var $sel = $('#messages'); let wait_html = ''; wait_html = `<div style="float: left"> <img src="img/check.png" width="65px" onerror="this.onerror=null;this.src='img/noimage.png';"> </div> <div class="col"> <h6 class="translate">Request was sent to Netatmo Cloud</h6> </div>`; $sel.html(wait_html); $('#netatmo_energy_close_all').show(); translateAll(); }); /* Open modal for device friendly name editing */ $(`a.open-rename`).click(function (event) { const $trigger = $(event.target); const instance = M.Modal.getInstance($('#modal_rename')); const $modal = $(instance.el); const id = $trigger.parents('div.valve').data('device-name_id'); const deviceName = $trigger.parents('div.valve').data('device-name'); $modal.data('oid', id); $modal.find('#friendly_name_input').val(deviceName); if (M) M.updateTextFields(); instance.open(); }); /* Apply friendly name object */ $(`a.apply-rename`).click(function (event) { const $el = $(event.target); const $modal = $el.parents('#modal_rename'); const id = $modal.data('oid'); const name = $modal.find('#friendly_name_input').val(); sendTo(namespace, 'ModifyDeviceObject', {id, object: {name}}, function (data) {}); }); translateAll(); } function save(callback) { callback(obj); } </script> </head> <body> <div id="main" class="m adapter-container"> <!-- Header --> <div id="navbar" class="row navbar-fixed"> <nav class="nav-extended" style="Background-color:#649470;"> <div class="nav-wrapper"> <div class="col" style="float: left"> <img class="logo" src="netatmo-energy.png" > </div> <div class="col"> <h5 class="translate">Netatmo Energy</h5> </div> </div> <div class="nav-content" style="height: 48px;"> <ul id="nav-mobile" class="right"> <li> <a id="netatmo_energy_close_all" class="btn-floating waves-effect waves-light red tooltipped center-align hoverable translateT" title="close"> <i class="material-icons large icon-blue">close</i> </a> <a id="netatmo_energy_save_all" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="save"> <i class="material-icons large icon-blue">save</i> </a> <a id="netatmo_energy_home_mode" class="btn-floating waves-effect waves-light green tooltipped center-align hoverable translateT" title="default mode"> <i class="material-icons large icon-blue">today</i> </a> <a id="netatmo_energy_homesdata" class="btn-floating waves-effect waves-light brown tooltipped center-align hoverable translateT" title="API Request refresh all"> <i class="material-icons large icon-blue">cloud_download</i> </a> <a id="netatmo_energy_refresh" class="btn-floating waves-effect waves-light orange tooltipped center-align hoverable translateT" title="refresh"> <i class="material-icons large icon-blue">sync</i> </a> </li> </ul> </div> </nav> </div> <div id="spacer" class="row"></div> <div id="messages" class="row"></div> <div id="valves" class="row"></div> <!-- Modal edit --> <div id="modal_rename" class="modal"> <div class="modal-content"> <div class="row"> <div class="input-field col s12"> <input id="friendly_name_input" type="text" class="validate" value=""> <label class="active translate" for="friendly_name_input">Name</label> </div> </div> </div> <div class="modal-footer"> <a id="apply_rename" href="#!" class="modal-close apply-rename waves-effect waves-green btn-flat translate">Apply</a> </div> </div> </div> </body> </html>