mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
add initial version of asynchronous webserver
This commit is contained in:
parent
ace426cf2c
commit
34ab0a0900
6 changed files with 217 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
||||||
# Ignore any .vscode folder
|
# Ignore any .vscode folder
|
||||||
*.vscode/
|
*.vscode/
|
||||||
|
|
||||||
|
# Ignore any files in the build folder
|
||||||
|
Software/build/
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "USER_SETTINGS.h"
|
#include "USER_SETTINGS.h"
|
||||||
#include "src/battery/BATTERIES.h"
|
#include "src/battery/BATTERIES.h"
|
||||||
#include "src/devboard/config.h"
|
#include "src/devboard/config.h"
|
||||||
|
#include "src/devboard/webserver/webserver.h"
|
||||||
#include "src/inverter/INVERTERS.h"
|
#include "src/inverter/INVERTERS.h"
|
||||||
#include "src/lib/adafruit-Adafruit_NeoPixel/Adafruit_NeoPixel.h"
|
#include "src/lib/adafruit-Adafruit_NeoPixel/Adafruit_NeoPixel.h"
|
||||||
#include "src/lib/eModbus-eModbus/Logging.h"
|
#include "src/lib/eModbus-eModbus/Logging.h"
|
||||||
|
@ -109,6 +110,8 @@ bool inverterAllowsContactorClosing = true;
|
||||||
void setup() {
|
void setup() {
|
||||||
init_serial();
|
init_serial();
|
||||||
|
|
||||||
|
init_webserver();
|
||||||
|
|
||||||
init_CAN();
|
init_CAN();
|
||||||
|
|
||||||
init_LED();
|
init_LED();
|
||||||
|
|
6
Software/USER_SETTINGS.cpp
Normal file
6
Software/USER_SETTINGS.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "USER_SETTINGS.h"
|
||||||
|
|
||||||
|
const char* ssid = "REPLACE_WITH_YOUR_SSID"; // maximum of 63 characters;
|
||||||
|
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // minimum of 8 characters;
|
||||||
|
const char* ssidAP = "Battery Emulator"; // maximum of 63 characters;
|
||||||
|
const char* passwordAP = "123456789"; // minimum of 8 characters; set to NULL if you want the access point to be open
|
39
Software/src/devboard/webserver/README.md
Normal file
39
Software/src/devboard/webserver/README.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Battery Emulator Webserver
|
||||||
|
This webserver creates a WiFi access point. It also connects ot an existing network.
|
||||||
|
The webserver intends to display useful information to the user of the battery emulator
|
||||||
|
development board, without the need to physically connect to the board via USB.
|
||||||
|
The webserver implementation also provides the option to update the firmware of the board over the air.
|
||||||
|
|
||||||
|
To use the webserver, follow the following steps:
|
||||||
|
- Connect to the board via Serial, and boot up the board.
|
||||||
|
- The IP address of the WiFi access point is printed to Serial when the board boots up. Note this down.
|
||||||
|
- Connect to the access point created by board via a WiFi-capable device
|
||||||
|
- On that device, open a webbrowser and type the IP address of the WiFi access point.
|
||||||
|
- If the ssid and password of an existing WiFi network are provided, the board will also connect to this network. The IP address obtained on the existing network is shown in the webserver. Note this down.
|
||||||
|
- From this point onwards, any device connected to the existing WiFi network can access the webserver via a webbrowser. To do this:
|
||||||
|
- Connect your WiFi-capable device to the existing nwetork.
|
||||||
|
- Open a webbrowser and type the IP address obtained on the existing WiFi network.
|
||||||
|
|
||||||
|
To update the software over the air:
|
||||||
|
- In Arduino, go to `Sketch` > `Export Compiled Binary`. This will create the `.bin` file that you need to update the firmware. It is found in the folder `Software/build/`
|
||||||
|
- In your webbrowser, go to the url consisting of the IP address, followed by `/update`, for instance `http://192.168.0.224/update`.
|
||||||
|
- In the webbrowser, follow the steps to select the `.bin` file and to upload the file to the board.
|
||||||
|
|
||||||
|
## Future work
|
||||||
|
This section lists a number of features that can be implemented as part of the webserver in the future.
|
||||||
|
|
||||||
|
- TODO: display state of charge
|
||||||
|
- TODO: display battery hardware selected
|
||||||
|
- TODO: display emulated inverter communication protocol selected
|
||||||
|
- TODO: list all available ssids: scan WiFi Networks https://randomnerdtutorials.com/esp32-useful-wi-fi-functions-arduino/
|
||||||
|
- TODO: add option to add/change ssid and password and save, connect to the new ssid (Option: save ssid and password using Preferences.h library https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/)
|
||||||
|
- TODO: display WiFi connection strength (https://randomnerdtutorials.com/esp32-useful-wi-fi-functions-arduino/)
|
||||||
|
- TODO: display CAN state (indicate if there is a communication error)
|
||||||
|
- TODO: display battery errors in battery diagnosis tab
|
||||||
|
- TODO: display inverter errors in battery diagnosis tab
|
||||||
|
- TODO: add functionality to turn WiFi AP off
|
||||||
|
- TODO: fix IP address on home network (https://randomnerdtutorials.com/esp32-static-fixed-ip-address-arduino-ide/)
|
||||||
|
- TODO: set hostname (https://randomnerdtutorials.com/esp32-set-custom-hostname-arduino/)
|
||||||
|
|
||||||
|
# References
|
||||||
|
The code for this webserver is based on code provided by Rui Santos at https://randomnerdtutorials.com.
|
112
Software/src/devboard/webserver/webserver.cpp
Normal file
112
Software/src/devboard/webserver/webserver.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#include "webserver.h"
|
||||||
|
|
||||||
|
// Create AsyncWebServer object on port 80
|
||||||
|
AsyncWebServer server(80);
|
||||||
|
|
||||||
|
const char index_html[] PROGMEM = R"rawliteral(
|
||||||
|
<!DOCTYPE HTML><html>
|
||||||
|
<head>
|
||||||
|
<title>Battery Emulator Web Server</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href="data:,">
|
||||||
|
<style>
|
||||||
|
html {font-family: Arial; display: inline-block; text-align: center;}
|
||||||
|
h2 {font-size: 3.0rem;}
|
||||||
|
p {font-size: 3.0rem;}
|
||||||
|
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
|
||||||
|
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
|
||||||
|
.switch input {display: none}
|
||||||
|
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 6px}
|
||||||
|
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px}
|
||||||
|
input:checked+.slider {background-color: #b30000}
|
||||||
|
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Battery Emulator Web Server</h2>
|
||||||
|
%PLACEHOLDER%
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)rawliteral";
|
||||||
|
|
||||||
|
String wifi_state;
|
||||||
|
bool wifi_connected;
|
||||||
|
|
||||||
|
// Wifi connect time declarations and definition
|
||||||
|
unsigned long wifi_connect_start_time;
|
||||||
|
unsigned long wifi_connect_current_time;
|
||||||
|
const long wifi_connect_timeout = 5000; // Timeout for WiFi connect in milliseconds
|
||||||
|
|
||||||
|
void init_webserver() {
|
||||||
|
// Configure WiFi
|
||||||
|
WiFi.mode(WIFI_AP_STA); // Simultaneous WiFi Access Point and WiFi STAtion
|
||||||
|
init_WiFi_AP();
|
||||||
|
init_WiFi_STA(ssid, password);
|
||||||
|
|
||||||
|
// Route for root / web page
|
||||||
|
server.on("/", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest* request) { request->send_P(200, "text/html", index_html, processor); });
|
||||||
|
|
||||||
|
// Send a GET request to <ESP_IP>/update
|
||||||
|
server.on("/update", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "OK"); });
|
||||||
|
|
||||||
|
// Start server
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_WiFi_AP() {
|
||||||
|
Serial.print("Creating Access Point: ");
|
||||||
|
Serial.println(ssidAP);
|
||||||
|
Serial.print("With password: ");
|
||||||
|
Serial.println(passwordAP);
|
||||||
|
|
||||||
|
WiFi.softAP(ssidAP, passwordAP);
|
||||||
|
|
||||||
|
IPAddress IP = WiFi.softAPIP();
|
||||||
|
Serial.println("Access Point created.");
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_WiFi_STA(const char* ssid, const char* password) {
|
||||||
|
// Connect to Wi-Fi network with SSID and password
|
||||||
|
Serial.print("Connecting to ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
|
||||||
|
wifi_connect_start_time = millis();
|
||||||
|
wifi_connect_current_time = wifi_connect_start_time;
|
||||||
|
while ((wifi_connect_current_time - wifi_connect_start_time) <= wifi_connect_timeout &&
|
||||||
|
WiFi.status() != WL_CONNECTED) { // do this loop for up to 5000ms
|
||||||
|
// to break the loop when the connection is not established (wrong ssid or password).
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
wifi_connect_current_time = millis();
|
||||||
|
}
|
||||||
|
if (WiFi.status() == WL_CONNECTED) { // WL_CONNECTED is assigned when connected to a WiFi network
|
||||||
|
wifi_connected = true;
|
||||||
|
wifi_state = "connected";
|
||||||
|
// Print local IP address and start web server
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print("Connected to WiFi network: ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
} else {
|
||||||
|
wifi_connected = false;
|
||||||
|
wifi_state = "not connected";
|
||||||
|
Serial.print("Not connected to WiFi network: ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
Serial.println("Please check WiFi network name and password, and if WiFi network is available.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String processor(const String& var) {
|
||||||
|
if (var == "PLACEHOLDER") {
|
||||||
|
String content = "";
|
||||||
|
content += "<h4>Output</h4>";
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
return String();
|
||||||
|
}
|
54
Software/src/devboard/webserver/webserver.h
Normal file
54
Software/src/devboard/webserver/webserver.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef WEBSERVER_H
|
||||||
|
#define WEBSERVER_H
|
||||||
|
|
||||||
|
// Load Wi-Fi library
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include "../../../USER_SETTINGS.h" // Needed for WiFi ssid and password
|
||||||
|
#include "../../lib/me-no-dev-AsyncTCP/src/AsyncTCP.h"
|
||||||
|
#include "../../lib/me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h"
|
||||||
|
#include "../config.h" // Needed for LED defines
|
||||||
|
|
||||||
|
extern uint8_t LEDcolor; // Enum, 0-10
|
||||||
|
extern const char* ssid;
|
||||||
|
extern const char* password;
|
||||||
|
extern const char* ssidAP;
|
||||||
|
extern const char* passwordAP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization function for the webserver.
|
||||||
|
*
|
||||||
|
* @param[in] void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void init_webserver();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization function that creates a WiFi Access Point.
|
||||||
|
*
|
||||||
|
* @param[in] void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void init_WiFi_AP();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization function that connects to an existing network.
|
||||||
|
*
|
||||||
|
* @param[in] ssid WiFi network name
|
||||||
|
* @param[in] password WiFi network password
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void init_WiFi_STA(const char* ssid, const char* password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces placeholder with content section in web page
|
||||||
|
*
|
||||||
|
* @param[in] var
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
String processor(const String& var);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue