<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>ESPurna</title>
|
|
<meta charset="utf-8" />
|
|
<link rel="stylesheet" href="spectre.min.css" />
|
|
<script src="jquery-1.12.3.min.js"></script>
|
|
<style>
|
|
html, body {
|
|
font-size: 12px;
|
|
margin: 0;
|
|
padding: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
div.page {
|
|
display: none;
|
|
}
|
|
.bg-grey {
|
|
background-color: #efefef;
|
|
padding: 1rem;
|
|
border-radius: .3rem;
|
|
}
|
|
div.hint {
|
|
background-color: #efefef;
|
|
padding: 2rem;
|
|
margin: 20px 0;
|
|
border-left: 2px solid blue;
|
|
}
|
|
</style>
|
|
<script>
|
|
|
|
$(function() {
|
|
|
|
var timer = null;
|
|
|
|
$("form").submit(function(event) {
|
|
button = $(":submit", this);
|
|
button.addClass("loading");
|
|
$.ajax({
|
|
'method': 'POST',
|
|
'url': '/save',
|
|
'dataType': 'json',
|
|
'data': $(this).serializeArray()
|
|
}).done(function(data) {
|
|
button.removeClass("loading");
|
|
}).fail(function() {
|
|
button.removeClass("loading");
|
|
});
|
|
event.preventDefault();
|
|
setTimeout(update, 200);
|
|
});
|
|
|
|
function init() {
|
|
$.ajax({
|
|
'method': 'GET',
|
|
'url': '/init',
|
|
'dataType': 'json'
|
|
}).done(function(data) {
|
|
keys = Object.keys(data);
|
|
for (index in keys) {
|
|
key = "#" + keys[index];
|
|
value = data[keys[index]];
|
|
try {
|
|
if ($(key).prop('tagName') == 'INPUT') {
|
|
$(key).val(value);
|
|
} else {
|
|
$(key).html(value);
|
|
}
|
|
} catch(err) {
|
|
// nope
|
|
};
|
|
};
|
|
timer = setInterval(update, data.updateInterval);
|
|
document.title = data.hostname;
|
|
$("[name='pwMainsVoltage']").val(data.pwMainsVoltage);
|
|
$("[name='rfDevice']").val(data.rfDevice);
|
|
});
|
|
}
|
|
|
|
function update() {
|
|
$.ajax({
|
|
'method': 'GET',
|
|
'url': '/status',
|
|
'dataType': 'json'
|
|
}).done(function(data) {
|
|
$("#mqtt").val(data.mqtt ? "CONNECTED" : "NOT CONNECTED");
|
|
$("#power").val((data.power | 0) + "W");
|
|
$("#temperature").val((data.temperature | 0) + "ºC");
|
|
$("#humidity").val((data.humidity | 0) + "%");
|
|
if (data.relay) {
|
|
$("#relay").addClass('btn-primary').html("ON");
|
|
$("#status").val(1);
|
|
} else {
|
|
$("#relay").removeClass('btn-primary').html("OFF");
|
|
$("#status").val(0);
|
|
}
|
|
});
|
|
}
|
|
|
|
$("#btn-admin").click(function() {
|
|
$("#panel-status").hide();
|
|
$("#panel-admin").show();
|
|
$("#btn-admin").addClass('btn-primary');
|
|
$("#btn-status").removeClass('btn-primary');
|
|
});
|
|
|
|
$("#btn-status").click(function() {
|
|
$("#panel-admin").hide();
|
|
$("#panel-status").show();
|
|
$("#btn-admin").removeClass('btn-primary');
|
|
$("#btn-status").addClass('btn-primary');
|
|
});
|
|
|
|
$("#relay").click(function(event) {
|
|
var status = parseInt($("#status").val());
|
|
if (status == 1) {
|
|
$.ajax({'method': 'GET', 'url': '/relay/off'});
|
|
} else {
|
|
$.ajax({'method': 'GET', 'url': '/relay/on'});
|
|
}
|
|
setTimeout(update, 200);
|
|
event.preventDefault();
|
|
})
|
|
|
|
init();
|
|
update();
|
|
|
|
});
|
|
|
|
</script>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="container">
|
|
|
|
<header class="navbar bg-grey">
|
|
<section class="navbar-section">
|
|
<a href="#" class="navbar-brand"><span id="appname"></span></a>
|
|
</section>
|
|
<section class="navbar-section">
|
|
<button class="btn" id="btn-admin">Administration</button>
|
|
<button class="btn btn-primary" id="btn-status">Status</button>
|
|
</section>
|
|
</header>
|
|
|
|
<div class="page" id="panel-status" style="display: block;">
|
|
|
|
<div class="columns">
|
|
<div class="column col-12">
|
|
<form class="form-horizontal">
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="manufacturer">Manufacturer</label>
|
|
</div>
|
|
<div class="col-xs-9">
|
|
<input type="text" class="form-input" id="manufacturer" value="" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="device">Device</label>
|
|
</div>
|
|
<div class="col-xs-9">
|
|
<input type="text" class="form-input" id="device" value="" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="hostname">Hostname</label>
|
|
</div>
|
|
<div class="col-xs-9">
|
|
<input type="text" class="form-input" id="hostname" value="" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="network">Network</label>
|
|
</div>
|
|
<div class="col-xs-9">
|
|
<input type="text" class="form-input" id="network" value="" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="ip">IP</label>
|
|
</div>
|
|
<div class="col-xs-9">
|
|
<input type="text" class="form-input" id="ip" value="" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="mqtt">MQTT Status</label>
|
|
</div>
|
|
<div class="col-xs-9">
|
|
<input type="text" class="form-input" id="mqtt" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="power">Power</label>
|
|
</div>
|
|
<div class="col-xs-6">
|
|
<input type="text" class="form-input" id="power" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="temperature">Temperature</label>
|
|
</div>
|
|
<div class="col-xs-6">
|
|
<input type="text" class="form-input" id="temperature" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="humidity">Humidity</label>
|
|
</div>
|
|
<div class="col-xs-6">
|
|
<input type="text" class="form-input" id="humidity" disabled>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-xs-3">
|
|
<label class="form-label" for="relay">Relay Status</label>
|
|
</div>
|
|
<div class="col-xs-6">
|
|
<input type="hidden" class="form-input" name="status" id="status" value="0" />
|
|
<a class="btn" data="0" id="relay">OFF</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="page" id="panel-admin">
|
|
|
|
<form action="/" method="post">
|
|
|
|
<div class="hint">
|
|
You can configure up to 3 different WiFi networks. The device will try to connect to any of them starting with the first one.
|
|
</div>
|
|
|
|
<div class="columns">
|
|
|
|
<div class="column col-4">
|
|
<h5>Network 1</h5>
|
|
<div class="form-group">
|
|
<label class="form-label" for="ssid0">Network SSID</label>
|
|
<input name="ssid0" id="ssid0" type="text" class="form-input" size="8" tabindex="1" placeholder="Network SSID">
|
|
</div>
|
|
<div>
|
|
<label class="form-label" for="pass0">Network Password</label>
|
|
<input name="pass0" id="pass0" type="text" class="form-input" maxlength="255" tabindex="2" placeholder="Network password">
|
|
</div>
|
|
</div>
|
|
<div class="column col-4">
|
|
<h5>Network 2</h5>
|
|
<div class="form-group">
|
|
<label class="form-label" for="ssid1">Network SSID</label>
|
|
<input name="ssid1" id="ssid1" type="text" class="form-input" size="8" tabindex="3" placeholder="Network SSID">
|
|
</div>
|
|
<div>
|
|
<label class="form-label" for="pass1">Network Password</label>
|
|
<input name="pass1" id="pass1" type="text" class="form-input" maxlength="255" tabindex="4" placeholder="Network password">
|
|
</div>
|
|
</div>
|
|
<div class="column col-4">
|
|
<h5>Network 3</h5>
|
|
<div class="form-group">
|
|
<label class="form-label" for="ssid2">Network SSID</label>
|
|
<input name="ssid2" id="ssid2" type="text" class="form-input" size="8" tabindex="5" placeholder="Network SSID">
|
|
</div>
|
|
<div>
|
|
<label class="form-label" for="pass2">Network Password</label>
|
|
<input name="pass2" id="pass2" type="text" class="form-input" maxlength="255" tabindex="6" placeholder="Network password">
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="clearfix"></div>
|
|
|
|
<div class="hint">
|
|
Configure an <strong>MQTT broker</strong> in your network and you will be able to change the switch status via an MQTT message. Just send a 0 or a 1 as a payload to the provided topic below.
|
|
The switch will also report its current open/close status to the same topic and its IP address to the topic you define plus "<code>/ip</code>". Leave the server field empty to disable MQTT.
|
|
</div>
|
|
|
|
<div class="columns">
|
|
<div class="column col-4">
|
|
<div class="form-group">
|
|
<label class="form-label" for="mqttServer">MQTT Server</label>
|
|
<input name="mqttServer" id="mqttServer" type="text" class="form-input" size="8" tabindex="8" placeholder="MQTT Server">
|
|
</div>
|
|
</div>
|
|
<div class="column col-2">
|
|
<div class="form-group">
|
|
<label class="form-label" for="mqttPort">MQTT Port</label>
|
|
<input name="mqttPort" id="mqttPort" type="text" class="form-input" size="8" tabindex="9" placeholder="1883">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="columns">
|
|
<div class="column col-4">
|
|
<div class="form-group">
|
|
<label class="form-label" for="mqttUser">MQTT User</label>
|
|
<input name="mqttUser" id="mqttUser" type="text" class="form-input" size="8" tabindex="10" placeholder="Leave blank if no user/pass">
|
|
</div>
|
|
</div>
|
|
<div class="column col-4">
|
|
<div class="form-group">
|
|
<label class="form-label" for="mqttPassword">MQTT Password</label>
|
|
<input name="mqttPassword" id="mqttPassword" type="text" class="form-input" size="8" tabindex="11" placeholder="Leave blank if no user/pass">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="columns">
|
|
<div class="column col-4">
|
|
<div class="form-group">
|
|
<label class="form-label" for="mqttTopic">MQTT Topic</label>
|
|
<input name="mqttTopic" id="mqttTopic" type="text" class="form-input" size="8" tabindex="12" maxlength="35" placeholder="MQTT Topic">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="clearfix"></div>
|
|
|
|
<div class="hint">
|
|
If your device supports RF switching you can configure here the channel and device ID.
|
|
</div>
|
|
|
|
<div class="columns">
|
|
<div class="column col-2">
|
|
<div class="form-group">
|
|
<label class="form-label" for="rfChannel">RF Channel</label>
|
|
<input name="rfChannel" id="rfChannel" type="number" min="0" max="31" step="1" class="form-input" tabindex="13"/>
|
|
</div>
|
|
</div>
|
|
<div class="column col-2">
|
|
<div class="form-group">
|
|
<label class="form-label" for="rfDevice">RF Device</label>
|
|
<select name="rfDevice" class="form-input" tabindex="14">
|
|
<option value="0">A</a>
|
|
<option value="1">B</a>
|
|
<option value="2">C</a>
|
|
<option value="3">D</a>
|
|
<option value="4">E</a>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="clearfix"></div>
|
|
|
|
<div class="hint">
|
|
If your device supports power measurement, here you can configure line potential and current ratio.
|
|
</div>
|
|
|
|
<div class="columns">
|
|
<div class="column col-2">
|
|
<div class="form-group">
|
|
<label class="form-label" for="pwMainsVoltage">AC RMS Voltage</label>
|
|
<select name="pwMainsVoltage" class="form-input" tabindex="15">
|
|
<option value="125">125</a>
|
|
<option value="220">220</a>
|
|
<option value="230">230</a>
|
|
<option value="240">240</a>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="column col-2">
|
|
<div class="form-group">
|
|
<label class="form-label" for="pwCurrentRatio">Current ratio</label>
|
|
<input name="pwCurrentRatio" id="pwCurrentRatio" type="text" class="form-input" size="8" tabindex="16" placeholder="30">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div>
|
|
<button class="btn btn-primary float-right">Update</button>
|
|
</div>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|