add system name & description to home page

pull/69/head
Thorsten von Eicken 9 years ago
parent 14e206eb3f
commit 86d6638e53
  1. 4
      esp-link/cgi.c
  2. 4
      esp-link/cgimqtt.c
  3. 1
      esp-link/cgimqtt.h
  4. 1
      esp-link/config.c
  5. 1
      esp-link/config.h
  6. 54
      esp-link/main.c
  7. 37
      html/home.html
  8. 6
      html/style.css
  9. 49
      html/ui.js
  10. 8
      httpd/httpd.c

@ -16,6 +16,7 @@ Some random cgi routines.
#include <esp8266.h> #include <esp8266.h>
#include "cgi.h" #include "cgi.h"
#include "config.h"
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
noCacheHeaders(HttpdConnData *connData, int code) { noCacheHeaders(HttpdConnData *connData, int code) {
@ -158,7 +159,8 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) {
"\"REST/MQTT\", \"/mqtt.html\"," "\"REST/MQTT\", \"/mqtt.html\","
#endif #endif
"\"Debug log\", \"/log.html\" ],\n" "\"Debug log\", \"/log.html\" ],\n"
" \"version\": \"%s\" }", esp_link_version); " \"version\": \"%s\","
"\"name\":\"%s\"}", esp_link_version, flashConfig.sys_name);
httpdSend(connData, buff, -1); httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }

@ -11,6 +11,10 @@ static char *mqtt_states[] = {
"disconnected", "reconnecting", "connecting", "connected", "disconnected", "reconnecting", "connecting", "connected",
}; };
char *mqttState(void) {
return mqtt_states[mqttClient.connState];
}
// Cgi to return MQTT settings // Cgi to return MQTT settings
int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) {
char buff[1024]; char buff[1024];

@ -4,6 +4,7 @@
#include "httpd.h" #include "httpd.h"
int cgiMqtt(HttpdConnData *connData); int cgiMqtt(HttpdConnData *connData);
char *mqttState(void);
#endif // CGIMQTT_H #endif // CGIMQTT_H
#endif // MQTT #endif // MQTT

@ -22,6 +22,7 @@ FlashConfig flashDefault = {
2, 1, // mqtt_timeout, mqtt_clean_session 2, 1, // mqtt_timeout, mqtt_clean_session
1883, 60, // mqtt port, mqtt_keepalive 1883, 60, // mqtt port, mqtt_keepalive
"\0", "\0", "\0", "\0", "\0", // mqtt host, client_id, user, password, status-topic "\0", "\0", "\0", "\0", "\0", // mqtt host, client_id, user, password, status-topic
"\0", "\0", // sys name, sys description
}; };
typedef union { typedef union {

@ -23,6 +23,7 @@ typedef struct {
uint16_t mqtt_port, mqtt_keepalive; // MQTT Host port, MQTT Keepalive timer uint16_t mqtt_port, mqtt_keepalive; // MQTT Host port, MQTT Keepalive timer
char mqtt_host[32], mqtt_clientid[48], mqtt_username[32], mqtt_password[32]; char mqtt_host[32], mqtt_clientid[48], mqtt_username[32], mqtt_password[32];
char mqtt_status_topic[32]; char mqtt_status_topic[32];
char sys_name[12], sys_descr[128]; // informal system name and description
} FlashConfig; } FlashConfig;
extern FlashConfig flashConfig; extern FlashConfig flashConfig;

@ -31,6 +31,9 @@
#include "log.h" #include "log.h"
#include <gpio.h> #include <gpio.h>
static int ICACHE_FLASH_ATTR cgiSystemInfo(HttpdConnData *connData);
static int ICACHE_FLASH_ATTR cgiSystemSet(HttpdConnData *connData);
/* /*
This is the main url->function dispatching data struct. This is the main url->function dispatching data struct.
In short, it's a struct with various URLs plus their handlers. The handlers can In short, it's a struct with various URLs plus their handlers. The handlers can
@ -64,8 +67,9 @@ HttpdBuiltInUrl builtInUrls[] = {
{ "/wifi/connstatus", cgiWiFiConnStatus, NULL }, { "/wifi/connstatus", cgiWiFiConnStatus, NULL },
{ "/wifi/setmode", cgiWiFiSetMode, NULL }, { "/wifi/setmode", cgiWiFiSetMode, NULL },
{ "/wifi/special", cgiWiFiSpecial, NULL }, { "/wifi/special", cgiWiFiSpecial, NULL },
{ "/system/info", cgiSystemInfo, NULL },
{ "/system/update", cgiSystemSet, NULL },
{ "/pins", cgiPins, NULL }, { "/pins", cgiPins, NULL },
{ "/tcpclient", cgiTcp, NULL },
#ifdef MQTT #ifdef MQTT
{ "/mqtt", cgiMqtt, NULL }, { "/mqtt", cgiMqtt, NULL },
#endif #endif
@ -97,6 +101,53 @@ static char *flash_maps[] = {
"2MB:1024/1024", "4MB:1024/1024" "2MB:1024/1024", "4MB:1024/1024"
}; };
// Cgi to return various System information
static int ICACHE_FLASH_ATTR cgiSystemInfo(HttpdConnData *connData) {
char buff[1024];
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
uint8 part_id = system_upgrade_userbin_check();
uint32_t fid = spi_flash_get_id();
struct rst_info *rst_info = system_get_rst_info();
os_sprintf(buff, "{\"name\": \"%s\", \"reset cause\": \"%d=%s\", "
"\"size\": \"%s\"," "\"id\": \"0x%02lX 0x%04lX\"," "\"partition\": \"%s\","
"\"slip\": \"%s\"," "\"mqtt\": \"%s/%s\"," "\"baud\": \"%ld\","
"\"description\": \"%s\"" "}",
flashConfig.sys_name, rst_info->reason, rst_codes[rst_info->reason],
flash_maps[system_get_flash_size_map()], fid & 0xff, (fid&0xff00)|((fid>>16)&0xff),
part_id ? "user2.bin" : "user1.bin",
flashConfig.slip_enable ? "enabled" : "disabled",
flashConfig.mqtt_enable ? "enabled" : "disabled",
mqttState(), flashConfig.baud_rate, flashConfig.sys_descr
);
jsonHeader(connData, 200);
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
// Cgi to update system info (name/description)
static int ICACHE_FLASH_ATTR cgiSystemSet(HttpdConnData *connData) {
if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
int8_t status = 0;
status |= getStringArg(connData, "name", flashConfig.sys_name, sizeof(flashConfig.sys_name));
status |= getStringArg(connData, "description", flashConfig.sys_descr, sizeof(flashConfig.sys_descr));
if (status < 0) return HTTPD_CGI_DONE; // getStringArg has produced an error response
if (configSave()) {
httpdStartResponse(connData, 204);
httpdEndHeaders(connData);
} else {
httpdStartResponse(connData, 500);
httpdEndHeaders(connData);
httpdSend(connData, "Failed to save config", -1);
}
return HTTPD_CGI_DONE;
}
extern void app_init(void); extern void app_init(void);
extern void mqtt_client_init(void); extern void mqtt_client_init(void);
@ -120,6 +171,7 @@ void user_init(void) {
os_delay_us(10000L); os_delay_us(10000L);
os_printf("\n\n** %s\n", esp_link_version); os_printf("\n\n** %s\n", esp_link_version);
os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*");
if (flashConfig.sys_name[0] == 0) os_strcpy(flashConfig.sys_name, "nameme");
#if defined(STA_SSID) && defined(STA_PASS) #if defined(STA_SSID) && defined(STA_PASS)
int x = wifi_get_opmode() & 0x3; int x = wifi_get_opmode() & 0x3;

@ -8,21 +8,20 @@
<div class="content"> <div class="content">
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-1"><div class="card"> <div class="pure-u-1"><div class="card">
<p>The JeeLabs esp-link firmware bridges the ESP8266 serial port to Wifi and can <p style="margin-bottom:0;">The JeeLabs esp-link firmware bridges the ESP8266
serial port to Wifi and can
program microcontrollers over the serial port, in particular Arduinos, AVRs, and program microcontrollers over the serial port, in particular Arduinos, AVRs, and
NXP's LPC800 and other ARM processors.</p> NXP's LPC800 and other ARM processors. Typical avrdude command line to
<p style="margin-bottom:0;">Program an Arduino/AVR using avrdude using a command program an Arduino:</p>
line similar to:</p> <div class="tt">/home/arduino/hardware/tools/avrdude \<br>
<div class="tt">/home/arduino-1.0.5/hardware/tools/avrdude \<br>
&nbsp;&nbsp;-DV -patmega328p -Pnet:esp-link.local:23 -carduino -b115200 -U \<br> &nbsp;&nbsp;-DV -patmega328p -Pnet:esp-link.local:23 -carduino -b115200 -U \<br>
&nbsp;&nbsp;-C /home/arduino-1.0.5/hardware/tools/avrdude.conf flash:w:my_sketch.hex:i &nbsp;&nbsp;-C /home/arduino/hardware/tools/avrdude.conf flash:w:my_sketch.hex:i
</div> </div>
<p>where <tt>-Pnet:esp-link.local:23</tt> tells avrdude to connect to port 23 of esp-link. <p>where <tt>-Pnet:esp-link.local:23</tt> tells avrdude to connect to port 23 of esp-link.
You can substitute the IP address of your esp-link for esp-link.local if necessary.</p> You can substitute the IP address of your esp-link for esp-link.local if necessary.
<p>Please refer to Please refer to
<a href="https://github.com/jeelabs/esp-link/blob/master/README.md">the online README</a> <a href="https://github.com/jeelabs/esp-link/blob/master/README.md">the online README</a>
for up-to-date help and to the forthcoming for up-to-date help.</p>
<a href="http://jeelabs.org">JeeLabs blog</a> for an intro to the codebase.</p>
</div></div> </div></div>
</div> </div>
<div class="pure-g"> <div class="pure-g">
@ -39,6 +38,21 @@
<tr><td>Configured hostname</td><td id="wifi-hostname"></td></tr> <tr><td>Configured hostname</td><td id="wifi-hostname"></td></tr>
</tbody></table> </tbody></table>
</div> </div>
<div class="card">
<h1>Esp-link summary</h1>
<div id="system-spinner" class="spinner spinner-small"></div>
<table id="system-table" class="pure-table pure-table-horizontal" hidden><tbody>
<tr><td>Name</td><td><input type=text maxlength=12 disabled id="system-name"></td></tr>
<tr><td>Flash chip ID</td><td id="system-id"></td></tr>
<tr><td>Flash size</td><td id="system-size"></td></tr>
<tr><td>Current partition</td><td id="system-partition"></td></tr>
<tr><td>SLIP status</td><td id="system-slip"></td></tr>
<tr><td>MQTT status</td><td id="system-mqtt"></td></tr>
<tr><td>Serial baud</td><td id="system-baud"></td></tr>
<tr><td colspan=2 >Description:<br>
<textarea rows=3 maxlength=127 disabled id="system-description"></textarea></td></tr>
</tbody></table>
</div>
</div> </div>
<div class="pure-u-1 pure-u-md-1-2"><div class="card"> <div class="pure-u-1 pure-u-md-1-2"><div class="card">
<h1>Pin assignment</h1> <h1>Pin assignment</h1>
@ -56,8 +70,11 @@
<script type="text/javascript"> <script type="text/javascript">
onLoad(function() { onLoad(function() {
makeAjaxInput("system", "name");
makeAjaxInput("system", "description");
fetchPins(); fetchPins();
getWifiInfo(); getWifiInfo();
getSystemInfo();
}); });
</script> </script>
</body></html> </body></html>

@ -3,10 +3,14 @@ html, button, input, select, textarea, .pure-g [class *= "pure-u"] {
font-family: sans-serif; font-family: sans-serif;
} }
input[type="text"], input[type="password"] { input[type="text"], input[type="password"], textarea {
width: 100%; width: 100%;
} }
input[type="text"]:disabled, textarea:disabled {
cursor: pointer;
}
input[type=checkbox] { input[type=checkbox] {
float: left; float: left;
margin: .35em 0.4em; margin: .35em 0.4em;

@ -226,6 +226,7 @@ onLoad(function() {
<div class="pure-menu">\ <div class="pure-menu">\
<a class="pure-menu-heading" href="https://github.com/jeelabs/esp-link">\ <a class="pure-menu-heading" href="https://github.com/jeelabs/esp-link">\
<img src="/favicon.ico" height="32">&nbsp;esp-link</a>\ <img src="/favicon.ico" height="32">&nbsp;esp-link</a>\
<div class="pure-menu-heading" id="sysname" style="padding: 0px 0.6em"></div>\
<ul id="menu-list" class="pure-menu-list"></ul>\ <ul id="menu-list" class="pure-menu-list"></ul>\
</div>\ </div>\
</div>\ </div>\
@ -258,6 +259,9 @@ onLoad(function() {
v = $("#version"); v = $("#version");
if (v != null) { v.innerHTML = data.version; } if (v != null) { v.innerHTML = data.version; }
n = $("#sysname");
if (n != null) { n.innerHTML = data.name; }
}, function() { setTimeout(getMenu, 1000); }); }, function() { setTimeout(getMenu, 1000); });
}; };
getMenu(); getMenu();
@ -285,6 +289,51 @@ function getWifiInfo() {
function(s, st) { window.setTimeout(getWifiInfo, 1000); }); function(s, st) { window.setTimeout(getWifiInfo, 1000); });
} }
//===== System info
function showSystemInfo(data) {
Object.keys(data).forEach(function(v) {
el = $("#system-" + v);
if (el != null) {
if (el.nodeName === "INPUT") el.value = data[v];
else el.innerHTML = data[v];
}
});
$("#system-spinner").setAttribute("hidden", "");
$("#system-table").removeAttribute("hidden");
currAp = data.ssid;
}
function getSystemInfo() {
ajaxJson('GET', "/system/info", showSystemInfo,
function(s, st) { window.setTimeout(getSystemInfo, 1000); });
}
function enableInput(el) {
el.disabled = false;
el.select();
return false;
}
function submitInput(klass, id, v) {
console.log("Submit POST /"+klass+"/update?"+id+"="+v);
$("#"+klass+"-"+id).disabled = true;
ajaxSpin("POST", "/"+klass+"/update?"+id+"="+v, function() {
showNotification(id + " changed to " + v);
}, function() {
showWarning(id + " change failed");
});
return false;
}
function makeAjaxInput(klass, field) {
var el = $("#"+klass+"-"+field);
bnd(el.parentElement, "click", function(){return enableInput(el);});
bnd(el, "blur", function(){return submitInput(klass,field,el.value);});
bnd(el, "keyup", function(ev){
if ((ev||window.event).keyCode==13) return submitInput(klass,field,el.value);
});
}
//===== Notifications //===== Notifications
function showWarning(text) { function showWarning(text) {

@ -17,6 +17,8 @@ Esp8266 http server - core routines
#include <esp8266.h> #include <esp8266.h>
#include "httpd.h" #include "httpd.h"
#define HTTPD_DBG
//Max length of request head //Max length of request head
#define MAX_HEAD_LEN 1024 #define MAX_HEAD_LEN 1024
@ -394,9 +396,13 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
if (conn->post) conn->post->len = 0; // skip any remaining receives if (conn->post) conn->post->len = 0; // skip any remaining receives
return; return;
} }
else if (r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED) { else {
if (!(r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED)) {
os_printf("%shandler for %s returned invalid result %d\n", connStr, conn->url, r);
}
//URL doesn't want to handle the request: either the data isn't found or there's no //URL doesn't want to handle the request: either the data isn't found or there's no
//need to generate a login screen. //need to generate a login screen.
conn->cgi = NULL; // force lookup again
i++; //look at next url the next iteration of the loop. i++; //look at next url the next iteration of the loop.
} }
} }

Loading…
Cancel
Save