Subversion Repositories ESP8266_P1_Meter

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 raymond 1
#include <FS.h>
2
#include <LittleFS.h>
3
#include <AsyncFsWebServer.h>  //https://github.com/cotestatnt/async-esp-fs-webserver
4
 
5
// Timezone definition to get properly time from NTP server
6
#define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"
7
struct tm Time;
8
 
9
#define FILESYSTEM LittleFS
10
AsyncFsWebServer server(FILESYSTEM, 80, "myserver");
11
 
12
// Define built-in LED if not defined by board (eg. generic dev boards)
13
#ifndef LED_BUILTIN
14
#define LED_BUILTIN 2
15
#endif
16
#define BOOT_PIN    0
17
 
18
// Labels used in /setup webpage for options
19
#define LED_LABEL "The LED pin number"
20
#define BOOL_LABEL "A bool variable"
21
#define BOOL_LABEL2 "A second bool variable"
22
#define LONG_LABEL "A long variable"
23
#define FLOAT_LABEL "A float variable"
24
#define STRING_LABEL "A String variable"
25
#define DROPDOWN_LABEL "Days of week"
26
#define BRIGHTNESS_LABEL "Brightness"
27
 
28
// Test "options" values
29
uint8_t ledPin = LED_BUILTIN;
30
bool boolVar = true;
31
bool boolVar2 = false;
32
uint32_t longVar = 1234567890;
33
float floatVar = 15.51F;
34
String stringVar = "Test option String";
35
 
36
// Add a dropdown list box in /setup page
37
const char* days[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
38
uint8_t daySelected = 2;// Default to "Wednesday"
39
AsyncFsWebServer::DropdownList dayOfWeek{ DROPDOWN_LABEL, days, 7, daySelected}; 
40
 
41
// Add a slider in /setup page
42
AsyncFsWebServer::Slider brightness{ BRIGHTNESS_LABEL, 0.0, 100.0, 1.0, 50.0 };
43
 
44
static const char reload_btn_htm[] PROGMEM = R"EOF(
45
<div class="bar">
46
  <a class="btn" id="reload-btn">Reload options</a>
47
</div>
48
)EOF";
49
 
50
static const char reload_btn_script[] PROGMEM = R"EOF(
51
/* Add click listener to button */
52
const reloadCfg = () => {
53
  console.log('Reload configuration options');
54
  fetch('/reload')
55
  .then((response) => {
56
    if (response.ok) {
57
      openModal('Options loaded', 'Options was reloaded from configuration file');
58
      return;
59
    }
60
    throw new Error('Something goes wrong with fetch');
61
  })
62
  .catch((error) => {
63
    openModal('Error', 'Something goes wrong with your request');
64
  });
65
};
66
document.getElementById('reload-btn').addEventListener('click', reloadCfg);
67
)EOF";
68
 
69
 
70
/////////// Callback: notify user when the configuration file is saved  /////////////
71
void onConfigSaved(const char* path) {
72
  Serial.printf("\n[Config] File salvato: %s\n", path);
73
}
74
 
75
////////////////////////////////  Filesystem  /////////////////////////////////////////
76
bool startFilesystem() {
77
  if (FILESYSTEM.begin()){
78
    server.printFileList(FILESYSTEM, "/", 2);
79
    return true;
80
  }
81
  else {
82
    Serial.println("ERROR on mounting filesystem. It will be reformatted!");
83
    FILESYSTEM.format();
84
    ESP.restart();
85
  }
86
  return false;
87
}
88
 
89
////////////////////  Load application options from filesystem  ////////////////////
90
bool loadOptions() {
91
  if (FILESYSTEM.exists(server.getConfiFileName())) {
92
    server.getOptionValue(LED_LABEL, ledPin);
93
    server.getOptionValue(BOOL_LABEL, boolVar);
94
    server.getOptionValue(BOOL_LABEL2, boolVar2);
95
    server.getOptionValue(LONG_LABEL, longVar);
96
    server.getOptionValue(FLOAT_LABEL, floatVar);
97
    server.getOptionValue(STRING_LABEL, stringVar);
98
    server.getDropdownSelection(dayOfWeek);    
99
    server.getSliderValue(brightness);
100
    server.closeSetupConfiguration();  // Close configuration to free resources
101
 
102
    Serial.println("\nThis are the current values stored: \n");
103
    Serial.printf("LED pin value: %d\n", ledPin);
104
    Serial.printf("Bool value: %s\n", boolVar ? "true" : "false");
105
    Serial.printf("Bool value2: %s\n", boolVar2 ? "true" : "false");
106
    Serial.printf("Long value: %u\n", longVar);
107
    Serial.printf("Float value: %3.2f\n", floatVar);
108
    Serial.printf("String value: %s\n", stringVar.c_str());
109
    Serial.printf("Dropdown selected value: %s\n", days[dayOfWeek.selectedIndex]);
110
    Serial.printf("Slider value: %3.2f\n\n", brightness.value);
111
    return true;
112
  }
113
  else
114
    Serial.println(F("Config file not exist"));
115
  return false;
116
}
117
 
