feat(firmware): integrate WiFiManager for improved WiFi configuration and connection handling
This commit is contained in:
@@ -17,5 +17,6 @@ lib_deps =
|
|||||||
matth-x/MicroOcppMongoose@^1.2.0
|
matth-x/MicroOcppMongoose@^1.2.0
|
||||||
roboticsbrno/SmartLeds@^3.1.5
|
roboticsbrno/SmartLeds@^3.1.5
|
||||||
miguelbalboa/MFRC522@^1.4.12
|
miguelbalboa/MFRC522@^1.4.12
|
||||||
|
tzapu/WiFiManager@^2.0.17
|
||||||
build_flags = -DMO_PLATFORM=MO_PLATFORM_ARDUINO -DMO_MG_USE_VERSION=MO_MG_V715 -DMO_NUMCONNECTORS=3
|
build_flags = -DMO_PLATFORM=MO_PLATFORM_ARDUINO -DMO_MG_USE_VERSION=MO_MG_V715 -DMO_NUMCONNECTORS=3
|
||||||
board_build.partitions = partitions.csv
|
board_build.partitions = partitions.csv
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#define CFG_WIFI_SSID "MisakaNetwork"
|
|
||||||
#define CFG_WIFI_PASS "20211028"
|
|
||||||
#define CFG_WIFI_MAXIMUM_RETRY 5
|
#define CFG_WIFI_MAXIMUM_RETRY 5
|
||||||
#define CFG_OCPP_BACKEND "ws://192.168.1.100:8180/steve/websocket/CentralSystemService"
|
#define CFG_OCPP_BACKEND "ws://csms.helios.bh8.ga:8180/steve/websocket/CentralSystemService"
|
||||||
#define CFG_CP_IDENTIFIER "CQWU_HHB_0001"
|
#define CFG_CP_IDENTIFIER "CQWU_HHB_0001"
|
||||||
#define CFG_CB_SERIAL "REDAone_prototype00"
|
#define CFG_CB_SERIAL "REDAone_prototype00"
|
||||||
|
#define CFG_CP_FW_VERSION "1.0.0"
|
||||||
#define CFG_CP_MODAL "Helios DA One"
|
#define CFG_CP_MODAL "Helios DA One"
|
||||||
#define CFG_CP_VENDOR "RayineElec"
|
#define CFG_CP_VENDOR "RayineElec"
|
||||||
#define CFG_AUTHORIZATIONKEY "my_secret_key"
|
#define CFG_AUTHORIZATIONKEY "my_secret_key"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <WiFi.h>
|
#include <WiFiManager.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <MicroOcpp.h>
|
#include <MicroOcpp.h>
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <MFRC522.h>
|
#include <MFRC522.h>
|
||||||
|
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "smartconfig.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
/* LED State Enum */
|
/* LED State Enum */
|
||||||
@@ -22,8 +21,6 @@ enum LEDState
|
|||||||
LED_ERROR // Red - Error state
|
LED_ERROR // Red - Error state
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FreeRTOS event group to signal when we are connected*/
|
|
||||||
static volatile bool s_wifi_connected = false;
|
|
||||||
static int s_retry_num = 0;
|
static int s_retry_num = 0;
|
||||||
static volatile bool s_ocpp_connected = false;
|
static volatile bool s_ocpp_connected = false;
|
||||||
static volatile LEDState s_led_state = LED_INITIALIZING;
|
static volatile LEDState s_led_state = LED_INITIALIZING;
|
||||||
@@ -35,7 +32,6 @@ uint8_t mac[6];
|
|||||||
char cpSerial[13];
|
char cpSerial[13];
|
||||||
|
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
// MicroOcpp::MOcppMongooseClient *client = nullptr;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WS2812B LED Pin
|
* WS2812B LED Pin
|
||||||
@@ -47,44 +43,6 @@ struct mg_mgr mgr;
|
|||||||
|
|
||||||
SmartLed leds(LED_WS2812B, LED_COUNT, LED_PIN, 0, DoubleBuffer);
|
SmartLed leds(LED_WS2812B, LED_COUNT, LED_PIN, 0, DoubleBuffer);
|
||||||
|
|
||||||
// WiFi event handler
|
|
||||||
static void WiFiEvent(WiFiEvent_t event)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case ARDUINO_EVENT_WIFI_STA_START:
|
|
||||||
Serial.println("WiFi STA started");
|
|
||||||
s_led_state = LED_INITIALIZING;
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
|
||||||
if (s_retry_num < CFG_WIFI_MAXIMUM_RETRY)
|
|
||||||
{
|
|
||||||
s_retry_num++;
|
|
||||||
Serial.println("Retry to connect to the AP");
|
|
||||||
s_led_state = LED_INITIALIZING;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_wifi_connected = false;
|
|
||||||
Serial.println("Failed to connect to AP");
|
|
||||||
s_led_state = LED_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
|
|
||||||
Serial.println("WiFi connected");
|
|
||||||
Serial.printf("- Hostname: %s\n", WiFi.getHostname());
|
|
||||||
break;
|
|
||||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
|
||||||
Serial.println("Got IP: " + WiFi.localIP().toString());
|
|
||||||
s_retry_num = 0;
|
|
||||||
s_wifi_connected = true;
|
|
||||||
s_led_state = LED_WIFI_CONNECTED;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LED Control Functions */
|
/* LED Control Functions */
|
||||||
void updateLED()
|
void updateLED()
|
||||||
{
|
{
|
||||||
@@ -152,73 +110,188 @@ void setup()
|
|||||||
s_blink_last_time = 0;
|
s_blink_last_time = 0;
|
||||||
s_blink_on = false;
|
s_blink_on = false;
|
||||||
|
|
||||||
// Initialize WiFi
|
leds[0] = Rgb{255, 255, 0};
|
||||||
// WiFi.onEvent(WiFiEvent);
|
leds.show();
|
||||||
// WiFi.mode(WIFI_STA);
|
|
||||||
// WiFi.setHostname((CFG_CP_MODAL + String("_") + String(cpSerial).substring(String(cpSerial).length() - 6)).c_str());
|
|
||||||
// WiFi.begin(CFG_WIFI_SSID, CFG_WIFI_PASS);
|
|
||||||
|
|
||||||
// Wait for WiFi connection with LED updates
|
WiFiManager wm;
|
||||||
// int retry = 0;
|
const char *customHeadElement = R"rawliteral(
|
||||||
// while (WiFi.status() != WL_CONNECTED && retry < 20)
|
<style>
|
||||||
// {
|
:root {
|
||||||
// delay(200);
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||||
// updateLED(); // Update LED while waiting for WiFi
|
color: #1f2a37;
|
||||||
// Serial.print(".");
|
--primarycolor: #2563eb;
|
||||||
// retry++;
|
|
||||||
// }
|
|
||||||
// Serial.println();
|
|
||||||
|
|
||||||
if (!connectToSavedWiFi())
|
|
||||||
{
|
|
||||||
String ssidPrefix = CFG_CP_MODAL + String("_") + String(cpSerial).substring(String(cpSerial).length() - 6);
|
|
||||||
char ssidPrefixBuffer[32];
|
|
||||||
strcpy(ssidPrefixBuffer, ssidPrefix.c_str());
|
|
||||||
startSmartConfig(ssidPrefixBuffer, cpSerial);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
body,
|
||||||
|
body.invert {
|
||||||
|
margin: 0;
|
||||||
|
background: #f4f6fb;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px;
|
||||||
|
color: #1f2a37;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
width: min(360px, 100%);
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #111827;
|
||||||
|
margin-top: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
button {
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="password"],
|
||||||
|
input[type="number"],
|
||||||
|
input[type="email"],
|
||||||
|
select {
|
||||||
|
padding: 12px;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
border: 1px solid #d0d7e2;
|
||||||
|
background: #f9fafc;
|
||||||
|
transition: border 0.2s, box-shadow 0.2s, background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus,
|
||||||
|
select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #2563eb;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input[type="submit"],
|
||||||
|
button.D {
|
||||||
|
padding: 12px;
|
||||||
|
border: none;
|
||||||
|
background: #2563eb;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s, transform 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.D {
|
||||||
|
background: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover,
|
||||||
|
input[type="submit"]:hover {
|
||||||
|
background: #1d4ed8;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active,
|
||||||
|
input[type="submit"]:active {
|
||||||
|
transform: scale(0.99);
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg {
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
background: #f9fafb;
|
||||||
|
padding: 16px;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg.P {
|
||||||
|
border-color: #2563eb;
|
||||||
|
background: rgba(37, 99, 235, 0.08);
|
||||||
|
color: #1f2a37;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg.S {
|
||||||
|
border-color: #16a34a;
|
||||||
|
background: rgba(22, 163, 74, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg.D {
|
||||||
|
border-color: #dc2626;
|
||||||
|
background: rgba(220, 38, 38, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.q {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #2563eb;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
background: #e5e7eb;
|
||||||
|
margin: 24px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
)rawliteral";
|
||||||
|
wm.setCustomHeadElement(customHeadElement);
|
||||||
|
bool autoConnectRet = wm.autoConnect((String("HLCP_") + String(cpSerial).substring(String(cpSerial).length() - 6)).c_str(), cpSerial);
|
||||||
|
if (!autoConnectRet)
|
||||||
|
{
|
||||||
|
Serial.println("Failed to connect and hit timeout");
|
||||||
|
s_led_state = LED_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.println("WiFi connected successfully");
|
||||||
|
s_led_state = LED_WIFI_CONNECTED;
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
MicroOcpp::MOcppMongooseClient *client = new MicroOcpp::MOcppMongooseClient(&mgr, CFG_OCPP_BACKEND, CFG_CP_IDENTIFIER, CFG_AUTHORIZATIONKEY, "", MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail), MicroOcpp::ProtocolVersion(1, 6));
|
MicroOcpp::MOcppMongooseClient *client = new MicroOcpp::MOcppMongooseClient(&mgr, CFG_OCPP_BACKEND, CFG_CP_IDENTIFIER, CFG_AUTHORIZATIONKEY, "", MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail), MicroOcpp::ProtocolVersion(1, 6));
|
||||||
mocpp_initialize(*client, ChargerCredentials(CFG_CP_MODAL, CFG_CP_VENDOR, "1.0.0", cpSerial, nullptr, nullptr, CFG_CB_SERIAL, nullptr, nullptr), MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail));
|
mocpp_initialize(*client, ChargerCredentials(CFG_CP_MODAL, CFG_CP_VENDOR, CFG_CP_FW_VERSION, cpSerial, nullptr, nullptr, CFG_CB_SERIAL, nullptr, nullptr), MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
if (!smartconfig_done)
|
|
||||||
{
|
|
||||||
dnsServer.processNextRequest();
|
|
||||||
server.handleClient();
|
|
||||||
}
|
|
||||||
if (should_reboot)
|
|
||||||
{
|
|
||||||
Serial.println("Rebooting...");
|
|
||||||
delay(1000);
|
|
||||||
ESP.restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
mg_mgr_poll(&mgr, 10);
|
mg_mgr_poll(&mgr, 10);
|
||||||
mocpp_loop();
|
mocpp_loop();
|
||||||
|
|
||||||
// Check OCPP connection status
|
auto ctx = getOcppContext();
|
||||||
// if (s_wifi_connected)
|
if (ctx && ctx->getConnection().isConnected())
|
||||||
// {
|
{
|
||||||
// auto ctx = getOcppContext();
|
if (s_led_state != LED_OCPP_CONNECTED)
|
||||||
// if (ctx && ctx->getConnection().isConnected())
|
{
|
||||||
// {
|
s_led_state = LED_OCPP_CONNECTED;
|
||||||
// if (s_led_state != LED_OCPP_CONNECTED)
|
}
|
||||||
// {
|
}
|
||||||
// s_led_state = LED_OCPP_CONNECTED;
|
else
|
||||||
// }
|
{
|
||||||
// }
|
if (s_led_state != LED_WIFI_CONNECTED)
|
||||||
// else
|
{
|
||||||
// {
|
s_led_state = LED_WIFI_CONNECTED;
|
||||||
// if (s_led_state != LED_WIFI_CONNECTED)
|
}
|
||||||
// {
|
}
|
||||||
// s_led_state = LED_WIFI_CONNECTED;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
updateLED();
|
updateLED();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user