system status page

master
Ondřej Hruška 8 years ago
parent d41d080a70
commit 7df870c77c
  1. 7
      Makefile
  2. 6
      esp_meas.pro
  3. 2
      esp_meas.pro.user
  4. 10
      html/css/app.css
  5. 13
      html/js/all.js
  6. 84
      html/pages/home.tpl
  7. 11
      html/pages/wifi.tpl
  8. 6
      html_src/_start.php
  9. 10
      html_src/css/app.css
  10. 2
      html_src/css/app.css.map
  11. 2
      html_src/gulpfile.js
  12. 72
      html_src/home.php
  13. 11
      html_src/js-src/app.js
  14. 13
      html_src/js/all.js
  15. 1
      html_src/js/all.js.map
  16. 1
      html_src/js/all.min.js.map
  17. 1
      html_src/sass/app.scss
  18. 11
      html_src/sass/pages/_home.scss
  19. 1
      html_src/wifi.php
  20. 1
      libesphttpd/include/esp8266.h
  21. 16
      libesphttpd/util/cgiwifi.c
  22. 61
      user/cgi.c
  23. 2
      user/cgi.h
  24. 38
      user/uptime.c
  25. 13
      user/uptime.h
  26. 9
      user/user_main.c

@ -183,17 +183,18 @@ $1/%.o: %.S
$(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@
endef
.PHONY: all checkdirs clean libesphttpd default-tgt
.PHONY: all checkdirs clean libesphttpd default-tgt html
all: checkdirs htmlbuild $(TARGET_OUT) $(FW_BASE)
all: checkdirs $(TARGET_OUT) $(FW_BASE)
$(Q) echo -e "\nBuild OK.\n"
# libesphttpd/Makefile:
# $(Q) echo "No libesphttpd submodule found. Using git to fetch it..."
# $(Q) git submodule init
# $(Q) git submodule update
htmlbuild:
html:
$(vecho) "Building HTML..."
$(Q) ./html_build.sh

@ -49,7 +49,8 @@ SOURCES += \
sbmp/sbmp_frame.c \
sbmp/sbmp_session.c \
user/datalink.c \
user/serial.c
user/serial.c \
user/uptime.c
HEADERS += \
include/uart_hw.h \
@ -120,7 +121,8 @@ HEADERS += \
sbmp/sbmp_session.h \
user/datalink.h \
user/serial.h \
libesphttpd/include/logging.h
libesphttpd/include/logging.h \
user/uptime.h
DISTFILES += \
style.astylerc \

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.6.0, 2016-03-20T01:54:18. -->
<!-- Written by QtCreator 3.6.0, 2016-03-20T11:55:48. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

@ -1074,4 +1074,14 @@ label.select-wrap {
-ms-flex: 0 0 15%;
flex: 0 0 15%; }
.page-home #rssi-perc:after {
padding-left: 0.1459102934rem;
content: '%';
font-size: 0.8888888889em; }
.page-home #rssi-dbm:after {
padding-left: 0.1459102934rem;
content: 'dBm';
font-size: 0.8888888889em; }
/*# sourceMappingURL=app.css.map */

