<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <title>fiatlux v0.2</title> <link rel="stylesheet" href="css/picnic.min.css"> <link rel="stylesheet" href="css/style.css"> </head> <body> <nav> <a href="#" class="brand"> <span>fiatlux v0.2</span> <span class="label warning" id="status_box">Loading...</span> </a> </nav> <main data-page="dashboard" id="page"> <section id="dashboard"> <h2>Status</h2> <div class="flex"> <div> <article class="card"> <header> <h3>System</h3> </header> <div class="table"> <div class="row"> <span>Chip ID</span> <span><span class="postfill_chipid">N/A</span></span> </div> <div class="row"> <span>Hostname</span> <span><span class="postfill_hostname">N/A</span></span> </div> <div class="row"> <span>Firmware Version</span> <span>N/A</span> </div> <div class="row"> <span>Flash ID</span> <span><span class="postfill_flashid">N/A</span></span> </div> <div class="row"> <span>Flash size</span> <span><span class="postfill_flashsize">N/A</span> KiB</span> </div> <div class="row"> <span>Free heap</span> <span><span class="postfill_heap">N/A</span> bytes</span> </div> <div class="row"> <span>Uptime</span> <span><span class="postfill_uptime">N/A</span> s</span> </div> </div> </article> </div> <div> <article class="card"> <header> <h3>Network <span class="label success postfill_clientip">current connection</span></h3> </header> <div class="table"> <div class="row"> <span>Mode</span> <span><span class="postfill_opmode">N/A</span></span> </div> <div class="row"> <span>Station SSID</span> <span><span class="postfill_stassid">N/A</span></span> </div> <div class="row"> <span>Station IP</span> <span><span class="postfill_staip">N/A</span></span> </div> <div class="row"> <span>Station MAC</span> <span><span class="postfill_stamac">N/A</span></span> </div> <div class="row"> <span>AP SSID</span> <span><span class="postfill_apssid">N/A</span></span> </div> <div class="row"> <span>AP IP</span> <span><span class="postfill_apip">N/A</span></span> </div> <div class="row"> <span>AP MAC</span> <span><span class="postfill_apmac">N/A</span></span> </div> </div> </article> </div> <div> <article class="card"> <header> <h3>Power</h3> </header> <div class="table"> <div class="row"> <span>Input</span> <span><span class="label success">5V</span><span class="label success">12V</span></span> </div> <div class="row"> <span>Output</span> <span><span class="label warning"><span id="out_voltage">11.2</span>V</span></span> </div> </div> <canvas id="chartCanvas" style="height:100px"></canvas> </article> </div> <div> <article class="card"> <header> <h3>I/O</h3> </header> <footer> <label> <input type="checkbox" name="onoffswitch" id="led-switch" onclick="gpio()"> <span class="toggle button">toggle signal led</span> </label> </footer> </article> </div> </div> </section> </main> <div id="unused_values" style="display:none;"></div> <script type="text/javascript" src="js/smoothie_min.js"></script> <script> var menu = document.getElementById("bmenub"); var voltage = document.getElementById("out_voltage"); var unused_values = {}; DataView.prototype.setChar = function(pos, char) { this.setInt8(pos++, char.charCodeAt(0)); return pos; }; DataView.prototype.setString = function(pos, str) { for(var i = 0; i < str.length; i++) { this.setInt8(pos++, str.charCodeAt(i)); } this.setInt8(pos++, 0); return pos; }; var ws; var retries; var series = new TimeSeries(); function setMsg(cls, text) { sbox = document.getElementById('status_box'); sbox.className = "label " + cls; sbox.innerHTML = text; console.log(text); } function startPolling() { var chart = new SmoothieChart({ millisPerPixel: 111, grid: {fillStyle: '#ffffff', strokeStyle: '#ffffff', borderVisible: false}, labels: {fillStyle: '#000000'}, maxValue: 1024, minValue: 0 }); chart.addTimeSeries(series, {lineWidth: 2, strokeStyle: '#03a9f4', fillStyle: '#f1f5fa'}); var canvas = document.getElementById("chartCanvas"); canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; chart.streamTo(canvas, 500); } function onMessage(evt) { retries = 0; if (typeof evt.data == 'string') { var data = JSON.parse(evt.data); for (const [key, value] of Object.entries(data)) { const elements = document.querySelectorAll(".postfill_" + key); if (!elements.length) unused_values[key] = value; else for (i = 0; i < elements.length; ++i) { elements[i].innerHTML = value; } } document.getElementById("unused_values").innerHTML = JSON.stringify(unused_values); } else { var dv = new DataView(evt.data); var cmd = String.fromCharCode(dv.getUint8(0)); var val = dv.getUint16(1); if (cmd === 'G') console.log("LED switched", val); else if (cmd === 'V') { voltage.innerHTML = (val * 13 / 1024).toFixed(2); series.append(new Date().getTime(), val); } else console.log('unknown command', cmd, val); } } function wsOpen() { var uri = "/stream" if (ws === undefined || ws.readyState !== 0) { if (retries) setMsg("warning", "WebSocket timeout, retrying.."); else setMsg("primary", "Opening WebSocket.."); ws = new WebSocket("ws://" + location.host + uri); ws.binaryType = 'arraybuffer'; ws.onopen = function (evt) { retries = 0; setMsg("success", "WebSocket is open."); }; ws.onerror = function (evt) { console.error(evt); setMsg("error", "WebSocket error!"); /*window.location.reload(true);*/ }; ws.onmessage = function (evt) { onMessage(evt); }; retries = 0; } } function buf2hex(buffer) { // buffer is an ArrayBuffer return [...new Uint8Array(buffer)].map(x => x.toString(16).padStart(2, '0')).join(''); } function wsWrite(data) { console.info(buf2hex(data)); if (ws.readyState === 3 || retries++ > 5) wsOpen(); else if (ws.readyState === 1) ws.send(data); } function gpio() { if (document.getElementById('led-switch').checked) wsWrite('E'); else wsWrite('D'); } window.onload = function () { wsOpen(); startPolling(); } </script> </body> </html>