| 2 |
raymond |
1 |
#include <FS.h>
|
|
|
2 |
#include <LittleFS.h>
|
|
|
3 |
#include <AsyncFsWebServer.h> // https://github.com/cotestatnt/async-esp-fs-webserver
|
|
|
4 |
|
|
|
5 |
const char* hostname = "myserver";
|
|
|
6 |
#define FILESYSTEM LittleFS
|
|
|
7 |
AsyncFsWebServer server(FILESYSTEM, 80, hostname);
|
|
|
8 |
|
|
|
9 |
#ifndef LED_BUILTIN
|
|
|
10 |
#define LED_BUILTIN 2
|
|
|
11 |
#endif
|
|
|
12 |
|
|
|
13 |
// Test "options" values
|
|
|
14 |
uint8_t ledPin = LED_BUILTIN;
|
|
|
15 |
bool boolVar = true;
|
|
|
16 |
bool boolVar2 = false;
|
|
|
17 |
uint32_t longVar = 1234567890;
|
|
|
18 |
float floatVar = 15.5F;
|
|
|
19 |
String stringVar = "Test option String";
|
|
|
20 |
String dropdownSelected = "Item1";
|
|
|
21 |
// ThingsBoard variables
|
|
|
22 |
String tb_deviceName = "ESP Sensor";
|
|
|
23 |
double tb_deviceLatitude = 41.88505;
|
|
|
24 |
double tb_deviceLongitude = 12.50050;
|
|
|
25 |
String tb_deviceToken = "xxxxxxxxxxxxxxxxxxx";
|
|
|
26 |
String tb_device_key = "xxxxxxxxxxxxxxxxxxx";
|
|
|
27 |
String tb_secret_key = "xxxxxxxxxxxxxxxxxxx";
|
|
|
28 |
String tb_serverIP = "thingsboard.cloud";
|
|
|
29 |
uint16_t tb_port = 80;
|
|
|
30 |
|
|
|
31 |
// Var labels (in /setup webpage)
|
|
|
32 |
#define LED_LABEL "The LED pin number"
|
|
|
33 |
#define BOOL_LABEL "A bool variable"
|
|
|
34 |
#define LONG_LABEL "A long variable"
|
|
|
35 |
#define FLOAT_LABEL "A float variable"
|
|
|
36 |
#define STRING_LABEL "A String variable"
|
|
|
37 |
#define DROPDOWN_TEST "A dropdown listbox"
|
|
|
38 |
|
|
|
39 |
#define TB_DEVICE_NAME "Device Name"
|
|
|
40 |
#define TB_DEVICE_LAT "Device Latitude"
|
|
|
41 |
#define TB_DEVICE_LON "Device Longitude"
|
|
|
42 |
#define TB_SERVER "ThingsBoard server address"
|
|
|
43 |
#define TB_PORT "ThingsBoard server port"
|
|
|
44 |
#define TB_DEVICE_TOKEN "ThingsBoard device token"
|
|
|
45 |
#define TB_DEVICE_KEY "Provisioning device key"
|
|
|
46 |
#define TB_SECRET_KEY "Provisioning secret key"
|
|
|
47 |
|
|
|
48 |
// Timezone definition to get properly time from NTP server
|
|
|
49 |
//n.u. #define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"
|
|
|
50 |
//n.u. struct tm Time;
|
|
|
51 |
|
|
|
52 |
/*
|
|
|
53 |
* Include the custom HTML, CSS and Javascript to be injected in /setup webpage.
|
|
|
54 |
* HTML code will be injected according to the order of options declaration.
|
|
|
55 |
* CSS and JavaScript will be appended to the end of body in order to work properly.
|
|
|
56 |
* In this manner, is also possible override the default element styles
|
|
|
57 |
* like for example background color, margins, padding etc etc
|
|
|
58 |
*/
|
|
|
59 |
#include "customElements.h"
|
|
|
60 |
#include "thingsboard.h"
|
|
|
61 |
|
|
|
62 |
// Callback: notify user when the configuration file is saved
|
|
|
63 |
void onConfigSaved(const char* path) {
|
|
|
64 |
Serial.printf("\n[Config] File salvato: %s\n", path);
|
|
|
65 |
}
|
|
|
66 |
|
|
|
67 |
//////////////////////////////// Filesystem /////////////////////////////////////////
|
|
|
68 |
bool startFilesystem() {
|
|
|
69 |
if (FILESYSTEM.begin()){
|
|
|
70 |
server.printFileList(FILESYSTEM, "/", 1);
|
|
|
71 |
return true;
|
|
|
72 |
}
|
|
|
73 |
else {
|
|
|
74 |
Serial.println("ERROR on mounting filesystem. It will be reformatted!");
|
|
|
75 |
FILESYSTEM.format();
|
|
|
76 |
ESP.restart();
|
|
|
77 |
}
|
|
|
78 |
return false;
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
|
|
|
82 |
//////////////////// Load application options from filesystem ////////////////////
|
|
|
83 |
bool loadOptions() {
|
|
|
84 |
if (FILESYSTEM.exists(server.getConfiFileName())) {
|
|
|
85 |
// Test "options" values
|
|
|
86 |
server.getOptionValue(LED_LABEL, ledPin);
|
|
|
87 |
server.getOptionValue(BOOL_LABEL, boolVar);
|
|
|
88 |
server.getOptionValue(BOOL_LABEL "2", boolVar2);
|
|
|
89 |
server.getOptionValue(LONG_LABEL, longVar);
|
|
|
90 |
server.getOptionValue(FLOAT_LABEL, floatVar);
|
|
|
91 |
server.getOptionValue(STRING_LABEL, stringVar);
|
|
|
92 |
server.getOptionValue(DROPDOWN_TEST, dropdownSelected);
|
|
|
93 |
// ThingsBoard variables
|
|
|
94 |
server.getOptionValue(TB_DEVICE_NAME, tb_deviceName);
|
|
|
95 |
server.getOptionValue(TB_DEVICE_LAT, tb_deviceLatitude);
|
|
|
96 |
server.getOptionValue(TB_DEVICE_LON, tb_deviceLongitude);
|
|
|
97 |
server.getOptionValue(TB_DEVICE_TOKEN, tb_deviceToken);
|
|
|
98 |
server.getOptionValue(TB_DEVICE_KEY, tb_device_key);
|
|
|
99 |
server.getOptionValue(TB_SECRET_KEY, tb_secret_key);
|
|
|
100 |
server.getOptionValue(TB_SERVER, tb_serverIP);
|
|
|
101 |
server.getOptionValue(TB_PORT, tb_port);
|
|
|
102 |
server.closeSetupConfiguration(); // Close configuration to free resources
|
|
|
103 |
|
|
|
104 |
Serial.println("\nThis are the current values stored: \n");
|
|
|
105 |
Serial.printf("LED pin value: %d\n", ledPin);
|
|
|
106 |
Serial.printf("Bool value 1: %s\n", boolVar ? "true" : "false");
|
|
|
107 |
Serial.printf("Bool value 2: %s\n", boolVar2 ? "true" : "false");
|
|
|
108 |
Serial.printf("Long value: %u\n", longVar);
|
|
|
109 |
Serial.printf("Float value: %d.%d\n", (int)floatVar, (int)(floatVar*1000)%1000);
|
|
|
110 |
Serial.printf("String value: %s\n", stringVar.c_str());
|
|
|
111 |
Serial.printf("Dropdown selected: %s\n", dropdownSelected.c_str());
|
|
|
112 |
return true;
|
|
|
113 |
}
|
|
|
114 |
else {
|
|
|
115 |
Serial.println("Failed to parse configuration file");
|
|
|
116 |
return false;
|
|
|
117 |
}
|
|
|
118 |
return true;
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
|
|
|
122 |
void setup() {
|
|
|
123 |
pinMode(LED_BUILTIN, OUTPUT);
|
|
|
124 |
Serial.begin(115200);
|
|
|
125 |
|
|
|
126 |
// FILESYSTEM INIT
|
|
|
127 |
if (startFilesystem()){
|
|
|
128 |
// Load configuration (if not present, default will be created when webserver will start)
|
|
|
129 |
loadOptions();
|
|
|
130 |
}
|
|
|
131 |
|
|
|
132 |
// Try to connect to WiFi (will start AP if not connected after timeout)
|
|
|
133 |
if (!server.startWiFi(10000)) {
|
|
|
134 |
Serial.println("\nWiFi not connected! Starting AP mode...");
|
|
|
135 |
server.startCaptivePortal("ESP_AP", "123456789", "/setup");
|
|
|
136 |
}
|
|
|
137 |
|
|
|
138 |
// Add custom HTTP request handlers to webserver
|
|
|
139 |
server.on("/reload", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
|
140 |
request->send(200, "text/plain", "Options loaded");
|
|
|
141 |
loadOptions();
|
|
|
142 |
Serial.println("Application option loaded after web request");
|
|
|
143 |
});
|
|
|
144 |
|
|
|
145 |
// Add a new options box
|
|
|
146 |
server.addOptionBox("My Options");
|
|
|
147 |
server.addOption(LED_LABEL, ledPin);
|
|
|
148 |
server.addOption(LONG_LABEL, longVar);
|
|
|
149 |
// Float fields can be configured with min, max and step properties
|
|
|
150 |
server.addOption(FLOAT_LABEL, floatVar, 0.0, 100.0, 0.01);
|
|
|
151 |
server.addOption(STRING_LABEL, stringVar);
|
|
|
152 |
server.addOption(BOOL_LABEL, boolVar);
|
|
|
153 |
server.addOption(BOOL_LABEL "2", boolVar2);
|
|
|
154 |
static const char* dropItem[] = {"Item1", "Item2", "Item3"};
|
|
|
155 |
AsyncFsWebServer::DropdownList dropdownDef{ DROPDOWN_TEST, dropItem, 3, 0 };
|
|
|
156 |
server.addDropdownList(dropdownDef);
|
|
|
157 |
|
|
|
158 |
// Add a new options box with custom code injected
|
|
|
159 |
server.addOptionBox("Custom HTML");
|
|
|
160 |
// How many times you need (for example one in different option box)
|
|
|
161 |
server.addHTML(custom_html, "fetch-test", /*overwrite*/ false);
|
|
|
162 |
|
|
|
163 |
// Add a new options box
|
|
|
164 |
server.addOptionBox("ThingsBoard");
|
|
|
165 |
server.addOption(TB_DEVICE_NAME, tb_deviceName);
|
|
|
166 |
server.addOption(TB_DEVICE_LAT, tb_deviceLatitude, -180.0, 180.0, 0.00001);
|
|
|
167 |
server.addOption(TB_DEVICE_LON, tb_deviceLongitude, -180.0, 180.0, 0.00001);
|
|
|
168 |
server.addOption(TB_SERVER, tb_serverIP);
|
|
|
169 |
server.addOption(TB_PORT, tb_port);
|
|
|
170 |
server.addOption(TB_DEVICE_KEY, tb_device_key);
|
|
|
171 |
server.addOption(TB_SECRET_KEY, tb_secret_key);
|
|
|
172 |
server.addOption(TB_DEVICE_TOKEN, tb_deviceToken);
|
|
|
173 |
server.addHTML(thingsboard_htm, "ts", /*overwrite file*/ false);
|
|
|
174 |
|
|
|
175 |
// CSS will be appended to HTML head
|
|
|
176 |
server.addCSS(custom_css, "fetch", /*overwrite file*/ false);
|
|
|
177 |
// Javascript will be appended to HTML body
|
|
|
178 |
server.addJavascript(custom_script, "fetch", /*overwrite file*/ false);
|
|
|
179 |
server.addJavascript(thingsboard_script, "ts", /*overwrite file*/ false);
|
|
|
180 |
|
|
|
181 |
// Add custom page title to /setup
|
|
|
182 |
server.setSetupPageTitle("Custom HTML Web Server");
|
|
|
183 |
|
|
|
184 |
// Set custom logo for /setup page using a raster image (png, jpg, bmp),
|
|
|
185 |
// with the method below, but remember to set the proper mime type for the image
|
|
|
186 |
// (use the provided python script to convert your image to byte array with proper format and size for best results)
|
|
|
187 |
server.setSetupPageLogo(custom_logo, sizeof(custom_logo), /*mime type*/ "image/png", /*overwrite*/ false);
|
|
|
188 |
|
|
|
189 |
// As alternative use the content of SVG file as text for logo
|
|
|
190 |
// server.setSetupPageLogo(custom_logo_svg, /*overwrite*/ false);
|
|
|
191 |
|
|
|
192 |
// Enable ACE FS file web editor and add FS info callback function
|
|
|
193 |
server.enableFsCodeEditor();
|
|
|
194 |
|
|
|
195 |
// Inform user when config.json is saved via /edit or /upload
|
|
|
196 |
server.setConfigSavedCallback(onConfigSaved);
|
|
|
197 |
|
|
|
198 |
// Start web server
|
|
|
199 |
if (server.init()) {
|
|
|
200 |
Serial.print(F("\n\nWeb Server started on IP Address: "));
|
|
|
201 |
Serial.println(server.getServerIP());
|
|
|
202 |
Serial.println(F(
|
|
|
203 |
"\nThis is \"customHTML.ino\" example.\n"
|
|
|
204 |
"Open /setup page to configure optional parameters.\n"
|
|
|
205 |
"Open /edit page to view, edit or upload example or your custom webserver source files."
|
|
|
206 |
));
|
|
|
207 |
Serial.printf("Ready! Open http://%s.local in your browser\n", hostname);
|
|
|
208 |
if (server.isAccessPointMode())
|
|
|
209 |
Serial.print(F("Captive portal is running"));
|
|
|
210 |
}
|
|
|
211 |
|
|
|
212 |
}
|
|
|
213 |
|
|
|
214 |
|
|
|
215 |
void loop() {
|
|
|
216 |
if (server.isAccessPointMode())
|
|
|
217 |
server.updateDNS();
|
|
|
218 |
|
|
|
219 |
// Nothing to do here, just a small delay for task yield
|
|
|
220 |
delay(10);
|
|
|
221 |
}
|