@ -27,6 +27,14 @@ function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
@ -122,6 +130,7 @@ var wifi = (function () {
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
@ -155,7 +164,7 @@ var wifi = (function () {
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(Math.round(ap.rssi / 2.55)))
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
@ -947,4 +956,4 @@ function initDef() {
}());
//# sourceMappingURL=all.min.js.map
//# sourceMappingURL=all.js.map

@ -9,16 +9,10 @@
<link href="/css/app.css" rel="stylesheet">
<!-- IE8 support (not tested) -->
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.7/es5-shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="/js/all.min.js"></script>
<script src="/js/all.js"></script>
</head>
<body>
<body class="page-home">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>
@ -27,7 +21,77 @@
<h1>System Status</h1>
<div class="Box">This page was shown %counter% times.</div>
<div class="Box">
<h2>Runtime</h2>
<table>
<tbody>
<tr>
<th>Uptime:</th>
<td>%uptime%</td>
</tr>
<tr>
<th>Free heap:</th>
<td>%heap% bytes</td>
</tr>
</tbody>
</table>
</div>
<div class="Box">
<h2>Wireless</h2>
<table>
<tbody>
<tr>
<th>WiFi mode:</th>
<td>%wifiMode%</td>
</tr>
<tr class="sta-only">
<th>SSID:</th>
<td>%staSSID%</td>
</tr>
<tr class="sta-only">
<th>RSSI:</th>
<td><span id="rssi-perc"></span>, <span id="rssi-dbm"></span></td>
</tr>
<tr>
<th>Client MAC:</th>
<td>%staMAC%</td>
</tr>
<tr>
<th>AP MAC:</th>
<td>%apMAC%</td>
</tr>
</tbody>
</table>
</div>
<div class="Box">
<h2>Hardware</h2>
<table>
<tbody>
<tr>
<th>ESP8266 S/N:</th>
<td>%chipID%</td>
</tr>
</tbody>
</table>
</div>
<script>
var wifiMode = '%wifiMode%';
var staRSSI = '%staRSSI%';
$().ready(function() {
if (wifiMode == 'SoftAP') {
$('.sta-only').hide();
} else {
$('#rssi-perc').html(rssiPerc(staRSSI));
$('#rssi-dbm').html(staRSSI);
}
setTimeout(function(){location.reload()}, 10000);
});
</script>
<script>
$().ready(initDef);

@ -9,16 +9,10 @@
<link href="/css/app.css" rel="stylesheet">
<!-- IE8 support (not tested) -->
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.7/es5-shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="/js/all.min.js"></script>
<script src="/js/all.js"></script>
</head>
<body>
<body class="page-wifi">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>
@ -40,7 +34,6 @@
</tr>
</tbody>
</table>
</div>
<div class="Box" id="ap-box">

@ -22,16 +22,18 @@ $appname = 'Current analyzer';
<link href="/css/app.css" rel="stylesheet">
<?php if(false): ?>
<!-- IE8 support (not tested) -->
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.7/es5-shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<?php endif; ?>
<script src="/js/all.min.js"></script>
<script src="/js/all.js"></script>
</head>
<body>
<body class="page-<?=$page?>">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current analyzer</div>

@ -1074,4 +1074,14 @@ label.select-wrap {
-ms-flex: 0 0 15%;
flex: 0 0 15%; }
.page-home #rssi-perc:after {
padding-left: 0.1459102934rem;
content: '%';
font-size: 0.8888888889em; }
.page-home #rssi-dbm:after {
padding-left: 0.1459102934rem;
content: 'dBm';
font-size: 0.8888888889em; }
/*# sourceMappingURL=app.css.map */

File diff suppressed because one or more lines are too long

@ -21,5 +21,5 @@ elixir(function (mix) {
mix.scripts([
'js-src/app.js',
'js-src/chibi.js'
], 'js/all.min.js');
], 'js/all.js');
});

@ -2,6 +2,76 @@
<h1>System Status</h1>
<div class="Box">This page was shown %counter% times.</div>
<div class="Box">
<h2>Runtime</h2>
<table>
<tbody>
<tr>
<th>Uptime:</th>
<td>%uptime%</td>
</tr>
<tr>
<th>Free heap:</th>
<td>%heap% bytes</td>
</tr>
</tbody>
</table>
</div>
<div class="Box">
<h2>Wireless</h2>
<table>
<tbody>
<tr>
<th>WiFi mode:</th>
<td>%wifiMode%</td>
</tr>
<tr class="sta-only">
<th>SSID:</th>
<td>%staSSID%</td>
</tr>
<tr class="sta-only">
<th>RSSI:</th>
<td><span id="rssi-perc"></span>, <span id="rssi-dbm"></span></td>
</tr>
<tr>
<th>Client MAC:</th>
<td>%staMAC%</td>
</tr>
<tr>
<th>AP MAC:</th>
<td>%apMAC%</td>
</tr>
</tbody>
</table>
</div>
<div class="Box">
<h2>Hardware</h2>
<table>
<tbody>
<tr>
<th>ESP8266 S/N:</th>
<td>%chipID%</td>
</tr>
</tbody>
</table>
</div>
<script>
var wifiMode = '%wifiMode%';
var staRSSI = '%staRSSI%';
$().ready(function() {
if (wifiMode == 'SoftAP') {
$('.sta-only').hide();
} else {
$('#rssi-perc').html(rssiPerc(staRSSI));
$('#rssi-dbm').html(staRSSI);
}
setTimeout(function(){location.reload()}, 10000);
});
</script>
<?php include "_end.php"; ?>

