Skip to content

Commit 0c9f15d

Browse files
committed
Add NeoPixel support.
Add Device setup. Add Data trigger and extraction for local display.
1 parent 6c9aec7 commit 0c9f15d

File tree

5 files changed

+531
-292
lines changed

5 files changed

+531
-292
lines changed

Page_Root.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const char PAGE_Root[] PROGMEM = R"=====(
2020
<pre><div id='log'></div></pre>
2121
<p>
2222
<form id='msg' action='data' method='get'>
23-
<input id='txt' name='text' type='text'></input><input id='crlf' type='checkbox' checked>+crlf?</input>
23+
<input id='txt' name='text' type='text'></input><input id='crlf' type='checkbox' checked>+cr?</input>
2424
</form></p>
2525
<p><a href="/admin.html">Settings</a> <a href="/file?start=1">Stream</a></p>
2626
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js'></script>

Pages.h

+201-52
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,50 @@
22
#define PAGES_H
33

44

5+
String send_tag_values(const String& tag) {
6+
if (tag == "devicename") return (String) config.DeviceName;
7+
if (tag == "baud") return (String) config.baud;
8+
if (tag == "Connect") return (String) (config.Connect ? "checked" : "");
9+
if (tag == "logging") return (String) (config.Logging ? "checked" : "");
10+
if (tag == "server") return (String) config.streamServerURL;
11+
if (tag == "interval") return (String) config.Interval;
12+
if (tag == "wakecount") return (String) config.WakeCount;
13+
if (tag == "blinked") return (String) (digitalRead(WAS_BLINK)? "YES": "NO");
14+
if (tag == "datatrigger") return (String) config.datatrigger;
15+
if (tag == "dataregexp1") return (String) config.dataregexp1;
16+
if (tag == "dataslope1") return String(config.dataslope1,7);
17+
if (tag == "dataoffset1") return String(config.dataoffset1,7);
18+
if (tag == "dataname1") return (String) config.dataname1;
19+
if (tag == "dataslope2") return String(config.dataslope2,7);
20+
if (tag == "dataoffset2") return String(config.dataoffset2,7);
21+
if (tag == "dataname2") return (String) config.dataname2;
22+
if (tag == "dataslope3") return String(config.dataslope3,7);
23+
if (tag == "dataoffset3") return String(config.dataoffset3,7);
24+
if (tag == "dataname3") return (String) config.dataname3;
25+
if (tag == "datacount") return (String) config.datacount;
26+
if (tag == "directory") {
27+
String dirlist = "";
28+
Dir dir = SPIFFS.openDir("/");
29+
while (dir.next()) {
30+
dirlist += String(dir.fileName());
31+
dirlist += "\t ";
32+
File f = dir.openFile("r");
33+
dirlist += String(f.size());
34+
dirlist += " bytes\n ";
35+
}
36+
return dirlist ;
37+
}
38+
}
39+
540
/**** ADMIN MAIN PAGE ****/
641
const char PAGE_AdminMainPage[] PROGMEM = R"=====(
742
<!DOCTYPE html>
843
<HTML>
944
<HEAD>
1045
<meta name="viewport" content="width=device-width, initial-scale=1" />
1146
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
47+
<link rel="stylesheet" href="/style.css" />
48+
1249
</HEAD>
1350
<BODY>
1451

