initial web portal

This commit is contained in:
Kevin Matz 2020-12-17 12:45:36 -05:00
parent 8672bf19d7
commit d1776f9eba
7 changed files with 568 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,389 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WiFlash Configuration</title>
<link rel="icon" type="image/png" href="favico.png">
<link rel="stylesheet" href="style.css">
<script src="jquery-3.5.1.min.js"></script>
<script src="wiflash.js"></script>
</head>
<body>
<header>
<img id="logo" src="logo.png" alt="logo">
<h1 id="devicename">WiFlash</h1>
</header>
<main>
<nav id="tabs">
<button class="tablinks" onclick="switchTab(event, 'tabinfo')">Overview</button>
<button class="tablinks" onclick="switchTab(event, 'tabconfig')">Configuration</button>
<button class="tablinks" onclick="switchTab(event, 'tabfixtures')">Hardware</button>
<button class="tablinks" onclick="switchTab(event, 'tabhelp')">Help</button>
</nav>
<div id="tabinfo" class="tab">
<h2>System Status</h2>
<fieldset>
<legend>WiFi</legend>
<div>
<label for="status_wifi_mode">Mode</label>
<select id="status_wifi_mode" disabled>
<option value="0">&nbsp;</option>
<option value="1">Client</option>
<option value="2">Access Point</option>
<option value="3">AP+Client</option>
<option value="4">Max</option>
</select>
</div>
<div>
<label for="wifi_ssid">SSID</label>
<input id="wifi_ssid" type="text" disabled>
</div>
<!-- <div>
<label for="status_wifi_auth">Authentication</label>
<select id="status_wifi_auth" disabled>
<option value="">&nbsp;</option>
<option value="0">Open</option>
<option value="1">WEP</option>
<option value="2">WPA PSK</option>
<option value="3">WPA2 PSK</option>
<option value="4">WPA/WPA2 PSK</option>
<option value="5">WPA2 Enterprise</option>
<option value="6">MAX</option>
</select>
</div> -->
<div>
<label for="status_wifi_power">Tx Power</label>
<select id="status_wifi_power" disabled>
<option value="">&nbsp;</option>
<option value="78">19.5dBm</option>
<option value="76">19dBm</option>
<option value="74">18.5dBm</option>
<option value="68">17dBm</option>
<option value="60">15dBm</option>
<option value="52">13dBm</option>
<option value="44">11dBm</option>
<option value="34">8.5dBm</option>
<option value="28">7dBm</option>
<option value="20">5dBm</option>
<option value="8">2dBm</option>
<option value="-4">-1dBm</option>
</select>
</div>
<div>
<label for="status_wifi_status">Status</label>
<select id="status_wifi_status" disabled>
<option value="">&nbsp;</option>
<option value="255">Error</option>
<option value="0">Idle</option>
<option value="1">No SSID Available</option>
<option value="2">Scan Completed</option>
<option value="3">Connected</option>
<option value="4">Connect Failed</option>
<option value="5">Connection Lost</option>
<option value="6">Disconnected</option>
</select>
</div>
</fieldset>
<fieldset>
<legend>Network</legend>
<div>
<label for="status_network_ipv4">IP Address</label>
<input id="status_network_ipv4" type="text" disabled>
/
<input id="status_network_cidr" type="number" disabled>
</div>
<div>
<label for="status_network_ipv6">IPv6 Address</label>
<input id="status_network_ipv6" type="text" disabled>
</div>
<div>
<label for="status_network_mac">MAC Address</label>
<input id="status_network_mac" type="text" disabled>
</div>
</fieldset>
<fieldset>
<legend>Battery</legend>
<label for="status_battery_voltage">Battery Voltage</label>
<input id="status_battery_voltage" type="text" disabled>
</fieldset>
<fieldset>
<legend>RAM</legend>
<div>
<label for="status_iram_total">Total RAM</label>
<input id="status_iram_total" type="number" disabled>
</div>
<div>
<label for="status_iram_free">Free RAM</label>
<input id="status_iram_free" type="number" disabled>
</div>
</fieldset>
<fieldset>
<legend>Flash</legend>
<div>
<label for="status_spiffs_total">Total Flash</label>
<input id="status_spiffs_total" type="number" disabled>
</div>
<div>
<label for="status_spiffs_free">Free Flash</label>
<input id="status_spiffs_free" type="number" disabled>
</div>
</fieldset>
</div>
<div id="tabconfig" class="tab">
<h2>Configuration</h2>
<fieldset>
<legend>WiFi</legend>
<div>
<label for="config_wifi_mode">WiFi mode</label>
<select id="config_wifi_mode">
<option value="1">Client</option>
<option value="2">Access Point</option>
</select>
</div>
<div>
<label for="config_wifi_ssid">SSID</label>
<input id="config_wifi_ssid" type="text">
</div>
<div>
<label for="config_wifi_password">Password</label>
<input id="config_wifi_password" type="password">
<label for="show_password">Show Password</label>
<input id="show_password" type="checkbox" onchange="showPassword(config_wifi_password, this)" >
</div>
</fieldset>
<fieldset>
<legend>Network</legend>
<div>
<label for="config_network_hostname">Hostname</label>
<input id="config_network_hostname" type="text">
</div>
<div>
<label for="config_network_dhcp">Enable DHCP</label>
<input id="config_network_dhcp" type="checkbox">
</div>
<div>
<label for="config_network_ipv4">IP address</label>
<input id="config_network_ipv4" type="text">
</div>
<div>
<label for="config_network_mask">Subnet mask</label>
<input id="config_network_mask" type="text">
</div>
<div>
<label for="config_network_gateway">Gateway IP</label>
<input id="config_network_gateway" type="text">
</div>
</fieldset>
<fieldset>
<legend>OSC Button</legend>
<div>
<label for="config_button_osc_host">OSC Server</label>
<input id="config_button_osc_host" type="text">
<label for="config_button_osc_port">OSC Port</label>
<input id="config_button_osc_port" type="number" min="1" max="65535">
</div>
<div>
<label for="config_button_osc_pressed_address">OSC Address (pressed)</label>
<input id="config_button_osc_pressed_address" type="text">
<label for="config_button_osc_pressed_value">Value (pressed)</label>
<input id="config_button_osc_pressed_value" type="text">
</div>
<div>
<label for="config_button_osc_released_address">OSC Address (released)</label>
<input id="config_button_osc_released_address" type="text">
<label for="config_button_osc_released_value">Value (released)</label>
<input id="config_button_osc_released_value" type="text">
</div>
</fieldset>
<fieldset>
<legend>LED Strobe</legend>
<div>
<label for="config_strobe_universe">sACN Universe</label>
<input id="config_strobe_universe" type="number" min="1" max="63999">
</div>
<div>
<label for="config_strobe_address">DMX Address</label>
<input id="config_strobe_address" type="number" min="1" max="509">
</div>
</fieldset>
<fieldset>
<legend>LED Pixels</legend>
<div>
<label for="config_strip_universe">sACN Universe</label>
<input id="config_strip_universe" type="number" min="1" max="63999">
</div>
<div>
<label for="config_strip_address">DMX Address</label>
<input id="config_strip_address" type="number" min="1" max="497">
</div>
</fieldset>
</div>
<div id="tabfixtures" class="tab">
<h2>Hardware Setup</h2>
<fieldset>
<legend>OSC Button</legend>
<div>
<label for="config_button_enable">Enable OSC Button</label>
<input id="config_button_enable" type="checkbox">
</div>
<div>
<label for="config_button_pin">Button Pin</label>
<input id="config_button_pin" type="text">
</div>
</fieldset>
<fieldset>
<legend>LED Strobe</legend>
<div>
<label for="config_strobe_enable">Enable Strobe</label>
<input id="config_strobe_enable" type="checkbox">
</div>
<div>
<label for="config_strobe_pin">Strobe Pin</label>
<input id="config_strobe_pin" type="text">
</div>
</fieldset>
<fieldset>
<legend>LED Pixels</legend>
<div>
<label for="config_strip_enable">Enable Pixels</label>
<input id="config_strip_enable" type="checkbox">
</div>
<div>
<label for="config_strip_count">Number of LED Pixels</label>
<input id="config_strip_count" type="number" min="4">
</div>
<div>
<label for="config_strip_pin">Pixel Data Pin</label>
<input id="config_strip_pin" type="text">
</div>
</fieldset>
<form action="/api/reboot" method="post">
<fieldset>
<legend>System Restart</legend>
<div>
<label for="reboot">Perform a system restart</label>
<button id="reboot">Restart</button>
</div>
<div>
<label for="reset_on_reboot">Reset configuration</label>
<input id="reset_on_reboot" type="checkbox">
</div>
</fieldset>
</form>
<form action="/api/ota" method="post">
<fieldset>
<legend>Firmware Update</legend>
<div>
<label for="ota_file">Firmware file</label>
<input id="ota_file" type="file" disabled>
</div>
<div class="">
<label for="submit_firmware">Upload</label>
<input id="submit_firmware" type="submit" value="Submit" disabled>
</div>
</fieldset>
</form>
</div>
<div id="tabhelp" class="tab">
<h2>Help</h2>
<figure>
<blockquote cite="https://en.wikipedia.org/wiki/Clarke%27s_three_laws">Any sufficiently advanced technology is indistinguishable from magic.</blockquote>
<figcaption>&mdash;Arthur C. Clark, <cite>Clark's Third Law</cite></figcaption>
</figure>
<article>
<h3>LED Strobe DMX mapping</h3>
<table>
<thead>
<tr>
<th>Chan</th>
<th>Command</th>
<th>DMX Range</th>
<th>Value Range</th>
<th>Resolution</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Intensity Coarse</td>
<td rowspan=2>0 - 65535</td>
<td rowspan=2>0 - 100%</td>
<td rowspan=2>15 bit<br/>2.4kHz PWM</td>
</tr>
<tr>
<td>2</td>
<td>Intensity Fine</td>
</tr>
<tr>
<td>3</td>
<td>Duration</td>
<td>0 - 255</td>
<td>0.02 - 0.5s</td>
<td>0.004s</td>
</tr>
<tr>
<td>4</td>
<td>Rate</td>
<td>0 - 255</td>
<td>0.5 - 25Hz</td>
<td>0.1Hz</td>
</tr>
</tbody>
</table>
</article>
<article>
<h3>Copyrights</h3>
<table>
<thead>
<tr>
<th>Library</th>
<th>Copyright</th>
<th>License</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https//git.company235.com/kevin/WiFlasher">WiFlash</a></td>
<td>Copyright &copy; 2020 Kevin Matz</td>
<td><a href="https//git.company235.com/kevin/WiFlasher/src/branch/master/LICENSE">MIT</a></td>
</tr>
<tr>
<td><a href="https//github.com/forkineye/ESPAsyncE131">ESPAsyncE131</a></td>
<td>Copyright &copy; 2019 Shelby Merrick</td>
<td></td>
</tr>
<tr>
<td><a href="https//github.com/Makuna/NeoPixelBus">NeoPixelBus</a></td>
<td>Michael Miller</td>
<td><a href="https//github.com/Makuna/NeoPixelBus/blob/master/COPYING">LGPL 3.0</a></td>
</tr>
<tr>
<td><a href="https//github.com/me-no-dev/ESPAsyncWebServer">ESPAsyncWebServer</a></td>
<td>Copyright &copy; 2016 Hristo Gochkov</td>
<td><a href="http//www.gnu.org/licenses/lgpl-2.1.html">LGPL 2.1</a></td>
</tr>
<tr>
<td><a href="https//github.com/espressif/arduino-esp32">arduino-esp32</a></td>
<td>Copyright &copy; 2015 Ivan Grokhotkov</td>
<td><a href="https//github.com/espressif/arduino-esp32/blob/master/LICENSE.md">LGPL 2.1</a></td>
</tr>
</tbody>
</table>
</article>
</div>
</main>
<footer>
<p>Copyright &copy; 2020 Kevin Matz All Rights Reserved.</p>
</footer>
</body>
</html>

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,113 @@
body {
font-family: sans-serif;
margin-left: 4em;
margin-right: 4em;
background-color: #799;
}
h2 {
margin-bottom: 1.2em;
}
fieldset {
margin-top: 1em;
background-color: white;
}
legend {
background-color: gray;
color: white;
padding: 5px 10px;
}
label {
display: inline-block;
min-width: 14em;
text-align: right;
}
table {
background-color: white;
}
th, td {
text-align: left;
padding: 0.5em 1em;
}
thead {
background-color: #ccc;
}
tbody tr:nth-child(even) td {
background-color: #eee;
}
label::after {
content: ":";
}
footer {
color: darkgrey;
text-align: center;
}
#devicename {
padding-left: 3.5em;
}
#logo {
float: left;
height: 3em;
}
#tabs {
display: block;
overflow: hidden;
border: 1px solid darkslategrey;
background-color: #ddd;
}
#tabs button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 1em 2em;
transition: 0.3s;
font-weight: bolder;
}
#tabs button:hover {
background-color: #ccc;
}
/* Create an active/current tablink class */
#tabs button.active {
background-color: #bbb;
}
/* Style the tab content */
.tab {
background-color: #eee;
display: none;
padding: 6px 12px;
border: 1px solid darkslategrey;
border-top: none;
}
.tab h2:first-child {
display: none;
}
#tabinfo input:disabled, #tabinfo select:disabled {
font-size: 1.1em;
border-width: 0px;
color: black;
background: white;
}
#tabinfo input {
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
#tabinfo select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
figure {
display: flex;
flex-flow: column;
max-width: 25em;
}
figure blockquote {
margin: 0px;
padding: 0px;
}
figure figcaption {
text-align: right;
}

View File

@ -0,0 +1,64 @@
$( document ).ready(function() {
setInterval(getStatus, 10000);
getStatus();
getConfig();
$("#tabs button:first-child").click();
});
function getConfig() {
$.ajax({
url: "/api/config",
dataType: "json",
success: function(data) {
console.log(data);
unpackJson(data, "config");
}
});
}
function getStatus() {
$.ajax({
url: "/api/status",
dataType: "json",
success: function(data) {
console.log(data);
unpackJson(data, "status");
}
});
}
function switchTab(evt, name) {
$("#tabs button").removeClass("active");
$(evt.target).addClass("active");
$(".tab").hide();
$("#"+name).show();
}
function unpackJson(data, scope = false) {
scope = scope ? scope + "_" : "";
$.each(data, (key, value) => {
var id = scope + key;
if (isObject(value)) {
unpackJson(value, id);
} else {
var elmnt = $("#"+id);
if (elmnt.prop('type') == 'checkbox') {
elmnt.prop('checked', (value == "1") ? true : false);
} else {
elmnt.val(value);
}
}
});
}
function showPassword(input, button) {
if ($(button).prop('checked')) {
$(input).prop('type', "text");
} else {
$(input).prop('type', "password");
}
}
const isObject = (obj) => {
return Object.prototype.toString.call(obj) === '[object Object]';
};