mirror of https://github.com/jeelabs/esp-link.git
commit
60d3dbfa33
@ -0,0 +1,14 @@ |
||||
* Install [SourceTree](https://www.sourcetreeapp.com) and check CLI git or other git distribution to obtain git from CLI |
||||
* Install the latest Java JRE |
||||
* Install Python 2.7 to C:\Python27 |
||||
* Install link shell extension from [here](http://schinagl.priv.at/nt/hardlinkshellext/linkshellextension.html) |
||||
* Download and install the [Windows Unofficial Development Kit for Espressif ESP8266](http://programs74.ru/get.php?file=EspressifESP8266DevKit) to c:\espressif |
||||
* Create a symbolic link for java/bin and git/bin directories under C:\espressif\git-bin and C:\espressif\java-bin. You must do this because "make" doesn't work properly with paths like "program files(x86)". You can see all the expected paths in the [espmake.cmd](https://github.com/jeelabs/esp-link/blob/master/espmake.cmd) |
||||
* [Download](http://sourceforge.net/projects/mingw/files/Installer/) and install MinGW. Run mingw-get-setup.exe. During the installation process select without GUI. (uncheck "... also install support for the graphical user interface") |
||||
* [Download](http://programs74.ru/get.php?file=EspressifESP8266DevKitAddon) the scripts to automate the installation of additional modules for MinGW. |
||||
* Run install-mingw-package.bat. This will install the basic modules required for MinGW to build esp8266. |
||||
* Checkout esp-link from git to C:\espressif\esp-link |
||||
* When you're done open a command prompt and run: espmake.cmd "make all wiflash" |
||||
* For a new flash over serial use: espmake.cmd "make all flash" |
||||
* If you want to program with serial but not loose your config each time use: espmake.cmd "make all baseflash" |
||||
* You can open the esp-link.sln file in Visual Studio 2013. "Build Solution" will issue "make all wiflash". "Clean Solution" will issue "make clean". "Rebuild Solution" will issue "make clean all". This can be changed under solution properties -> Configuration Properties -> NMake |
@ -1,10 +1,10 @@ |
||||
char *mqttState(void); |
||||
#ifdef MQTT |
||||
#ifndef CGIMQTT_H |
||||
#define CGIMQTT_H |
||||
|
||||
#include "httpd.h" |
||||
int cgiMqtt(HttpdConnData *connData); |
||||
char *mqttState(void); |
||||
|
||||
#endif // CGIMQTT_H
|
||||
#endif // MQTT
|
||||
|
@ -0,0 +1,216 @@ |
||||
#include <esp8266.h> |
||||
#include "cgiwifi.h" |
||||
#include "cgi.h" |
||||
#include "config.h" |
||||
#include "syslog.h" |
||||
#include "sntp.h" |
||||
#include "cgimqtt.h" |
||||
|
||||
#ifdef CGISERVICES_DBG |
||||
#define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0) |
||||
#else |
||||
#define DBG(format, ...) do { } while(0) |
||||
#endif |
||||
|
||||
char* rst_codes[7] = { |
||||
"normal", "wdt reset", "exception", "soft wdt", "restart", "deep sleep", "external", |
||||
}; |
||||
|
||||
char* flash_maps[7] = { |
||||
"512KB:256/256", "256KB", "1MB:512/512", "2MB:512/512", "4MB:512/512", |
||||
"2MB:1024/1024", "4MB:1024/1024" |
||||
}; |
||||
|
||||
static ETSTimer reassTimer; |
||||
|
||||
// Cgi to update system info (name/description)
|
||||
int ICACHE_FLASH_ATTR cgiSystemSet(HttpdConnData *connData) { |
||||
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
|
||||
|
||||
int8_t n = getStringArg(connData, "name", flashConfig.hostname, sizeof(flashConfig.hostname)); |
||||
int8_t d = getStringArg(connData, "description", flashConfig.sys_descr, sizeof(flashConfig.sys_descr)); |
||||
|
||||
if (n < 0 || d < 0) return HTTPD_CGI_DONE; // getStringArg has produced an error response
|
||||
|
||||
if (n > 0) { |
||||
// schedule hostname change-over
|
||||
os_timer_disarm(&reassTimer); |
||||
os_timer_setfn(&reassTimer, configWifiIP, NULL); |
||||
os_timer_arm(&reassTimer, 1000, 0); // 1 second for the response of this request to make it
|
||||
} |
||||
|
||||
if (configSave()) { |
||||
httpdStartResponse(connData, 204); |
||||
httpdEndHeaders(connData); |
||||
} |
||||
else { |
||||
httpdStartResponse(connData, 500); |
||||
httpdEndHeaders(connData); |
||||
httpdSend(connData, "Failed to save config", -1); |
||||
} |
||||
return HTTPD_CGI_DONE; |
||||
} |
||||
|
||||
// Cgi to return various System information
|
||||
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.hostname, |
||||
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; |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR cgiServicesSNTPInit() { |
||||
if (flashConfig.sntp_server[0] != '\0') {
|
||||
sntp_stop(); |
||||
if (true == sntp_set_timezone(flashConfig.timezone_offset)) { |
||||
sntp_setservername(0, flashConfig.sntp_server);
|
||||
sntp_init(); |
||||
} |
||||
DBG("SNTP timesource set to %s with offset %d\n", flashConfig.sntp_server, flashConfig.timezone_offset); |
||||
} |
||||
} |
||||
|
||||
int ICACHE_FLASH_ATTR cgiServicesInfo(HttpdConnData *connData) { |
||||
char buff[1024]; |
||||
|
||||
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
|
||||
|
||||
os_sprintf(buff,
|
||||
"{ " |
||||
"\"syslog_host\": \"%s\", " |
||||
"\"syslog_minheap\": %d, " |
||||
"\"syslog_filter\": %d, " |
||||
"\"syslog_showtick\": \"%s\", " |
||||
"\"syslog_showdate\": \"%s\", " |
||||
"\"timezone_offset\": %d, " |
||||
"\"sntp_server\": \"%s\", " |
||||
"\"mdns_enable\": \"%s\", " |
||||
"\"mdns_servername\": \"%s\"" |
||||
" }",
|
||||
flashConfig.syslog_host, |
||||
flashConfig.syslog_minheap, |
||||
flashConfig.syslog_filter, |
||||
flashConfig.syslog_showtick ? "enabled" : "disabled", |
||||
flashConfig.syslog_showdate ? "enabled" : "disabled", |
||||
flashConfig.timezone_offset, |
||||
flashConfig.sntp_server, |
||||
flashConfig.mdns_enable ? "enabled" : "disabled", |
||||
flashConfig.mdns_servername |
||||
); |
||||
|
||||
jsonHeader(connData, 200); |
||||
httpdSend(connData, buff, -1); |
||||
return HTTPD_CGI_DONE; |
||||
} |
||||
|
||||
int ICACHE_FLASH_ATTR cgiServicesSet(HttpdConnData *connData) { |
||||
if (connData->conn == NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
|
||||
|
||||
int8_t syslog = 0; |
||||
|
||||
syslog |= getStringArg(connData, "syslog_host", flashConfig.syslog_host, sizeof(flashConfig.syslog_host)); |
||||
if (syslog < 0) return HTTPD_CGI_DONE; |
||||
syslog |= getUInt16Arg(connData, "syslog_minheap", &flashConfig.syslog_minheap); |
||||
if (syslog < 0) return HTTPD_CGI_DONE; |
||||
syslog |= getUInt8Arg(connData, "syslog_filter", &flashConfig.syslog_filter); |
||||
if (syslog < 0) return HTTPD_CGI_DONE; |
||||
syslog |= getBoolArg(connData, "syslog_showtick", &flashConfig.syslog_showtick); |
||||
if (syslog < 0) return HTTPD_CGI_DONE; |
||||
syslog |= getBoolArg(connData, "syslog_showdate", &flashConfig.syslog_showdate); |
||||
if (syslog < 0) return HTTPD_CGI_DONE; |
||||
|
||||
if (syslog > 0) { |
||||
syslog_init(flashConfig.syslog_host); |
||||
} |
||||
|
||||
int8_t sntp = 0; |
||||
sntp |= getInt8Arg(connData, "timezone_offset", &flashConfig.timezone_offset); |
||||
if (sntp < 0) return HTTPD_CGI_DONE; |
||||
sntp |= getStringArg(connData, "sntp_server", flashConfig.sntp_server, sizeof(flashConfig.sntp_server)); |
||||
if (sntp < 0) return HTTPD_CGI_DONE; |
||||
|
||||
if (sntp > 0) { |
||||
cgiServicesSNTPInit(); |
||||
} |
||||
|
||||
int8_t mdns = 0; |
||||
mdns |= getBoolArg(connData, "mdns_enable", &flashConfig.mdns_enable); |
||||
if (mdns < 0) return HTTPD_CGI_DONE; |
||||
|
||||
if (mdns > 0) { |
||||
if (flashConfig.mdns_enable){ |
||||
DBG("Services: MDNS Enabled\n"); |
||||
struct ip_info ipconfig; |
||||
wifi_get_ip_info(STATION_IF, &ipconfig); |
||||
|
||||
if (wifiState == wifiGotIP && ipconfig.ip.addr != 0) { |
||||
wifiStartMDNS(ipconfig.ip); |
||||
} |
||||
} |
||||
else { |
||||
DBG("Services: MDNS Disabled\n"); |
||||
espconn_mdns_server_unregister(); |
||||
espconn_mdns_close(); |
||||
mdns_started = true; |
||||
} |
||||
} |
||||
else { |
||||
mdns |= getStringArg(connData, "mdns_servername", flashConfig.mdns_servername, sizeof(flashConfig.mdns_servername)); |
||||
if (mdns < 0) return HTTPD_CGI_DONE; |
||||
|
||||
if (mdns > 0 && mdns_started) { |
||||
DBG("Services: MDNS Servername Updated\n"); |
||||
espconn_mdns_server_unregister(); |
||||
espconn_mdns_close(); |
||||
struct ip_info ipconfig; |
||||
wifi_get_ip_info(STATION_IF, &ipconfig); |
||||
|
||||
if (wifiState == wifiGotIP && ipconfig.ip.addr != 0) { |
||||
wifiStartMDNS(ipconfig.ip); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (configSave()) { |
||||
httpdStartResponse(connData, 204); |
||||
httpdEndHeaders(connData); |
||||
} |
||||
else { |
||||
httpdStartResponse(connData, 500); |
||||
httpdEndHeaders(connData); |
||||
httpdSend(connData, "Failed to save config", -1); |
||||
} |
||||
return HTTPD_CGI_DONE; |
||||
} |
@ -0,0 +1,16 @@ |
||||
#ifndef CGISERVICES_H |
||||
#define CGISERVICES_H |
||||
|
||||
#include "httpd.h" |
||||
|
||||
int cgiSystemSet(HttpdConnData *connData); |
||||
int cgiSystemInfo(HttpdConnData *connData); |
||||
|
||||
void cgiServicesSNTPInit(); |
||||
int cgiServicesInfo(HttpdConnData *connData); |
||||
int cgiServicesSet(HttpdConnData *connData); |
||||
|
||||
extern char* rst_codes[7]; |
||||
extern char* flash_maps[7]; |
||||
|
||||
#endif // CGISERVICES_H
|
@ -0,0 +1,106 @@ |
||||
<div id="main"> |
||||
<div class="header"> |
||||
<h1>Services</h1> |
||||
</div> |
||||
|
||||
<div class="content"> |
||||
<div class="pure-g"> |
||||
<div class="pure-u-1 pure-u-md-1-2"> |
||||
<div class="card"> |
||||
<h1> |
||||
Syslog |
||||
<div id="syslog-spinner" class="spinner spinner-small"></div> |
||||
</h1> |
||||
<form action="#" id="Syslog-form" class="pure-form" hidden> |
||||
<legend>Syslog settings</legend> |
||||
<div class="pure-form-stacked"> |
||||
<label>Syslog Host</label> |
||||
<input type="text" name="syslog_host" /> |
||||
<div class="popup">Use server [hostname:port] as UDP Syslog server</div> |
||||
</div> |
||||
<div class="pure-form-stacked"> |
||||
<label>Min Heap</label> |
||||
<input type="text" name="syslog_minheap" /> |
||||
<label>Filter</label> |
||||
<select name="syslog_filter" href="#"> |
||||
<option value="0">EMERG</option> |
||||
<option value="1">ALERT</option> |
||||
<option value="2">CRIT</option> |
||||
<option value="3">ERR</option> |
||||
<option value="4">WARNING</option> |
||||
<option value="5">NOTICE</option> |
||||
<option value="6">INFO</option> |
||||
<option value="7">DEBUG</option> |
||||
</select> |
||||
</div> |
||||
<div class="form-horizontal"> |
||||
<label>Show ESP µC Ticker in log message</label> |
||||
<input type="checkbox" name="syslog_showtick" /> |
||||
</div> |
||||
<div class="form-horizontal"> |
||||
<label>Show date in log message</label> |
||||
<input type="checkbox" name="syslog_showdate" /> |
||||
<div class="popup">Synology does a log rotate if timestamp is in the past so disable to prevent this</div> |
||||
</div> |
||||
<button id="Syslog-button" type="submit" class="pure-button button-primary"> |
||||
Update Syslog settings! |
||||
</button> |
||||
</form> |
||||
</div> |
||||
<div class="card"> |
||||
<h1> |
||||
mDNS |
||||
<div id="mdns-spinner" class="spinner spinner-small"></div> |
||||
</h1> |
||||
<form action="#" id="mDNS-form" class="pure-form" hidden> |
||||
<div class="form-horizontal"> |
||||
<input type="checkbox" name="mdns_enable"/> |
||||
<label>Enable mDNS</label> |
||||
</div> |
||||
<br> |
||||
<legend>mDNS server settings</legend> |
||||
<div class="pure-form-stacked"> |
||||
<label>Server Name</label> |
||||
<input type="text" name="mdns_servername"/> |
||||
</div> |
||||
<button id="mDNS-button" type="submit" class="pure-button button-primary"> |
||||
Update mDNS settings! |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
<div class="pure-u-1 pure-u-md-1-2"> |
||||
<div class="card"> |
||||
<h1> |
||||
SNTP |
||||
<div id="sntp-spinner" class="spinner spinner-small"></div> |
||||
</h1> |
||||
<form action="#" id="SNTP-form" class="pure-form" hidden> |
||||
<legend>SNTP server settings</legend> |
||||
<div class="pure-form-stacked"> |
||||
<label>Timezone Offset</label> |
||||
<input type="text" name="timezone_offset" /> |
||||
<label>SNTP Server</label> |
||||
<input type="text" name="sntp_server" /> |
||||
</div> |
||||
<button id="SNTP-button" type="submit" class="pure-button button-primary"> |
||||
Update SNTP settings! |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<script src="services.js"></script> |
||||
<script type="text/javascript"> |
||||
onLoad(function() { |
||||
fetchServices(); |
||||
bnd($("#Syslog-form"), "submit", changeServices); |
||||
bnd($("#SNTP-form"), "submit", changeServices); |
||||
bnd($("#mDNS-form"), "submit", changeServices); |
||||
}); |
||||
</script> |
||||
</body></html> |
@ -0,0 +1,77 @@ |
||||
function changeServices(e) { |
||||
e.preventDefault(); |
||||
var url = "services/update?1=1"; |
||||
var i, inputs = document.querySelectorAll("#" + e.target.id + " input,select"); |
||||
for (i = 0; i < inputs.length; i++) { |
||||
if (inputs[i].type == "checkbox") { |
||||
if (inputs[i].name.slice(-6) == "enable") |
||||
continue; |
||||
var val = (inputs[i].checked) ? 1 : 0; |
||||
url += "&" + inputs[i].name + "=" + val; |
||||
} |
||||
else |
||||
url += "&" + inputs[i].name + "=" + inputs[i].value; |
||||
}; |
||||
|
||||
hideWarning(); |
||||
var n = e.target.id.replace("-form", ""); |
||||
var cb = $("#" + n + "-button"); |
||||
addClass(cb, "pure-button-disabled"); |
||||
ajaxSpin("POST", url, function (resp) { |
||||
showNotification(n + " updated"); |
||||
removeClass(cb, "pure-button-disabled"); |
||||
}, function (s, st) { |
||||
showWarning("Error: " + st); |
||||
removeClass(cb, "pure-button-disabled"); |
||||
window.setTimeout(fetchServices, 100); |
||||
}); |
||||
} |
||||
|
||||
function displayServices(data) { |
||||
Object.keys(data).forEach(function (v) { |
||||
el = $("#" + v); |
||||
if (el != null) { |
||||
if (el.nodeName === "INPUT") el.value = data[v]; |
||||
else el.innerHTML = data[v]; |
||||
return; |
||||
} |
||||
|
||||
el = document.querySelector('input[name="' + v + '"]'); |
||||
if (el == null) |
||||
el = document.querySelector('select[name="' + v + '"]'); |
||||
|
||||
if (el != null) { |
||||
if (el.type == "checkbox") { |
||||
el.checked = data[v] == "enabled"; |
||||
} else el.value = data[v]; |
||||
} |
||||
}); |
||||
|
||||
$("#syslog-spinner").setAttribute("hidden", ""); |
||||
$("#sntp-spinner").setAttribute("hidden", ""); |
||||
$("#mdns-spinner").setAttribute("hidden", ""); |
||||
|
||||
$("#Syslog-form").removeAttribute("hidden"); |
||||
$("#SNTP-form").removeAttribute("hidden"); |
||||
$("#mDNS-form").removeAttribute("hidden"); |
||||
|
||||
var i, inputs = $("input"); |
||||
for (i = 0; i < inputs.length; i++) { |
||||
if (inputs[i].name == "mdns_enable") inputs[i].onclick = function () { setMDNS(this.checked) }; |
||||
} |
||||
} |
||||
|
||||
function setMDNS(v) { |
||||
ajaxSpin("POST", "/services/update?mdns_enable=" + (v ? 1 : 0), function () { |
||||
showNotification("mDNS is now " + (v ? "enabled" : "disabled")); |
||||
}, function () { |
||||
showWarning("Enable/disable failed"); |
||||
window.setTimeout(fetchServices, 100); |
||||
}); |
||||
} |
||||
|
||||
function fetchServices() { |
||||
ajaxJson("GET", "/services/info", displayServices, function () { |
||||
window.setTimeout(fetchServices, 1000); |
||||
}); |
||||
} |
Loading…
Reference in new issue