@@ -18,27 +55,7 @@ const char PAGE_AdminMainPage[] PROGMEM = R"=====(
1855
<a href="config.html" style="width:250px" class="btn btn--m btn--blue" >Network Configuration</a><br>
1956
<a href="info.html" style="width:250px" class="btn btn--m btn--blue" >Network Information</a><br>
2057
<a href="ntp.html" style="width:250px" class="btn btn--m btn--blue" >NTP Settings</a><br>
21-
22-
23-
<script>
24-
window.onload = function (){
25-
load("style.css","css", function() {
26-
load("microajax.js","js", function() {
27-
// Do something after load...
28-
});
29-
});
30-
}
31-
function load(e,t,n){
32-
if("js"==t){
33-
var a=document.createElement("script");
34-
a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)
35-
}
36-
else if("css"==t){
37-
var a=document.createElement("link");
38-
a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)
39-
}
40-
}
41-
</script>
58+
<a href="device.html" style="width:250px" class="btn btn--m btn--blue" >Connected Device Setup</a><br>
4259
</BODY>
4360
</HTML>
4461
)=====";
@@ -50,22 +67,24 @@ const char PAGE_AdminGeneralSettings[] PROGMEM = R"=====(
5067
<HEAD>
5168
<meta name="viewport" content="width=device-width, initial-scale=1" />
5269
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
70+
<link rel="stylesheet" href="/style.css" />
71+
<script src="microajax.js"></script>
5372
</HEAD>
5473
<BODY>
5574
<a href="admin.html" class="btn btn--s">&lt;</a>&nbsp;&nbsp;<strong>General Settings</strong>
5675
<hr>
5776
<form action="" method="post">
5877
<table border="0" cellspacing="0" cellpadding="3" >
59-
<tr><td align="right">Name of Device</td><td><input type="text" id="devicename" name="devicename" value=""></td></tr>
60-
<tr><td align="right"> Enable Connection:</td><td><input type="checkbox" id="connect" name="connect"></td></tr>
61-
<tr><td align="right"> Blink?:</td><td><div id="blinked">N/A</div></td></tr>
78+
<tr><td align="right">Name of Device</td><td><input type="text" id="devicename" name="devicename" value="`devicename`"></td></tr>
79+
<tr><td align="right"> Enable Connection:</td><td><input type="checkbox" id="connect" name="connect" `Connect`></td></tr>
80+
<tr><td align="right"> Blink?:</td><td><div id="blinked">`blinked`</div></td></tr>
6281
<tr><td align="left" colspan="2"><hr></td></tr>
6382
<tr><td align="left" colspan="2">Logging</td></tr>
64-
<tr><td align="right"> Enabled:</td><td><input type="checkbox" id="logging" name="logging"></td></tr>
65-
<tr><td align="right"> Interval:</td><td><input type="text" id="interval" name="interval" size="6" value="0"> Seconds</td></tr>
66-
<tr><td align="right"> Check in every:</td><td><input type="text" id="wakecount" name="wakecount" size="6" value="0"> intervals</td></tr>
67-
<tr><td colspan="2">Stream Server:<br><input type="text" id="server" name="server" size="65" value=""></td></tr>
68-
<tr><td colspan="2" align="center"><input disabled id="save" type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save"></td></tr>
83+
<tr><td align="right"> Enabled:</td><td><input type="checkbox" id="logging" name="logging" `logging`></td></tr>
84+
<tr><td align="right"> Interval:</td><td><input type="text" id="interval" name="interval" size="6" value="`interval`"> Seconds</td></tr>
85+
<tr><td align="right"> Check in every:</td><td><input type="text" id="wakecount" name="wakecount" size="6" value="`wakecount`"> intervals</td></tr>
86+
<tr><td colspan="2">Stream Server:<br><input type="text" id="server" name="server" size="65" value="`server`"></td></tr>
87+
<tr><td colspan="2" align="center"><input id="save" type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save"></td></tr>
6988
</table>
7089
</form>
7190
<br>Status <span id="status">&nbsp; </span>
@@ -78,7 +97,7 @@ var scale = 50000;
7897
var devstatus = document.getElementById('status');
7998

