UNPKG

iobroker.esphome

Version:

Control your ESP8266/ESP32 with simple yet powerful configuration files created and managed by ESPHome

434 lines (379 loc) 18.2 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> <!-- 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"> let _onChange; // Create secret for encrypted password storage let secret; function encryptManuell(key, value) { var result = ''; for(var i = 0; i < value.length; ++i) { result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i)); } return result; } function decryptManuell(key, value) { var result = ''; for (var i = 0; i < value.length; ++i) { result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i)); } return result; } // Build table based on devices known in instance function loadTable(obj) { let index = 0; let text = ''; console.log('Data for table ' + JSON.stringify(obj)); //device-pass for (i in obj) { if (obj[i] !== undefined) { text += '<tr id="' + obj[i].value.native.deviceName + '"><td><span id="' + obj[i].value.native.deviceName + '-index">' + obj[i].value.native.deviceName + '</span></td>'; text += '<td> <input id="' + index + '-Name" type="text" disabled="true" class="center-align input-field" value=' + obj[i].value.common.name + '></td>'; text += '<td> <input id="' + index + '-ip" type="text" disabled class="center-align input-field" value="' + obj[i].value.native.ip + '"></td>'; text += '<td> <div class="led-all center-led led-gray"></div></td>'; text += `<td> <a class="btn-floating btn-small waves-effect waves-light modal-trigger blue" onclick='editIPAddress(${index})' data-target="modal-edit-device"><i class="material-icons">create</i></a> <a onclick="delete_device('${obj[i].value.native.deviceName}')" class="delete-table-row btn-floating btn-small waves-effect waves-light red"><i class="material-icons">delete</i></a> </td>`; text += '</tr>'; index = (index + 1); } } $('#devices').append(text); $('.delete-table-row').on('click', (event) => { console.log('delete'); $(event.currentTarget).parentsUntil('tr').parent().remove(); }); getConnectedState(); $('input, .delete-device').each(function () { let $key = $(this); $key.on('click', function () { _onChange(); }).keyup(function () { _onChange(); }); $key.change(function () { _onChange(); }).keyup(function () { _onChange(); }); }); } function editIPAddress(index) { // let deviceObj socket.emit('getObjectView', 'system', 'device', {startkey: 'esphome.' + instance + '.', endkey: 'esphome.' + instance + '.\u9999', include_docs: true}, function (err, _devices) { console.log('Return of all devices : ' + JSON.stringify(_devices)); let text = ''; text += ` <p class="translate">You can either choose to use the Device Encryption Key (preferred) or API-Password (legacy)</p> <p class="translate">When Encryption Key is provided, API-Password will be ignored</p> <div class="input-field ip col s8"> <label for="device-ip"></label><input placeholder="192.168.0.100" class="center" id="device-ip" type="text"/> <span class="translate">IP</span> </div> <div class="input-field pass col s8"> <label for="deviceEncryptionKey"></label><input class="center" id="deviceEncryptionKey" type="password"/> <span class="translate">deviceEncryptionKey</span> </div> <div class="input-field pass col s8"> <label for="device-pass"></label><input class="center" id="device-pass" type="password"/> <span class="translate">device-pass</span> </div>`; $(`#edit_device_container`).html(text); }); } function delete_device(device_id) { console.log('test' + device_id); sendTo(null, 'removeDevice', device_id, (data) => { }); } // Get value of connection state function getConnectedState() { socket.emit('getObjectView', 'system', 'device', {startkey: 'esphome.' + instance + '.', endkey: 'esphome.' + instance + '.\u9999', include_docs: true}, function (err, _devices) { let namespace = 'esphome.' + instance + '.'; let len = namespace.length; console.log('Return of all devices : ' + JSON.stringify(_devices)); if (_devices && _devices.rows && _devices.rows.length) { for (const i in _devices.rows) { getState(_devices.rows[i].id + '.info._online', (err, state) => { console.log(JSON.stringify('Connection value for device : ' + _devices.rows[i].id + ' value ' + state.val)); let connectState = null; if (state.val === true) { connectState = 'led-green'; } else { connectState = 'led-red'; } console.log(connectState); let tableRow = $('td').filter((index, e) => { console.log(e); return $(e).text() === _devices.rows[i].value.native.deviceName; }).closest('tr'); console.log($(tableRow).attr('id')); $('#' + $(tableRow).attr('id') + '> td > .led-all').removeClass('led-gray'); $('#' + $(tableRow).attr('id') + '> td > .led-all').addClass(connectState); }); } } }); } // This will be called by the admin adapter when the settings page loads function loadHelper(settings, onChange) { _onChange = onChange; // example: select elements with id=key and class=value and insert value if (!settings) return; $('.value').each(function () { let $key = $(this); let id = $key.attr('id'); if (id === 'apiPass') { settings[id]; } if ($key.attr('type') === 'checkbox') { // do not call onChange direct, because onChange could expect some arguments $key.prop('checked', settings[id]) .on('change', () => onChange()); } else { // do not call onChange direct, because onChange could expect some arguments $key.val(settings[id]) .on('change', () => onChange()) .on('keyup', () => onChange()); } }); onChange(false); // reinitialize all the Materialize labels on the page if you are dynamically adding inputs: M.updateTextFields(); } function load(settings, onChange) { // example: select elements with id=key and class=value and insert value if (!settings) return; socket.emit('getObject', 'system.config', function (err, obj) { secret = (obj.native ? obj.native.secret : '') || 'Zgfr56gFe87jJOM'; loadHelper(settings, onChange); }); // initialize modal $('.modal').modal(); emitDevices(); $('#btn-edit-device').on('click', () => { console.log('Add device button executed'); messageObj = { 'device-ip': $('#device-ip').val(), 'device-pass': encryptManuell(secret, $('#device-pass').val()), 'deviceEncryptionKey': encryptManuell(secret, $('#deviceEncryptionKey').val()) }; sendTo(null, 'addDevice', messageObj, (data) => { console.log('Message from backend : ' + data); if (data.message === 'success') { $('#devices > tr').remove(); emitDevices(); } else { errorFunction(data); } }); }); $('#btn-add-device').on('click', () => { console.log('Add device button executed'); messageObj = { 'device-ip': $('#device-ip').val(), // 'device-pass': decryptManuell(secret, $('#device-pass').val()) 'device-pass': encryptManuell(secret, $('#device-pass').val()), 'deviceEncryptionKey': encryptManuell(secret, $('#deviceEncryptionKey').val()) }; sendTo(null, 'addDevice', messageObj, (data) => { console.log('Message from backend : ' + data); if (data.message === 'success') { $('#devices > tr').remove(); emitDevices(); } else { errorFunction(data); } }); }); onChange(false); // reinitialize all the Materialize labels on the page if you are dynamically adding inputs: if (M) M.updateTextFields(); } function errorFunction(data) { let text = ''; text += ` <h5 class="center ${data.type}">${data.type}</h5> <div class="row col s12 center"> <p class="break-word" >${data.message}</p> </div> <div class="row"></div>`; $(`#error_container`).html(text); $('#modal-error-message').modal('open'); } // This will be called by the admin adapter when the user presses the save button function save(callback) { let obj = {}; $('.value').each(function () { var $this = $(this); var id = $this.attr('id'); if ($this.attr('type') === 'checkbox') { obj[id] = $this.prop('checked'); } else { obj[id] = $this.val(); } }); callback(obj); console.log('test'); } // Read all devices from instance function emitDevices() { socket.emit('getObjectView', 'system', 'device', {startkey: 'esphome.' + instance + '.', endkey: 'esphome.' + instance + '.\u9999', include_docs: true}, function (err, _devices) { let namespace = 'esphome.' + instance + '.'; let len = namespace.length; console.log('Return of all devices : ' + JSON.stringify(_devices)); if (_devices && _devices.rows && _devices.rows.length) { console.log('Loopje : ' + len); loadTable(_devices.rows); } }); } </script> </head> <body> <div class="m adapter-container"> <div class="row"> <div class="col s12 m4 l2"> <img src="esphome.png" class="logo" alt='esphome'> </div> </div> <div class="section"> <p class="translate title">ESPHome Dashboard integration</p> <div class="row"> <div class="input-field col s4"> <input type="checkbox" class="value" id="ESPHomeDashboardEnabled" /> <span class="translate">ESPHomeDashboardEnabled</span> </div> <div class="col s3 input-field"> <input type="text" class="value" id="ESPHomeDashboardIP" /> <label for="ESPHomeDashboardIP" class="translate">ESPHomeDashboardIP</label> </div> <div class="col s2 input-field"> <input type="text" class="value" disabled="true" id="ESPHomeDashboardPort" /> <label for="ESPHomeDashboardPort" class="translate">ESPHomeDashboardPort</label> </div> </div> <div class="row center"> <p class="translate">ESPHome_Dashboard_Generic_info</p> <p class="translate">ESPHome_Dashboard_IP_info</p> </div> <p class="translate title">Devices can be added manually or by autodiscovery</p> <!-- <h6 class="translate">Devices can be added manually or by autodiscovery</h6>--> <div class="row"> <div class="input-field"> <a id="add-device" class="table-button-add col s2 waves-effect waves-light btn btn-large blue modal-trigger translate" data-target="modal-add-device"><i class="large left material-icons">add_circle</i>Add Device</a> </div> <!-- reconnect interval --> <div class="col s2 input_field input-field"> <label for="reconnectInterval"></label><input type="number" class="value center" id="reconnectInterval" max="3600" min="20" value="30"/> <span class="translate">reconnect interval</span> </div> <!-- end reconnect interval --> <!-- default Password --> <div class="col s2 input_field input-field"> <label for="apiPass"></label><input type="password" class="value" id="apiPass" value=""/> <span class="translate">API password</span> </div> <!-- end default Password --> <!-- Auto Discovery --> <div class="col s4 input-field"> <label for="autodiscovery"></label><input type="checkbox" class="value" id="autodiscovery" checked/> <span class="translate">Automatic device detection activated</span> </div> <!-- end Auto Discovery --> <div class="col s4 input-field"> <label for="autodiscovery"></label><input type="checkbox" class="value" id="configStates" checked/> <span class="translate">Show configuration as states</span> </div> </div> <!-- <p class="translate title">Devices</p>--> <div class="col s10 m10 l10 xl10 row"> <div class="table-values-div"> <table class="table-values centered"> <thead> <tr> <th class="translate">ID</th> <th class="translate">Name</th> <th class="translate">IP-Address</th> <th class="translate">Connected</th> <th class="translate">Delete</th> </tr> </thead> <tbody id="devices"></tbody> </table> </div> </div> <!-- Modal for edit input --> <div id="modal-edit-device" class="modal"> <div class="modal-content"> <h5 class="translate center">Edit device</h5> <div id='edit_device_container' class="row center"> <!--contend--> </div> </div> <div class="modal-footer"> <button id="btn-edit-device" class="btn waves-effect waves-light modal-close modal-action translate">Edit</button> <button class="btn waves-effect waves-light modal-close modal-action translate">Close</button> </div> </div> <!-- END for Modal for edit input --> <!-- Modal for manual ip input --> <div id="modal-add-device" class="modal"> <div class="modal-content"> <h5 class="translate center">Add device manually</h5> <div class="row center"> <p class="translate">You can either choose to use the Device Encryption Key (preferred) or API-Password (legacy)</p> <p class="translate">When Encryption Key is provided, API-Password will be ignored</p> <div class="input-field ip col s8"> <label for="device-ip"></label><input placeholder="192.168.0.100" class="center" id="device-ip" type="text"/> <span class="translate">IP</span> </div> <div class="input-field pass col s8"> <label for="deviceEncryptionKey"></label><input class="center" id="deviceEncryptionKey" type="password"/> <span class="translate">deviceEncryptionKey</span> </div> <div class="input-field pass col s8"> <label for="device-pass"></label><input class="center" id="device-pass" type="password"/> <span class="translate">device-pass</span> </div> </div> </div> <div class="modal-footer"> <button id="btn-add-device" class="btn waves-effect waves-light modal-close modal-action translate">Add</button> <button class="btn waves-effect waves-light modal-close modal-action translate">Close</button> </div> </div> <!-- END for Modal for manual ip input --> <!-- Modal for error message --> <div id="modal-error-message" class="modal"> <div class="content"> <div id='error_container'> <!--content--> </div> </div> <div class="row"> <div class="center"> <button class="btn waves-effect center waves-light modal-close modal-action translate">Close</button> </div> </div> </div> <!-- END for Modal for error message --> </div> </div> </body> </html>