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
|
||||
roboticsbrno/SmartLeds@^3.1.5
|
||||
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
|
||||
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_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_CB_SERIAL "REDAone_prototype00"
|
||||
#define CFG_CP_FW_VERSION "1.0.0"
|
||||
#define CFG_CP_MODAL "Helios DA One"
|
||||
#define CFG_CP_VENDOR "RayineElec"
|
||||
#define CFG_AUTHORIZATIONKEY "my_secret_key"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiManager.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <MicroOcpp.h>
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <MFRC522.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "smartconfig.h"
|
||||
#include "config.h"
|
||||
|
||||
/* LED State Enum */
|
||||
@@ -22,8 +21,6 @@ enum LEDState
|
||||
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 volatile bool s_ocpp_connected = false;
|
||||
static volatile LEDState s_led_state = LED_INITIALIZING;
|
||||
@@ -35,7 +32,6 @@ uint8_t mac[6];
|
||||
char cpSerial[13];
|
||||
|
||||
struct mg_mgr mgr;
|
||||
// MicroOcpp::MOcppMongooseClient *client = nullptr;
|
||||
|
||||
/**
|
||||
* WS2812B LED Pin
|
||||
@@ -47,44 +43,6 @@ struct mg_mgr mgr;
|
||||
|
||||
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 */
|
||||
void updateLED()
|
||||
{
|
||||
@@ -152,73 +110,188 @@ void setup()
|
||||
s_blink_last_time = 0;
|
||||
s_blink_on = false;
|
||||
|
||||
// Initialize WiFi
|
||||
// WiFi.onEvent(WiFiEvent);
|
||||
// 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);
|
||||
leds[0] = Rgb{255, 255, 0};
|
||||
leds.show();
|
||||
|
||||
// Wait for WiFi connection with LED updates
|
||||
// int retry = 0;
|
||||
// while (WiFi.status() != WL_CONNECTED && retry < 20)
|
||||
// {
|
||||
// delay(200);
|
||||
// updateLED(); // Update LED while waiting for WiFi
|
||||
// Serial.print(".");
|
||||
// retry++;
|
||||
// }
|
||||
// Serial.println();
|
||||
WiFiManager wm;
|
||||
const char *customHeadElement = R"rawliteral(
|
||||
<style>
|
||||
:root {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
color: #1f2a37;
|
||||
--primarycolor: #2563eb;
|
||||
}
|
||||
|
||||
if (!connectToSavedWiFi())
|
||||
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)
|
||||
{
|
||||
String ssidPrefix = CFG_CP_MODAL + String("_") + String(cpSerial).substring(String(cpSerial).length() - 6);
|
||||
char ssidPrefixBuffer[32];
|
||||
strcpy(ssidPrefixBuffer, ssidPrefix.c_str());
|
||||
startSmartConfig(ssidPrefixBuffer, cpSerial);
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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()
|
||||
{
|
||||
if (!smartconfig_done)
|
||||
{
|
||||
dnsServer.processNextRequest();
|
||||
server.handleClient();
|
||||
}
|
||||
if (should_reboot)
|
||||
{
|
||||
Serial.println("Rebooting...");
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
mg_mgr_poll(&mgr, 10);
|
||||
mocpp_loop();
|
||||
|
||||
// Check OCPP connection status
|
||||
// if (s_wifi_connected)
|
||||
// {
|
||||
// auto ctx = getOcppContext();
|
||||
// if (ctx && ctx->getConnection().isConnected())
|
||||
// {
|
||||
// if (s_led_state != LED_OCPP_CONNECTED)
|
||||
// {
|
||||
// s_led_state = LED_OCPP_CONNECTED;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (s_led_state != LED_WIFI_CONNECTED)
|
||||
// {
|
||||
// s_led_state = LED_WIFI_CONNECTED;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
auto ctx = getOcppContext();
|
||||
if (ctx && ctx->getConnection().isConnected())
|
||||
{
|
||||
if (s_led_state != LED_OCPP_CONNECTED)
|
||||
{
|
||||
s_led_state = LED_OCPP_CONNECTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_led_state != LED_WIFI_CONNECTED)
|
||||
{
|
||||
s_led_state = LED_WIFI_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
updateLED();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user