8099
function setValuesDone() {
81-
document.getElementById("save").disabled = false;
100+
82101
if ("Monster" == document.getElementById("devicename").value) {
83102
var elemDiv = document.createElement('div');
84103
elemDiv.style.cssText = 'position:absolute;width:100%;height:50px;opacity:0.3;z-index:100;background:#000;';
@@ -117,23 +136,9 @@ function clickSendNum(e){
117136
}
118137

119138
window.onload = function () {
120-
load("style.css","css", function() {
121-
load("microajax.js","js", function() {
122-
setValues("/admin/generalvalues");
123-
});
124-
});
139+
setValuesDone();
125140
};
126141

127-
function load(e,t,n){
128-
if("js"==t){
129-
var a=document.createElement("script");
130-
a.src=e,a.type="text/javascript",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)
131-
}
132-
else if("css"==t){
133-
var a=document.createElement("link");
134-
a.href=e,a.rel="stylesheet",a.type="text/css",a.async=!1,a.onload=function(){n()},document.getElementsByTagName("head")[0].appendChild(a)
135-
}
136-
}
137142
</script>
138143
</BODY>
139144
</HTML>
@@ -153,12 +158,12 @@ void send_general_html(AsyncWebServerRequest *request){
153158
//config.AutoTurnOff = false;
154159
String temp = "";
155160
for ( uint8_t i = 0; i < request->args(); i++ ) {
156-
if (request->argName(i) == "devicename") config.DeviceName = urldecode(request->arg(i));
161+
if (request->argName(i) == "devicename") urldecode(request->arg(i), config.DeviceName, sizeof(config.DeviceName));
157162
if (request->argName(i) == "logging") config.Logging = true;
158163
if (request->argName(i) == "connect") config.Connect = true;
159164
if (request->argName(i) == "interval") config.Interval = request->arg(i).toInt();
160165
if (request->argName(i) == "wakecount") config.WakeCount = request->arg(i).toInt();
161-
if (request->argName(i) == "server") config.streamServerURL = urldecode(request->arg(i));
166+
if (request->argName(i) == "server") urldecode(request->arg(i), config.streamServerURL, sizeof(config.streamServerURL));
162167
}
163168
WriteConfig();
164169
firstStart = true;
@@ -169,7 +174,7 @@ void send_general_html(AsyncWebServerRequest *request){
169174
}
170175
}
171176
if (config.Interval > 0) config.sleepy=true; else config.sleepy=false;
172-
request->send ( 200, "text/html", PAGE_AdminGeneralSettings );
177+
request->send_P ( 200, "text/html", PAGE_AdminGeneralSettings, send_tag_values );
173178
debugbuf+=__FUNCTION__;
174179
}
175180

@@ -183,11 +188,155 @@ void send_general_configuration_values_html(AsyncWebServerRequest *request) {
183188
values += "server|" + (String) config.streamServerURL + "|input\n";
184189
values += "blinked|" + (String) (digitalRead(WAS_BLINK)? "YES": "NO") + "|div\n";
185190
digitalWrite(CLEAR_BLINK, LOW);
191+
pinMode(CLEAR_BLINK, OUTPUT); //incase it was overwritten by Serial1 NeoPixel cmdString
186192
request->send ( 200, "text/plain", values);
187193
debugbuf+=__FUNCTION__;
188194
digitalWrite(CLEAR_BLINK, HIGH);
195+
pinMode(CLEAR_BLINK, OUTPUT); //incase it was overwritten by Serial1 NeoPixel cmdString
189196
}
190-
197+
198+
/**** FILE MANAGER PAGE ****/
199+
200+
const char PAGE_FileSystem[] PROGMEM = R"=====(
201+
<!DOCTYPE html>
202+
<HTML>
203+
<HEAD>
204+
<meta name="viewport" content="width=device-width, initial-scale=1" />
205+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
206+
<link rel="stylesheet" href="/style.css">
207+
</HEAD>
208+
<BODY>
209+
<a href="admin.html" class="btn btn--s">&lt;</a>&nbsp;&nbsp;<strong>File System</strong>
210+
<hr>
211+
<pre> `directory`</pre>
212+
<form method="post" enctype="multipart/form-data" action="/update">
213+
Upload: <br><input type="file" name="name">
214+
<input class="button" type="submit" value="Upload">
215+
</form>
216+
</BODY>
217+
</HTML>
218+
)=====";
219+
220+
void handle_fs_upload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
221+
static File fsUploadFile; //Used with SPIFFS to upload files.
222+
//Needs to persist because multiple calls are made to write data.
223+
224+
if(!index){
225+
fsUploadFile = SPIFFS.open("/"+filename, "w");
226+
//opening forward slash is required, or SPIFFS doesn't see the file as being in the root "folder"
227+
debugbuf+="Upload:";
228+
debugbuf+=filename;
229+
debugbuf+=" handle ";
230+
debugbuf+=String(fsUploadFile);
231+
debugbuf+="\n";
232+
}
233+
if (len) {
234+
fsUploadFile.write(data, len);
235+
debugbuf+=String((len));
236+
debugbuf+=" bytes\n";
237+
}
238+
if(final){
239+
if(fsUploadFile) fsUploadFile.close();
240+
debugbuf+=" done\n";
241+
}
242+
//yield(); //https://github.com/esp8266/Arduino/issues/1045
243+
}
244+
245+
void send_fs_html(AsyncWebServerRequest *request){
246+
if (request->args() > 0 ) { // Work to do
247+
for ( uint8_t i = 0; i < request->args(); i++ ) {
248+
if (request->argName(i) == "delete") debugbuf+= "delete"+ request->arg(i);
249+
}
250+
}
251+
debugbuf+=__FUNCTION__;
252+
request->send_P ( 200, "text/html", PAGE_FileSystem, send_tag_values );
253+
}
254+
255+
/**** CONNECTED DEVICE SETUP PAGE ****/
256+
257+
const char PAGE_AdminDeviceSettings[] PROGMEM = R"=====(
258+
<!DOCTYPE html>
259+
<HTML>
260+
<HEAD>
261+
<meta name="viewport" content="width=device-width, initial-scale=1" />
262+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
263+
<link rel="stylesheet" href="/style.css">
264+
</HEAD>
265+
<BODY>
266+
<a href="admin.html" class="btn btn--s">&lt;</a>&nbsp;&nbsp;<strong>Connected Device Settings</strong>
267+
<hr>
268+
<form action="" method="post">
269+
<table border="0" cellspacing="0" cellpadding="3" >
270+
<tr><td align="right">Baud rate</td><td><input type="text" id="baud" name="baud" value="`baud`"></td></tr>
271+
<tr><td align="right"> Enable Connection:</td><td><input type="checkbox" id="connect" name="connect" `Connect`></td></tr>
272+
<tr><td align="right"> Blink?:</td><td><div id="blinked">`blinked`</div></td></tr>
273+
<tr><td align="left" colspan="2"><hr></td></tr>
274+
<tr><td align="left" colspan="2">Extracted Data Reading: (<a href="http://www.cplusplus.com/reference/cstdio/scanf/">Data Pattern help</a>)</td></tr>
275+
<tr><td align="right"> Trigger:</td><td>
276+
<input type="text" id="datatrigger" name="datatrigger" value="`datatrigger`" size=6>
277+
Every <input type="text" id="datatcount" name="datacount" value="`datacount`" size=3> Seconds
278+
</td></tr>
279+
<tr><td align="right"> Data Pattern:</td><td><input type="text" id="dataregexp1" name="dataregexp1" value="`dataregexp1`"></td></tr>
280+
<tr><td align="right"> Name:</td>
281+
<td>
282+
<input type="text" id="dataname1" name="dataname1" size="6" value="`dataname1`">
283+
<input type="text" id="dataname2" name="dataname2" size="6" value="`dataname2`">
284+
<input type="text" id="dataname3" name="dataname3" size="6" value="`dataname3`">
285+
</td>
286+
</tr> <tr><td align="right"> Slope:</td>
287+
<td>
288+
<input type="text" id="dataslope1" name="dataslope1" size="6" value="`dataslope1`">
289+
<input type="text" id="dataslope2" name="dataslope2" size="6" value="`dataslope2`">
290+
<input type="text" id="dataslope3" name="dataslope3" size="6" value="`dataslope3`">
291+
</td>
292+
</tr>
293+
<tr><td align="right"> Offset:</td>
294+
<td>
295+
<input type="text" id="dataoffset1" name="dataoffset1" size="6" value="`dataoffset1`">
296+
<input type="text" id="dataoffset2" name="dataoffset2" size="6" value="`dataoffset2`">
297+
<input type="text" id="dataoffset3" name="dataoffset3" size="6" value="`dataoffset3`">
298+
</td>
299+
</tr>
300+
<tr><td colspan="2" align="center">
301+
<input id="save" type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save">
302+
</td></tr>
303+
</table>
304+
</form>
305+
</BODY>
306+
</HTML>
307+
)=====";
308+
309+
310+
void send_device_html(AsyncWebServerRequest *request){
311+
if (request->args() > 0 ) { // Save Settings
312+
config.Connect = false; //guess
313+
for ( uint8_t i = 0; i < request->args(); i++ ) {
314+
if (request->argName(i) == "baud") config.baud = request->arg(i).toInt();
315+
else if (request->argName(i) == "connect") config.Connect = true;
316+
else if (request->argName(i) == "datatrigger") strlcpy( config.datatrigger, HTMLencode(request->arg(i).c_str()).c_str(), sizeof(config.datatrigger));
317+
else if (request->argName(i) == "dataregexp1") strlcpy( config.dataregexp1, request->arg(i).c_str(), sizeof(config.dataregexp1));
318+
else if (request->argName(i) == "dataslope1") config.dataslope1 = request->arg(i).toFloat();
319+
else if (request->argName(i) == "dataoffset1") config.dataoffset1 = request->arg(i).toFloat();
320+
else if (request->argName(i) == "dataname1") strlcpy( config.dataname1, request->arg(i).c_str(), sizeof(config.dataname1));
321+
else if (request->argName(i) == "dataslope2") config.dataslope2 = request->arg(i).toFloat();
322+
else if (request->argName(i) == "dataoffset2") config.dataoffset2 = request->arg(i).toFloat();
323+
else if (request->argName(i) == "dataname2") strlcpy( config.dataname2, request->arg(i).c_str(), sizeof(config.dataname2));
324+
else if (request->argName(i) == "dataslope3") config.dataslope3 = request->arg(i).toFloat();
325+
else if (request->argName(i) == "dataoffset3") config.dataoffset3 = request->arg(i).toFloat();
326+
else if (request->argName(i) == "dataname3") strlcpy( config.dataname3, request->arg(i).c_str(), sizeof(config.dataname3));
327+
else if (request->argName(i) == "datacount") config.datacount = request->arg(i).toInt();
328+
}
329+
WriteConfig();
330+
if (config.Connect) {
331+
digitalWrite(SERIAL_ENABLE_PIN, HIGH);
332+
} else {
333+
digitalWrite(SERIAL_ENABLE_PIN, LOW);
334+
}
335+
}
336+
request->send_P ( 200, "text/html", PAGE_AdminDeviceSettings, send_tag_values );
337+
debugbuf+=__FUNCTION__;
338+
}
339+
191340
/**** ADMIN NETWORK INFORMATION PAGE ****/
192341
const char PAGE_Information[] PROGMEM = R"=====(
193342
<!DOCTYPE html>
@@ -339,8 +488,8 @@ void send_network_configuration_html(AsyncWebServerRequest *request) {
339488
String temp = "";
340489
config.dhcp = false;
341490
for ( uint8_t i = 0; i < request->args(); i++ ) {
342-
if (request->argName(i) == "ssid") config.ssid = urldecode(request->arg(i));
343-
if (request->argName(i) == "password") config.password = urldecode(request->arg(i));
491+
if (request->argName(i) == "ssid") urldecode(request->arg(i), config.ssid, sizeof(config.ssid));
492+
if (request->argName(i) == "password") urldecode(request->arg(i), config.password, sizeof(config.password));
344493
if (request->argName(i) == "ip_0") if (checkRange(request->arg(i))) config.IP[0] = request->arg(i).toInt();
345494
if (request->argName(i) == "ip_1") if (checkRange(request->arg(i))) config.IP[1] = request->arg(i).toInt();
346495
if (request->argName(i) == "ip_2") if (checkRange(request->arg(i))) config.IP[2] = request->arg(i).toInt();
@@ -511,7 +660,7 @@ void send_NTP_configuration_html(AsyncWebServerRequest *request) {
511660
config.daylight = false;
512661
String temp = "";
513662
for ( uint8_t i = 0; i < request->args(); i++ ) {
514-
if (request->argName(i) == "ntpserver") config.ntpServerName = urldecode( request->arg(i));
663+
if (request->argName(i) == "ntpserver") urldecode( request->arg(i), config.ntpServerName, sizeof(config.ntpServerName));
515664
if (request->argName(i) == "update") config.Update_Time_Via_NTP_Every = request->arg(i).toInt();
516665
if (request->argName(i) == "tz") config.timezone = request->arg(i).toInt();
517666
if (request->argName(i) == "dst") config.daylight = true;

0 commit comments

Comments
 (0)