@ -27,6 +27,14 @@ function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
@ -122,6 +130,7 @@ var wifi = (function () {
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
@ -155,7 +164,7 @@ var wifi = (function () {
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(Math.round(ap.rssi / 2.55)))
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));

@ -27,6 +27,14 @@ function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
@ -122,6 +130,7 @@ var wifi = (function () {
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
@ -155,7 +164,7 @@ var wifi = (function () {
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(Math.round(ap.rssi / 2.55)))
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
@ -947,4 +956,4 @@ function initDef() {
}());
//# sourceMappingURL=all.min.js.map
//# sourceMappingURL=all.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -33,3 +33,4 @@ $c-form-highlight-a: #28bc65;
// import all our pages
@import "pages/wifi";
@import "pages/home";

@ -0,0 +1,11 @@
.page-home #rssi-perc:after {
padding-left: dist(-4);
content: '%';
font-size: fsize(-1);
}
.page-home #rssi-dbm:after {
padding-left: dist(-4);
content: 'dBm';
font-size: fsize(-1);
}

@ -16,7 +16,6 @@ include "_start.php"; ?>
</tr>
</tbody>
</table>
</div>
<div class="Box" id="ap-box">

@ -12,6 +12,7 @@
#else
#include <c_types.h>
#include <ip_addr.h>
#include <espconn.h>
#include <ets_sys.h>

@ -23,8 +23,8 @@ typedef struct {
char ssid[32];
char bssid[8];
int channel;
char rssi;
char enc;
sint8 rssi;
uint8 enc;
} ApData;
//Scan result
@ -118,9 +118,15 @@ int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
if (!cgiWifiAps.scanInProgress && pos!=0) {
//Fill in json code for an access point
if (pos-1<cgiWifiAps.noAps) {
len=sprintf(buff, "{\"essid\":\"%s\",\"bssid\":\"" MACSTR "\",\"rssi\":%d,\"enc\":%d,\"channel\":%d}%s",
cgiWifiAps.apData[pos-1]->ssid, MAC2STR(cgiWifiAps.apData[pos-1]->bssid), cgiWifiAps.apData[pos-1]->rssi,
cgiWifiAps.apData[pos-1]->enc, cgiWifiAps.apData[pos-1]->channel, (pos-1==cgiWifiAps.noAps-1) ? "" : ","); //<-terminator
len=sprintf(buff, "{\"essid\":\"%s\",\"bssid\":\""MACSTR"\",\"rssi\":%d,\"enc\":%d,\"channel\":%d}%s",
cgiWifiAps.apData[pos-1]->ssid,
MAC2STR(cgiWifiAps.apData[pos-1]->bssid),
cgiWifiAps.apData[pos-1]->rssi,
cgiWifiAps.apData[pos-1]->enc,
cgiWifiAps.apData[pos-1]->channel,
(pos-1==cgiWifiAps.noAps-1) ? "" : ","); //<-terminator
httpdSend(connData, buff, len);
}
pos++;

@ -15,25 +15,74 @@ flash as a binary. Also handles the hit counter on the main page.
#include <esp8266.h>
#include "cgi.h"
static long hitCounter = 0;
#include "uptime.h"
//Template code for the counter on the index page.
int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg)
int ICACHE_FLASH_ATTR tplHome(HttpdConnData *connData, char *token, void **arg)
{
struct station_config stconf;
char buff[128];
u8 mac[6];
// empty string if no token matches
buff[0] = 0;
if (token == NULL) return HTTPD_CGI_DONE;
if (os_strcmp(token, "counter") == 0) {
hitCounter++;
os_sprintf(buff, "%ld", hitCounter);
if (strcmp(token, "uptime") == 0) {
// Uptime
uptime_str(buff);
} else if (strcmp(token, "heap") == 0) {
// Free heap
sprintf(buff, "%u", system_get_free_heap_size());
} else if (strcmp(token, "wifiMode") == 0) {
// WiFi mode
switch (wifi_get_opmode()) {
case STATION_MODE: strcpy(buff, "Client"); break;
case SOFTAP_MODE: strcpy(buff, "SoftAP"); break;
case STATIONAP_MODE: strcpy(buff, "STA+AP"); break;
default: strcpy(buff, "Unknown");
}
} else if (strcmp(token, "staSSID") == 0) {
// Station SSID (if in station mode)
int opmode = wifi_get_opmode();
if (opmode != STATION_MODE && opmode != STATIONAP_MODE) {
strcpy(buff, "N/A"); // no SSID in AP-only mode
} else {
wifi_station_get_config(&stconf);
strcpy(buff, (char*)stconf.ssid);
}
} else if (strcmp(token, "staRSSI") == 0) {
// Signal strength if in Station mode
int rssi = wifi_station_get_rssi();
sprintf(buff, "%d", rssi);
} else if (strcmp(token, "staMAC") == 0) {
// Station MAC addr
wifi_get_macaddr(STATION_IF, mac);
sprintf(buff, MACSTR, MAC2STR(mac));
} else if (strcmp(token, "apMAC") == 0) {
// SoftAP MAC addr
wifi_get_macaddr(SOFTAP_IF, mac);
sprintf(buff, MACSTR, MAC2STR(mac));
} else if (strcmp(token, "chipID") == 0) {
// Chip serial number
sprintf(buff, "%08x", system_get_chip_id());
}
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
// ----
typedef struct {
uint32_t count_remain;

@ -4,7 +4,7 @@
#include <esp8266.h>
#include "httpd.h"
int tplCounter(HttpdConnData *connData, char *token, void **arg);
int tplHome(HttpdConnData *connData, char *token, void **arg);
//int cgiRandomNumbers(HttpdConnData *connData);

@ -0,0 +1,38 @@
#include <esp8266.h>
volatile uint32_t uptime = 0;
static ETSTimer prUptimeTimer;
static void uptimeTimerCb(void *arg)
{
uptime++;
}
void uptime_timer_init(void)
{
os_timer_disarm(&prUptimeTimer);
os_timer_setfn(&prUptimeTimer, uptimeTimerCb, NULL);
os_timer_arm(&prUptimeTimer, 1000, 1);
}
void uptime_str(char *buf)
{
u32 a = uptime;
u32 days = a / 86400;
a -= days * 86400;
u32 hours = a / 3600;
a -= hours * 3600;
u32 mins = a / 60;
a -= mins * 60;
u32 secs = a;
if (days > 0) {
sprintf(buf, "%ud %02u:%02u:%02u", days, hours, mins, secs);
} else {
sprintf(buf, "%02u:%02u:%02u", hours, mins, secs);
}
}

@ -0,0 +1,13 @@
#ifndef UPTIME_H
#define UPTIME_H
#include <esp8266.h>
extern volatile uint32_t uptime;
void uptime_timer_init(void);
/** Print uptime to a buffer. Should be at least 20 long. */
void uptime_str(char *buf);
#endif // UPTIME_H

@ -25,6 +25,7 @@
#include "io.h"
#include "datalink.h"
#include "uart_driver.h"
#include "uptime.h"
#include "sbmp.h"
@ -34,7 +35,10 @@
static ETSTimer prHeapTimer;
static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) {
os_printf("Heap: %ld\n", (unsigned long)system_get_free_heap_size());
u32 heap = system_get_free_heap_size();
char upt[20];
uptime_str(upt);
os_printf("Uptime: %s, Heap: %u\n", upt, heap);
}
#endif
@ -112,7 +116,7 @@ CgiUploadFlashDef uploadParams = {
static HttpdBuiltInUrl builtInUrls[] = {
ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"), // redirect func for the captive portal
ROUTE_TPL_FILE("/", tplCounter, "/pages/home.tpl"),
ROUTE_TPL_FILE("/", tplHome, "/pages/home.tpl"),
ROUTE_TPL_FILE("/multipart", tplMultipart, "/multipart.tpl"),
@ -151,6 +155,7 @@ void user_init(void)
{
// set up the debuging output
serialInit();
uptime_timer_init();
banner("\n*** ESP8266 starting, "
"HTTPD v."HTTPDVER", "

Loading…
Cancel
Save