407 lines
18 KiB
HTML
407 lines
18 KiB
HTML
<html>
|
|
<head>
|
|
<!-- Materialze style -->
|
|
<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" src="words.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
var onChange;
|
|
|
|
function encrypt(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 decrypt(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 showHideSettings() {
|
|
if ($('#type').val() === 'client') {
|
|
$('#_clientId').show();
|
|
$('#_url').show();
|
|
$('#test').show();
|
|
$('#_patterns').show();
|
|
$('#_certPublic').hide();
|
|
$('#_certPrivate').hide();
|
|
$('#_certChained').hide();
|
|
$('#_webSocket').hide();
|
|
$('#_publishOnSubscribe').hide();
|
|
} else {
|
|
$('#_clientId').hide();
|
|
$('#_url').hide();
|
|
$('#test').hide();
|
|
$('#_patterns').hide();
|
|
$('#_webSocket').show();
|
|
|
|
if ($('#ssl').prop('checked')) {
|
|
$('#_certPublic').show();
|
|
$('#_certPrivate').show();
|
|
$('#_certChained').show();
|
|
} else {
|
|
$('#_certPublic').hide();
|
|
$('#_certPrivate').hide();
|
|
$('#_certChained').hide();
|
|
}
|
|
|
|
$('#_publishOnSubscribe').show();
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
showHideSettings();
|
|
$('#type').on('change', showHideSettings);
|
|
$('#ssl').on('change', showHideSettings);
|
|
$('#test').on('click', test);
|
|
}
|
|
|
|
function setValue(id, value) {
|
|
var $value = $('#' + id + '.value');
|
|
if ($value.attr('type') === 'checkbox') {
|
|
$value.prop('checked', value).change(function() {
|
|
onChange();
|
|
});
|
|
} else {
|
|
$value.val(value).change(function() {
|
|
onChange();
|
|
}).keyup(function() {
|
|
// Check that only numbers entered
|
|
if ($(this).hasClass('number')) {
|
|
var val = $(this).val();
|
|
if (val) {
|
|
var newVal = '';
|
|
for (var i = 0; i < val.length; i++) {
|
|
if (val[i] >= '0' && val[i] <= '9') {
|
|
newVal += val[i];
|
|
}
|
|
}
|
|
|
|
if (val != newVal) $(this).val(newVal);
|
|
}
|
|
}
|
|
|
|
onChange();
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadHelper(settings, param, subparam) {
|
|
if (!settings) return;
|
|
|
|
if (subparam && param) {
|
|
for (var key in settings[param][subparam]) {
|
|
if (!settings[param][subparam].hasOwnProperty(key)) continue;
|
|
if (typeof settings[param][subparam][key] !== 'object') {
|
|
setValue(param + '_' + subparam + '_' + key, settings[param][subparam][key]);
|
|
} else {
|
|
alert('4th level is not supported');
|
|
}
|
|
}
|
|
} else if (param) {
|
|
for (var key in settings[param]) {
|
|
if (!settings[param].hasOwnProperty(key)) continue;
|
|
if (typeof settings[param][key] !== 'object') {
|
|
setValue(param + '_' + key, settings[param][key]);
|
|
} else {
|
|
loadHelper(settings, param, key);
|
|
}
|
|
}
|
|
} else {
|
|
for (var key in settings) {
|
|
if (!settings.hasOwnProperty(key)) continue;
|
|
if (typeof settings[key] !== 'object') {
|
|
if (key === 'pass') {
|
|
settings[key] = decrypt('Zgfr56gFe87jJOM', settings[key]);
|
|
}
|
|
setValue(key, settings[key]);
|
|
} else {
|
|
loadHelper(settings, key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// the function loadSettings has to exist ...
|
|
function load(settings, _onChange) {
|
|
onChange = _onChange;
|
|
settings.retransmitInterval = settings.retransmitInterval || 2000;
|
|
settings.retransmitCount = settings.retransmitCount || 10;
|
|
settings.sendAckToo = settings.sendAckToo || false;
|
|
settings.webSocket = settings.webSocket || false;
|
|
settings.defaultQoS = (settings.defaultQoS === '' || settings.defaultQoS === -1 || settings.defaultQoS === '-1') ? -1 : settings.defaultQoS || 0;
|
|
if (settings.sendOnStartInterval === undefined) settings.sendOnStartInterval = 2000;
|
|
if (settings.sendInterval === undefined) settings.sendInterval = 10;
|
|
settings.clientId = settings.clientId || '';
|
|
loadHelper(settings);
|
|
$('#pass_confirm').val($('#pass').val());
|
|
|
|
init();
|
|
fillSelectCertificates('#certPublic', 'public', settings.certPublic);
|
|
fillSelectCertificates('#certPrivate', 'private', settings.certPrivate);
|
|
fillSelectCertificates('#certChained', 'chained', settings.certChained);
|
|
onChange(false);
|
|
if (M) M.updateTextFields();
|
|
}
|
|
|
|
function test() {
|
|
// var newValue = JSON.stringify(getSettings());
|
|
if (!common.enabled) {
|
|
showToast(null, _('Enable first the adapter to test client.'));
|
|
return;
|
|
}
|
|
if (changed) {
|
|
showToast(null, _('First save the adapter'));
|
|
return;
|
|
}
|
|
$('#test').addClass('disabled');
|
|
sendTo('mqtt.' + instance, 'test', getSettings(), function (result) {
|
|
$('#test').removeClass('disabled');
|
|
showMessage(_(result), _('Result: '));
|
|
});
|
|
}
|
|
|
|
function saveHelper(obj, id, value) {
|
|
var ids = id.split('_');
|
|
|
|
if (ids.length === 1) {
|
|
if (ids[0] === 'pass') value = encrypt('Zgfr56gFe87jJOM', value);
|
|
obj[id] = value;
|
|
} else if (ids.length === 2) {
|
|
if (!obj[ids[0]]) obj[ids[0]] = {};
|
|
obj[ids[0]][ids[1]] = value;
|
|
} else if (ids.length === 3) {
|
|
if (!obj[ids[0]]) obj[ids[0]] = {};
|
|
if (!obj[ids[0]][ids[1]]) obj[ids[0]][ids[1]] = {};
|
|
obj[ids[0]][ids[1]][ids[2]] = value;
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
function getSettings() {
|
|
var obj = {};
|
|
$('.value').each(function () {
|
|
var $this = $(this);
|
|
var id = $this.attr('id');
|
|
|
|
if ($this.attr('type') === 'checkbox') {
|
|
obj = saveHelper(obj, id, $this.prop('checked'))
|
|
} else {
|
|
obj = saveHelper(obj, id, $this.val())
|
|
}
|
|
});
|
|
obj.defaultQoS = parseInt(obj.defaultQoS, 10) || 0;
|
|
|
|
return obj;
|
|
}
|
|
|
|
function save(callback) {
|
|
if ($('#pass').val() !== $('#pass_confirm').val()) {
|
|
showMessage(_('Password confirmation is not equal with password'));
|
|
return;
|
|
}
|
|
if ($('#ssl').prop('checked') && $('#type').val() === 'server' && (!$('#certPrivate').val() || !$('#certPublic').val())) {
|
|
showMessage(_('Set certificates or load it first in the system settings (right top).'));
|
|
return;
|
|
}
|
|
|
|
callback(getSettings());
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.sub-title {
|
|
margin-top: 2rem!important;
|
|
padding: 0.5rem;
|
|
background: #64b5f6;
|
|
color: white;
|
|
}
|
|
.main-page {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
margin-bottom: 0 !important;
|
|
}
|
|
.page {
|
|
height: calc(100% - 34px) !important;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- you have to put your config page in a div with id adapter-container -->
|
|
<div class="m adapter-container">
|
|
<div class="main-page row">
|
|
<div class="col s12">
|
|
<ul class="tabs">
|
|
<li class="tab col s4"><a href="#tab-main" class="translate active">Connection</a></li>
|
|
<li class="tab col s4"><a href="#tab-mqtt" class="translate">MQTT Settings</a></li>
|
|
</ul>
|
|
</div>
|
|
<div id="tab-main" class="col s12 page">
|
|
<div class="row">
|
|
<div class="col s6">
|
|
<img src="mqtt.png" class="logo">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4">
|
|
<select id="type" class="value">
|
|
<option value="client" class="translate">Client</option>
|
|
<option value="server" class="translate">Server</option>
|
|
</select>
|
|
<label class="translate" for="type">Type:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4" id="_webSocket">
|
|
<input type="checkbox" id="webSocket" class="value filled-in" />
|
|
<span class="translate" for="webSocket">Use WebSockets:</span>
|
|
</div>
|
|
</div>
|
|
<h6 class="translate sub-title">Connection settings</h6>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4" id="_url">
|
|
<input type="text" id="url" class="value" />
|
|
<label class="translate" for="url">URL:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4">
|
|
<input id="port" type="number" min="1" max="65565" class="value" />
|
|
<label class="translate" for="port">Port:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m12">
|
|
<input id="ssl" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="ssl">Secure:</span>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4" id="_certPublic">
|
|
<select id="certPublic" class="value"></select>
|
|
<label class="translate" for="certPublic">Public certificate:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4" id="_certPrivate">
|
|
<select id="certPrivate" class="value"></select>
|
|
<label class="translate" for="certPrivate">Private certificate:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4" id="_certChained">
|
|
<select id="certChained" class="value"></select>
|
|
<label class="translate" for="certChained">Chained certificate:</label>
|
|
</div>
|
|
</div>
|
|
<h6 class="translate sub-title">Authentication settings</h6>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4">
|
|
<input id="user" type="text" size="17" class="value" />
|
|
<label class="translate" for="user">User:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4">
|
|
<input id="pass" type="password" size="17" class="value" />
|
|
<label class="translate" for="pass">Password:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4">
|
|
<input id="pass_confirm" type="password" size="17" />
|
|
<label class="translate" for="pass_confirm">Password confirmation:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col s12">
|
|
<a id="test" class="btn"><span class="translate">Test connection</span></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="tab-mqtt" class="col s12 page">
|
|
<div class="row">
|
|
<div class="col s6">
|
|
<img src="mqtt.png" class="logo">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div id="_patterns" class="input-field col s12 m6 l3">
|
|
<input id="patterns" type="text" size="17" class="value" />
|
|
<label for="patterns" class="translate">Patterns:</label> (
|
|
<span class="translate">Divided by comma</span>)
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="prefix" type="text" size="17" class="value" />
|
|
<label class="translate" for="prefix">Prefix for topics:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="publish" type="text" size="17" class="value" />
|
|
<label for="publish" class="translate">Mask to publish own states:</label> (
|
|
<span class="translate">Mask to publish</span>)
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="onchange" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="onchange">Store only on change:</span>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="publishAllOnStart" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="publishAllOnStart">Publish all states at start:</span>
|
|
</div>
|
|
<div id="_publishOnSubscribe" class="input-field col s12 m6 l3">
|
|
<input id="publishOnSubscribe" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="publishOnSubscribe">Publish states on subscribe:</span>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="debug" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="debug">Trace output for every message:</span>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="sendAckToo" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="sendAckToo">Send states (ack=true) too:</span>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="extraSet" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="extraSet">Use different topic names for set and get:</span>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div id="_clientId" class="input-field col s12 m6 l3">
|
|
<input id="clientId" type="text" class="value" size="17" />
|
|
<label class="translate" for="clientId">Client ID:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="maxTopicLength" type="text" class="value" size="17" />
|
|
<label for="maxTopicLength" class="translate">Max topic length:(<span class="translate">chars</span>)</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="sendOnStartInterval" type="text" class="value" size="17" />
|
|
<label for="sendOnStartInterval"><span class="translate">Interval before send topics by connection:</span> (<span class="translate">ms</span>)</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="sendInterval" type="text" class="value" size="17" />
|
|
<label for="sendInterval"><span class="translate">Send interval:</span> (<span class="translate">ms</span>)</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div id="_defaultQoS" class="input-field col s12 m6 l3">
|
|
<select id="defaultQoS" class="value">
|
|
<option value="0" class="translate">0 - At most once</option>
|
|
<option value="1" class="translate">1 - At least once</option>
|
|
<option value="2" class="translate">2 - Exactly once</option>
|
|
</select>
|
|
<label class="translate" for="defaultQoS">Default QoS:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l3">
|
|
<input id="retain" type="checkbox" class="value filled-in" />
|
|
<span class="translate" for="retain">Default retain flag:</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|