iobroker.wireless-mbus
Version:
Receive data from Wireless Meter-Bus (wM-Bus) devices like gas or electricity meters
346 lines (297 loc) • 13.2 kB
HTML
<html>
<head>
<!--
# vim: tabstop=4 shiftwidth=4 expandtab
This work is part of the ioBroker wmbus adapter
and is licensed under the terms of the GPL2 license.
Copyright (c) 2019 ISFH
Copyright (c) 2021 Christian Landvogt
-->
<!-- these 4 files always have to be included -->
<link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css">
<link rel="stylesheet" type="text/css" href="../../css/adapter.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>
<!-- these files always have to be included -->
<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" src="words.js"></script>
<style>
.m .col .select-wrapper+label {
top: -26px;
}
.m span{
font-size: 0.9em;
}
input[type="text"][disabled] {
color: black ;
}
</style>
<script type="text/javascript">
const MAX_RETRIES = 20;
let retryCounter = 0;
let isCustomPort = false;
let receivers = {};
let needsKey = [];
let onChangeCb;
let config;
function getSerialPorts(currentPort) {
retryCounter++;
if (retryCounter > MAX_RETRIES) {
return;
}
let timeoutSerialPorts = setTimeout(() => getSerialPorts(currentPort), 3000);
sendTo(null, 'listUart', null, (list) => {
clearTimeout(timeoutSerialPorts);
if (!list) {
timeoutSerialPorts = setTimeout(() => getSerialPorts(currentPort), 3000);
return;
}
let jqPort = $('#serialPort');
let jqCustomPort = $('#customPort');
let selectText = '';
let portFound = false;
list.forEach(port => {
if (port.path === 'Not available') {
selectText += `<option value="" selected>${_('Not available')}</option>`;
jqPort.prop('disabled', true);
return;
} else {
if (currentPort === port.path) {
portFound = true;
selectText += `<option value="${port.path}" selected>${port.path}</option>`;
} else {
selectText += `<option value="${port.path}">${port.path}</option>`;
}
}
});
isCustomPort = !portFound;
selectText += `<option value="custom"${isCustomPort ? ' selected' : ''}>${_('customPortSelect')}</option>`;
jqPort.html(selectText).select();
if (isCustomPort) {
jqCustomPort.val(currentPort);
} else {
jqCustomPort.val('');
}
checkForCustomPort();
});
}
function checkForCustomPort() {
$('#customPort').prop('disabled', $('#serialPort').val() !== 'custom');
}
function getReceiverList(actualValue) {
let timeoutReceiver = setTimeout(() => getReceiverList(actualValue), 2000);
sendTo(null, 'listReceiver', null, (list) => {
clearTimeout(timeoutReceiver);
if (!list || !Object.keys(list).length) {
timeoutReceiver = setTimeout(() => getReceiverList(actualValue), 2000);
return;
}
let jqDeviceType = $('#deviceType');
let text = '';
receivers = list;
Object.keys(list).forEach((item) => {
text += `<option value="${item}"${(actualValue === item) ? ' selected' : ''}>${list[item].name}</option>`;
});
jqDeviceType.html(text).select();
updateModes();
});
}
function getNeedsKey() {
let timeoutKeys = setTimeout(() => getNeedsKey(), 2000);
sendTo(null, 'needsKey', null, (list) => {
clearTimeout(timeoutKeys);
needsKey = list;
let aeskeys = table2values('aeskeys');
list.forEach(function(id) {
if (aeskeys.findIndex(item => item.id == id) === -1) {
aeskeys.push({id: id, key: "UNKNOWN"});
}
});
values2table('aeskeys', aeskeys, onChangeCb);
});
}
function updateModes() {
let deviceName = $('#deviceType').val();
let text = '';
Object.keys(receivers[deviceName].modes).forEach((item) => {
text += `<option value="${item}"${(config.wmbusMode === item) ? ' selected' : ''}>${receivers[deviceName].modes[item]}</option>`;
});
$('#wmbusMode').html(text).select();
}
function save(callback) {
let obj = {};
$('.value').each(function() {
let jqThis = $(this);
if (jqThis.attr('type') === 'checkbox') {
obj[jqThis.attr('id')] = jqThis.prop('checked');
} else {
obj[jqThis.attr('id')] = jqThis.val();
}
});
if (obj.serialPort === 'custom') {
obj.serialPort = $('#customPort').val();
}
obj.aeskeys = table2values('aeskeys');
obj.blacklist = table2values('blacklist');
callback(obj);
}
function load(settings, onChange) {
if (!settings) {
return;
}
settings.deviceType = settings.deviceType || 'ebi';
settings.serialPort = settings.serialPort || '/dev/ttyUSB0';
settings.serialBaudRate = settings.serialBaudRate || '9600';
settings.alwaysUpdate = settings.alwaysUpdate === true ? true : false;
settings.forcekWh = settings.forcekWh === true ? true : false;
settings.autoBlocklist = settings.autoBlocklist === false ? false : true;
$('.value').each(function () {
let jqThis = $(this);
let id = jqThis.attr('id');
if (jqThis.attr('type') === 'checkbox') {
// do not call onChange direct, because onChange could expect some arguments
jqThis.prop('checked', settings[id]).on('change', () => onChange());
} else {
// do not call onChange direct, because onChange could expect some arguments
jqThis.val(settings[id])
.on('change', () => onChange())
.on('keyup', () => onChange());
}
$('#customPort').on('keyup', () => onChange());
});
config = settings;
getSerialPorts(settings.serialPort);
getReceiverList(settings.deviceType);
onChangeCb = onChange;
$('#deviceType').on('change', updateModes);
$('#serialPort').on('change', checkForCustomPort);
onChange(false);
M.updateTextFields();
values2table('aeskeys', settings.aeskeys, onChange);
values2table('blacklist', settings.blacklist, onChange);
getNeedsKey();
}
</script>
</head>
<body>
<div class="m adapter-container">
<div class="row">
<div class="col s12">
<ul class="tabs">
<li class="tab col s2"><a href="#tab-main" class="translate active">Options</a></li>
<li class="tab col s2"><a href="#tab-keys" class="translate">AES keys</a></li>
<li class="tab col s2"><a href="#tab-blocklist" class="translate">Blocked Devices</a></li>
</ul>
</div>
<div id="tab-main" class="col s12 page">
<div class="row">
<div class="col s12 m4 l2">
<img src="wireless-mbus.png" class="logo">
</div>
</div>
<div class="row">
<div class="col s4 m4">
<label class="translate" for="deviceType">wMBus Receiver</label>
<select class="value" id="deviceType"></select>
</div>
<div class="col s4 m4">
<label class="translate" for="wmbusMode">wMBus Mode</label>
<select class="value" id="wmbusMode"></select>
</div>
</div>
<div class="row">
<div class="col s4 m4">
<select class="value" id="serialPort">
<option value="custom" class="translate" selected>customPortSelect</option>
</select>
<label for="serialPort" class="translate">serialPort</label>
</div>
<div class="col s8 m4">
<select class="value" id="serialBaudRate">
<option value="110">110</option>
<option value="150">150</option>
<option value="300">300</option>
<option value="600">600</option>
<option value="1200">1200</option>
<option value="2400">2400</option>
<option value="4800">4800</option>
<option value="9600">9600</option>
<option value="19200">19200</option>
<option value="38400">38400</option>
<option value="56000">56000</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
</select>
<label for="serialBaudRate" class="translate">serialBaudRate</label>
</div>
</div>
<div class="row">
<div class="col s4 m4">
<input id="customPort" type="text" />
<label for="customPort" class="translate">Custom serial port</label>
</div>
<div class="col s8 m4">
</div>
</div>
<div class="row">
<div class="col s8 m4">
<input class="value" id="alwaysUpdate" type="checkbox" />
<label for="alwaysUpdate" class="translate">Update unchanged states</label>
</div>
<div class="col s8 m4">
<input class="value" id="drCacheEnabled" type="checkbox" />
<label for="drCacheEnabled" class="translate">Cache for compact frames support</label>
</div>
</div>
<div class="row">
<div class="col s8 m4">
<input class="value" id="forcekWh" type="checkbox" />
<label for="forcekWh" class="translate">Force energy units to kWh</label>
</div>
<div class="col s8 m4">
<input class="value" id="autoBlocklist" type="checkbox" />
<label for="autoBlocklist" class="translate">Temporarily block device after consecutive failures</label>
</div>
</div>
</div>
<div id="tab-keys" class="col s12 page">
<div class="row">
<div class="col s8 m8" id="aeskeys">
<a class="btn-floating waves-effect waves-light blue table-button-add"><i class="material-icons">add</i></a>
<div class="table-values-div">
<table class="table-values">
<thead>
<tr>
<th data-name="id" class="translate">Device address</th>
<th data-name="key" class="translate">AES key</th>
<th data-buttons="delete"></th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
<div id="tab-blocklist" class="col s12 page">
<div class="row">
<div class="col s8 m8" id="blacklist">
<a class="btn-floating waves-effect waves-light blue table-button-add"><i class="material-icons">add</i></a>
<div class="table-values-div">
<table class="table-values">
<thead>
<tr>
<th data-name="id" class="translate">Device address</th>
<th data-buttons="delete"></th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>