Skip to content

Commit 74889da

Browse files
committed
Added WebServer example
1 parent e9695f8 commit 74889da

File tree

2 files changed

+251
-0
lines changed

2 files changed

+251
-0
lines changed
1.52 MB
Binary file not shown.
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/*
2+
This example shows how to retrieve data from Sqlite3 databases from SD Card
3+
through the Web Server and display in the form of HTML page.
4+
It also demonstrates query filtering by parameter passing and chunked encoding.
5+
Before running please copy following files to SD Card:
6+
7+
examples/sqlite3_small_db/data/babyname.db
8+
9+
This database contains around 30000 baby names and corresponding data.
10+
11+
Also need to increase stack size in cores/esp8266/cont.h
12+
to atleast 6144 (from 4096)
13+
*/
14+
15+
/*
16+
* Copyright (c) 2015, Majenko Technologies
17+
* All rights reserved.
18+
*
19+
* Redistribution and use in source and binary forms, with or without modification,
20+
* are permitted provided that the following conditions are met:
21+
*
22+
* * Redistributions of source code must retain the above copyright notice, this
23+
* list of conditions and the following disclaimer.
24+
*
25+
* * Redistributions in binary form must reproduce the above copyright notice, this
26+
* list of conditions and the following disclaimer in the documentation and/or
27+
* other materials provided with the distribution.
28+
*
29+
* * Neither the name of Majenko Technologies nor the names of its
30+
* contributors may be used to endorse or promote products derived from
31+
* this software without specific prior written permission.
32+
*
33+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
37+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
40+
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43+
*/
44+
45+
#include <ESP8266WiFi.h>
46+
#include <WiFiClient.h>
47+
#include <ESP8266WebServer.h>
48+
#include <ESP8266mDNS.h>
49+
#include <sqlite3.h>
50+
#include <vfs.h>
51+
#include <SPI.h>
52+
53+
const char *ssid = "Nokia1";
54+
const char *password = "nokiafour";
55+
56+
ESP8266WebServer server ( 80 );
57+
58+
const int led = 13;
59+
60+
void handleRoot() {
61+
digitalWrite ( led, 1 );
62+
String temp;
63+
int sec = millis() / 1000;
64+
int min = sec / 60;
65+
int hr = min / 60;
66+
67+
temp = "<html><head>\
68+
<title>ESP8266 Demo</title>\
69+
<style>\
70+
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; font-size: large; Color: #000088; }\
71+
</style>\
72+
</head>\
73+
<body>\
74+
<h1>Hello from ESP8266!</h1>\
75+
<p>Uptime: ";
76+
temp += hr;
77+
temp += ":";
78+
temp += min % 60;
79+
temp += ":";
80+
temp += sec % 60;
81+
temp += "</p>\
82+
<h2>Query gendered names database</h2>\
83+
<form name='params' method='GET' action='query_db'>\
84+
Enter from: <input type=text style='font-size: large' value='Bob' name='from'/> \
85+
<br>to: <input type=text style='font-size: large' value='Bobby' name='to'/> \
86+
<br><br><input type=submit style='font-size: large' value='Query database'/>\
87+
</form>\
88+
</body>\
89+
</html>";
90+
91+
server.send ( 200, "text/html", temp.c_str() );
92+
digitalWrite ( led, 0 );
93+
}
94+
95+
void handleNotFound() {
96+
digitalWrite ( led, 1 );
97+
String message = "File Not Found\n\n";
98+
message += "URI: ";
99+
message += server.uri();
100+
message += "\nMethod: ";
101+
message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
102+
message += "\nArguments: ";
103+
message += server.args();
104+
message += "\n";
105+
106+
for ( uint8_t i = 0; i < server.args(); i++ ) {
107+
message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
108+
}
109+
110+
server.send ( 404, "text/plain", message );
111+
digitalWrite ( led, 0 );
112+
}
113+
114+
sqlite3 *db1;
115+
int rc;
116+
sqlite3_stmt *res;
117+
int rec_count = 0;
118+
const char *tail;
119+
120+
int openDb(const char *filename, sqlite3 **db) {
121+
int rc = sqlite3_open(filename, db);
122+
if (rc) {
123+
Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db));
124+
return rc;
125+
} else {
126+
Serial.printf("Opened database successfully\n");
127+
}
128+
return rc;
129+
}
130+
131+
void setup ( void ) {
132+
pinMode ( led, OUTPUT );
133+
digitalWrite ( led, 0 );
134+
Serial.begin ( 74880 );
135+
WiFi.mode ( WIFI_STA );
136+
WiFi.begin ( ssid, password );
137+
Serial.println ( "" );
138+
139+
// Wait for connection
140+
while ( WiFi.status() != WL_CONNECTED ) {
141+
delay ( 500 );
142+
Serial.print ( "." );
143+
}
144+
145+
Serial.println ( "" );
146+
Serial.print ( "Connected to " );
147+
Serial.println ( ssid );
148+
Serial.print ( "IP address: " );
149+
Serial.println ( WiFi.localIP() );
150+
151+
if ( MDNS.begin ( "esp8266" ) ) {
152+
Serial.println ( "MDNS responder started" );
153+
}
154+
155+
SPI.begin();
156+
vfs_mount("/SD0", SS);
157+
158+
sqlite3_initialize();
159+
160+
// Open database
161+
if (openDb("/SD0/babyname.db", &db1))
162+
return;
163+
164+
server.on ( "/", handleRoot );
165+
server.on ( "/query_db", []() {
166+
String sql = "Select count(*) from gendered_names where name between '";
167+
sql += server.arg("from");
168+
sql += "' and '";
169+
sql += server.arg("to");
170+
sql += "'";
171+
rc = sqlite3_prepare_v2(db1, sql.c_str(), 1000, &res, &tail);
172+
if (rc != SQLITE_OK) {
173+
String resp = "Failed to fetch data: ";
174+
resp += sqlite3_errmsg(db1);
175+
resp += ".<br><br><input type=button onclick='location.href=\"/\"' value='back'/>";
176+
server.send ( 200, "text/html", resp.c_str());
177+
Serial.println(resp.c_str());
178+
return;
179+
}
180+
while (sqlite3_step(res) == SQLITE_ROW) {
181+
rec_count = sqlite3_column_int(res, 0);
182+
if (rec_count > 5000) {
183+
String resp = "Too many records: ";
184+
resp += rec_count;
185+
resp += ". Please select different range";
186+
resp += ".<br><br><input type=button onclick='location.href=\"/\"' value='back'/>";
187+
server.send ( 200, "text/html", resp.c_str());
188+
Serial.println(resp.c_str());
189+
sqlite3_finalize(res);
190+
return;
191+
}
192+
}
193+
sqlite3_finalize(res);
194+
195+
sql = "Select year, state, name, total_babies, primary_sex, primary_sex_ratio, per_100k_in_state from gendered_names where name between '";
196+
sql += server.arg("from");
197+
sql += "' and '";
198+
sql += server.arg("to");
199+
sql += "'";
200+
rc = sqlite3_prepare_v2(db1, sql.c_str(), 1000, &res, &tail);
201+
if (rc != SQLITE_OK) {
202+
String resp = "Failed to fetch data: ";
203+
resp += sqlite3_errmsg(db1);
204+
resp += "<br><br><a href='/'>back</a>";
205+
server.send ( 200, "text/html", resp.c_str());
206+
Serial.println(resp.c_str());
207+
return;
208+
}
209+
210+
rec_count = 0;
211+
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
212+
String resp = "<html><head><title>ESP8266 Database query through web server</title>\
213+
<style>\
214+
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; font-size: large; Color: #000088; }\
215+
</style><head><body><h1>ESP8266 Database query through web server</h1><h2>";
216+
resp += sql;
217+
resp += "</h2><br><table cellspacing='1' cellpadding='1' border='1'><tr><td>Year</td><td>State</td><td>Name</td><td>Total babies</td><td>Primary Sex</td><td>Ratio</td><td>Per 100k</td></tr>";
218+
server.send ( 200, "text/html", resp.c_str());
219+
while (sqlite3_step(res) == SQLITE_ROW) {
220+
resp = "<tr><td>";
221+
resp += sqlite3_column_int(res, 0);
222+
resp += "</td><td>";
223+
resp += (const char *) sqlite3_column_text(res, 1);
224+
resp += "</td><td>";
225+
resp += (const char *) sqlite3_column_text(res, 2);
226+
resp += "</td><td>";
227+
resp += sqlite3_column_int(res, 3);
228+
resp += "</td><td>";
229+
resp += (const char *) sqlite3_column_text(res, 4);
230+
resp += "</td><td>";
231+
resp += sqlite3_column_double(res, 5);
232+
resp += "</td><td>";
233+
resp += sqlite3_column_double(res, 6);
234+
resp += "</td></tr>";
235+
server.sendContent(resp);
236+
rec_count++;
237+
}
238+
resp = "</table><br><br>Number of records: ";
239+
resp += rec_count;
240+
resp += ".<br><br><input type=button onclick='location.href=\"/\"' value='back'/>";
241+
server.sendContent(resp);
242+
sqlite3_finalize(res);
243+
} );
244+
server.onNotFound ( handleNotFound );
245+
server.begin();
246+
Serial.println ( "HTTP server started" );
247+
}
248+
249+
void loop ( void ) {
250+
server.handleClient();
251+
}

0 commit comments

Comments
 (0)