118
 
119
////////////////////////////  HTTP Request Handlers  ////////////////////////////////////
120
void handleLoadOptions(AsyncWebServerRequest *request) {
121
  request->send(200, "text/plain", "Options loaded");
122
  loadOptions();
123
  Serial.println("Application option loaded after web request");
124
}
125
 
126
 
127
void setup() {
128
  pinMode(LED_BUILTIN, OUTPUT);
129
  pinMode(BOOT_PIN, INPUT_PULLUP);
130
  Serial.begin(115200);
131
 
132
  // FILESYSTEM INIT
133
  if (startFilesystem()){
134
    // Load configuration (if not present, default will be created when webserver will start)
135
    loadOptions();
136
  }
137
 
138
  // Default firmware version is set to compile time, but you can edit with a custom string
139
  // Custom firmware version -> Major.Minor.Build (build is set to compile date YYYYMMDDHHMM)
140
  String version = "1.0." + String(BUILD_TIMESTAMP);
141
  server.setFirmwareVersion(version);
142
 
143
  // Try to connect to WiFi (will start AP if not connected after timeout)
144
  if (!server.startWiFi(10000)) {
145
    Serial.println("\nWiFi not connected! Starting AP mode...");
146
    server.startCaptivePortal("ESP_AP", "123456789", "/setup");
147
  }
148
 
149
  // Add custom page handler
150
  server.on("/reload", HTTP_GET, handleLoadOptions);
151
 
152
  // Configure /setup page and start Web Server
153
  server.addOptionBox("My Options");
154
  server.addOption(BOOL_LABEL, boolVar);
155
  server.addOption(BOOL_LABEL2, boolVar2);
156
  server.addOption(LED_LABEL, ledPin);
157
  server.addOption(LONG_LABEL, longVar);
158
  server.addOption(FLOAT_LABEL, floatVar, 1.0, 100.0, 0.01);
159
  server.addOption(STRING_LABEL, stringVar);
160
  server.addDropdownList(dayOfWeek);
161
  server.addSlider(brightness);  
162
  server.addHTML(reload_btn_htm, "buttons", /*overwrite*/ false);
163
  server.addJavascript(reload_btn_script, "js", /*overwrite*/ false);
164
 
165
  // Enable ACE FS file web editor and add FS info callback function    
166
  server.enableFsCodeEditor();
167
 
168
  // set /setup and /edit page authentication
169
  server.setAuthentication("admin", "admin");
170
 
171
  // Inform user when config.json is saved via /edit or /upload
172
  server.setConfigSavedCallback(onConfigSaved);
173
 
174
  // Start server
175
  server.init();
176
  Serial.print(F("\nESP Web Server started on IP Address: "));
177
  Serial.println(server.getServerIP());
178
  Serial.println(F(
179
      "\nThis is \"customOptions.ino\" example.\n"
180
      "Open /setup page to configure optional parameters.\n"
181
      "Open /edit page to view, edit or upload example or your custom webserver source files."
182
  ));
183
}
184
 
185
void loop() {
186
  if (server.isAccessPointMode())
187
    server.updateDNS();
188
 
189
  // Keep BOOT_PIN pressed 5 seconds to clear application options
190
  static uint32_t buttonPressStart = 0;
191
  static bool buttonPressed = false;
192
 
193
  if (digitalRead(BOOT_PIN) == LOW) {
194
    if (!buttonPressed) {
195
      buttonPressed = true;
196
      buttonPressStart = millis();
197
    } 
198
    else if (millis() - buttonPressStart >= 5000) {
199
      Serial.println("\nClearing application options...");
200
      server.clearConfigFile();
201
      delay(1000);
202
      ESP.restart();
203
    }
204
  } else {
205
    buttonPressed = false;
206
  }
207
 
208
  // Nothing to do here, just a small delay for task yield
209
  delay(10);  
210
}