Updated WIFI on esp and svelte side to use proto
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <template/state_result.h>
|
||||
#include <string>
|
||||
#include <platform_shared/api.pb.h>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef FACTORY_WIFI_SSID
|
||||
#define FACTORY_WIFI_SSID ""
|
||||
@@ -21,118 +21,39 @@
|
||||
#define FACTORY_WIFI_RSSI_THRESHOLD -80
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
std::string ssid;
|
||||
uint8_t bssid[6];
|
||||
int32_t channel;
|
||||
std::string password;
|
||||
bool staticIPConfig;
|
||||
IPAddress localIP;
|
||||
IPAddress gatewayIP;
|
||||
IPAddress subnetMask;
|
||||
IPAddress dnsIP1;
|
||||
IPAddress dnsIP2;
|
||||
bool available;
|
||||
using WiFiNetwork = api_WifiNetwork;
|
||||
using WiFiSettings = api_WifiSettings;
|
||||
|
||||
void serialize(JsonVariant &json) const {
|
||||
json["ssid"] = ssid.c_str();
|
||||
json["password"] = password.c_str();
|
||||
json["static_ip_config"] = staticIPConfig;
|
||||
if (staticIPConfig) {
|
||||
json["local_ip"] = (uint32_t)(localIP);
|
||||
json["gateway_ip"] = (uint32_t)(gatewayIP);
|
||||
json["subnet_mask"] = (uint32_t)(subnetMask);
|
||||
json["dns_ip_1"] = (uint32_t)(dnsIP1);
|
||||
json["dns_ip_2"] = (uint32_t)(dnsIP2);
|
||||
}
|
||||
}
|
||||
|
||||
bool deserialize(const JsonVariant &json) {
|
||||
std::string newSsid = json["ssid"].as<std::string>();
|
||||
std::string newPassword = json["password"].as<std::string>();
|
||||
if (newSsid.length() < 1 || newSsid.length() > 31 || newPassword.length() > 64) {
|
||||
ESP_LOGE("WiFiSettings", "SSID or password length is invalid");
|
||||
return false;
|
||||
}
|
||||
ssid = newSsid;
|
||||
password = newPassword;
|
||||
staticIPConfig = json["static_ip_config"] | false;
|
||||
if (staticIPConfig) {
|
||||
localIP = IPAddress(json["local_ip"] | 0u);
|
||||
gatewayIP = IPAddress(json["gateway_ip"] | 0u);
|
||||
subnetMask = IPAddress(json["subnet_mask"] | 0u);
|
||||
dnsIP1 = IPAddress(json["dns_ip_1"] | 0u);
|
||||
dnsIP2 = IPAddress(json["dns_ip_2"] | 0u);
|
||||
if (dnsIP1 == IPAddress(0, 0, 0, 0) && dnsIP2 != IPAddress(0, 0, 0, 0)) {
|
||||
dnsIP1 = dnsIP2;
|
||||
dnsIP2 = IPAddress(0, 0, 0, 0);
|
||||
}
|
||||
if (localIP == IPAddress(0, 0, 0, 0) || gatewayIP == IPAddress(0, 0, 0, 0) ||
|
||||
subnetMask == IPAddress(0, 0, 0, 0)) {
|
||||
staticIPConfig = false;
|
||||
ESP_LOGW("WiFiSettings", "Invalid static IP configuration - falling back to DHCP");
|
||||
}
|
||||
}
|
||||
available = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} wifi_settings_t;
|
||||
|
||||
inline wifi_settings_t createDefaultWiFiSettings() {
|
||||
return wifi_settings_t {
|
||||
.ssid = FACTORY_WIFI_SSID,
|
||||
.bssid = {0},
|
||||
.channel = -1,
|
||||
.password = FACTORY_WIFI_PASSWORD,
|
||||
.staticIPConfig = false,
|
||||
.localIP = IPAddress(0, 0, 0, 0),
|
||||
.gatewayIP = IPAddress(0, 0, 0, 0),
|
||||
.subnetMask = IPAddress(0, 0, 0, 0),
|
||||
.dnsIP1 = IPAddress(0, 0, 0, 0),
|
||||
.dnsIP2 = IPAddress(0, 0, 0, 0),
|
||||
.available = false,
|
||||
};
|
||||
inline WiFiNetwork WiFiNetwork_defaults() {
|
||||
WiFiNetwork network = api_WifiNetwork_init_zero;
|
||||
strncpy(network.ssid, FACTORY_WIFI_SSID, sizeof(network.ssid) - 1);
|
||||
strncpy(network.password, FACTORY_WIFI_PASSWORD, sizeof(network.password) - 1);
|
||||
network.static_ip_config = false;
|
||||
network.local_ip = 0;
|
||||
network.gateway_ip = 0;
|
||||
network.subnet_mask = 0;
|
||||
network.dns_ip_1 = 0;
|
||||
network.dns_ip_2 = 0;
|
||||
return network;
|
||||
}
|
||||
|
||||
class WiFiSettings {
|
||||
public:
|
||||
std::string hostname;
|
||||
bool priorityBySignalStrength;
|
||||
std::vector<wifi_settings_t> wifiSettings;
|
||||
static void read(WiFiSettings &settings, JsonVariant &root) {
|
||||
root["hostname"] = settings.hostname.c_str();
|
||||
root["priority_RSSI"] = settings.priorityBySignalStrength;
|
||||
JsonArray wifiNetworks = root["wifi_networks"].to<JsonArray>();
|
||||
for (const auto &wifi : settings.wifiSettings) {
|
||||
JsonVariant wifiNetwork = wifiNetworks.add<JsonVariant>();
|
||||
wifi.serialize(wifiNetwork);
|
||||
}
|
||||
ESP_LOGV("WiFiSettings", "WiFi Settings read");
|
||||
inline WiFiSettings WiFiSettings_defaults() {
|
||||
WiFiSettings settings = api_WifiSettings_init_zero;
|
||||
strncpy(settings.hostname, FACTORY_WIFI_HOSTNAME, sizeof(settings.hostname) - 1);
|
||||
settings.priority_rssi = true;
|
||||
settings.wifi_networks_count = 0;
|
||||
if (strlen(FACTORY_WIFI_SSID) > 0) {
|
||||
settings.wifi_networks[0] = WiFiNetwork_defaults();
|
||||
settings.wifi_networks_count = 1;
|
||||
}
|
||||
static StateUpdateResult update(JsonVariant &root, WiFiSettings &settings) {
|
||||
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
|
||||
settings.priorityBySignalStrength = root["priority_RSSI"] | true;
|
||||
settings.wifiSettings.clear();
|
||||
if (root["wifi_networks"].is<JsonArray>()) {
|
||||
JsonArray wifiNetworks = root["wifi_networks"];
|
||||
int networkCount = 0;
|
||||
for (JsonVariant wifiNetwork : wifiNetworks) {
|
||||
if (networkCount >= 5) {
|
||||
ESP_LOGE("WiFiSettings", "Too many wifi networks");
|
||||
break;
|
||||
}
|
||||
wifi_settings_t newSettings;
|
||||
if (newSettings.deserialize(wifiNetwork)) {
|
||||
settings.wifiSettings.push_back(newSettings);
|
||||
networkCount++;
|
||||
}
|
||||
}
|
||||
} else if (std::string(FACTORY_WIFI_SSID).length() > 0) {
|
||||
ESP_LOGI("WiFiSettings", "No WiFi config found - using factory settings");
|
||||
settings.wifiSettings.push_back(createDefaultWiFiSettings());
|
||||
}
|
||||
ESP_LOGV("WiFiSettings", "WiFi Settings updated");
|
||||
return StateUpdateResult::CHANGED;
|
||||
}
|
||||
};
|
||||
return settings;
|
||||
}
|
||||
|
||||
inline void WiFiSettings_read(const WiFiSettings &settings, WiFiSettings &proto) {
|
||||
proto = settings;
|
||||
}
|
||||
|
||||
inline StateUpdateResult WiFiSettings_update(const WiFiSettings &proto, WiFiSettings &settings) {
|
||||
settings = proto;
|
||||
return StateUpdateResult::CHANGED;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
#include <esp_http_server.h>
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <string>
|
||||
|
||||
#include <filesystem.h>
|
||||
#include <utils/timing.h>
|
||||
#include <template/stateful_service.h>
|
||||
#include <template/stateful_persistence.h>
|
||||
#include <template/stateful_endpoint.h>
|
||||
#include <template/stateful_persistence_pb.h>
|
||||
#include <template/stateful_proto_endpoint.h>
|
||||
#include <settings/wifi_settings.h>
|
||||
|
||||
#define WIFI_SETTINGS_FILE "/config/wifiSettings.pb"
|
||||
|
||||
class WiFiService : public StatefulService<WiFiSettings> {
|
||||
private:
|
||||
static void getNetworks(JsonObject &root);
|
||||
@@ -20,12 +23,12 @@ class WiFiService : public StatefulService<WiFiSettings> {
|
||||
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||
|
||||
FSPersistence<WiFiSettings> _persistence;
|
||||
FSPersistencePB<WiFiSettings> _persistence;
|
||||
|
||||
void reconfigureWiFiConnection();
|
||||
void manageSTA();
|
||||
void connectToWiFi();
|
||||
void configureNetwork(wifi_settings_t &network);
|
||||
void configureNetwork(WiFiNetwork &network);
|
||||
|
||||
unsigned long _lastConnectionAttempt;
|
||||
bool _stopping;
|
||||
@@ -41,11 +44,11 @@ class WiFiService : public StatefulService<WiFiSettings> {
|
||||
|
||||
void setupMDNS(const char *hostname);
|
||||
|
||||
const char *getHostname() { return state().hostname.c_str(); }
|
||||
const char *getHostname() { return state().hostname; }
|
||||
|
||||
static esp_err_t handleScan(httpd_req_t *request);
|
||||
static esp_err_t getNetworks(httpd_req_t *request);
|
||||
static esp_err_t getNetworkStatus(httpd_req_t *request);
|
||||
|
||||
StatefulHttpEndpoint<WiFiSettings> endpoint;
|
||||
StatefulProtoEndpoint<WiFiSettings, api_WifiSettings> protoEndpoint;
|
||||
};
|
||||
|
||||
+3
-5
@@ -65,11 +65,10 @@ void setupServer() {
|
||||
return servoController.protoEndpoint.handleStateUpdate(request, protoReq);
|
||||
});
|
||||
|
||||
// TODO: REMAKE TO PROTO
|
||||
server.on("/api/wifi/sta/settings", HTTP_GET,
|
||||
[&](httpd_req_t *request) { return wifiService.endpoint.getState(request); });
|
||||
server.on("/api/wifi/sta/settings", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
|
||||
return wifiService.endpoint.handleStateUpdate(request, json);
|
||||
[&](httpd_req_t *request) { return wifiService.protoEndpoint.getState(request); });
|
||||
server.onProto("/api/wifi/sta/settings", HTTP_POST, [&](httpd_req_t *request, api_Request *protoReq) {
|
||||
return wifiService.protoEndpoint.handleStateUpdate(request, protoReq);
|
||||
});
|
||||
server.on("/api/wifi/scan", HTTP_GET, [&](httpd_req_t *request) { return wifiService.handleScan(request); });
|
||||
server.on("/api/wifi/networks", HTTP_GET, [&](httpd_req_t *request) { return wifiService.getNetworks(request); });
|
||||
@@ -102,7 +101,6 @@ void setupServer() {
|
||||
[&](httpd_req_t *request, JsonVariant &json) { return mdnsService.queryServices(request, json); });
|
||||
#endif
|
||||
|
||||
// TODO: REMAKE TO PROTO
|
||||
server.on("/api/config/*", HTTP_GET, [](httpd_req_t *request) { return FileSystem::getConfigFile(request); });
|
||||
server.on("/api/files", HTTP_GET, [&](httpd_req_t *request) { return FileSystem::getFilesProto(request); });
|
||||
PROTO_ENDPOINT(server, "/api/files/delete", file_delete_request, FileSystem::handleDelete);
|
||||
|
||||
+33
-28
@@ -2,8 +2,11 @@
|
||||
#include <communication/webserver.h>
|
||||
|
||||
WiFiService::WiFiService()
|
||||
: _persistence(WiFiSettings::read, WiFiSettings::update, this, WIFI_SETTINGS_FILE),
|
||||
endpoint(WiFiSettings::read, WiFiSettings::update, this) {
|
||||
: _persistence(WiFiSettings_read, WiFiSettings_update, this, WIFI_SETTINGS_FILE,
|
||||
api_WifiSettings_fields, api_WifiSettings_size, WiFiSettings_defaults()),
|
||||
protoEndpoint(WiFiSettings_read, WiFiSettings_update, this,
|
||||
API_REQUEST_EXTRACTOR(wifi_settings, api_WifiSettings),
|
||||
API_RESPONSE_ASSIGNER(wifi_settings, api_WifiSettings)) {
|
||||
addUpdateHandler([&](const std::string &originId) { reconfigureWiFiConnection(); }, false);
|
||||
}
|
||||
|
||||
@@ -25,8 +28,8 @@ void WiFiService::begin() {
|
||||
_persistence.readFromFS();
|
||||
reconfigureWiFiConnection();
|
||||
|
||||
if (state().wifiSettings.size() == 1) {
|
||||
configureNetwork(state().wifiSettings[0]);
|
||||
if (state().wifi_networks_count == 1) {
|
||||
configureNetwork(state().wifi_networks[0]);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
@@ -64,7 +67,7 @@ esp_err_t WiFiService::getNetworks(httpd_req_t *request) {
|
||||
}
|
||||
|
||||
void WiFiService::setupMDNS(const char *hostname) {
|
||||
MDNS.begin(state().hostname.c_str());
|
||||
MDNS.begin(state().hostname);
|
||||
MDNS.setInstanceName(hostname);
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("ws", "tcp", 80);
|
||||
@@ -115,15 +118,11 @@ void WiFiService::getNetworkStatus(JsonObject &root) {
|
||||
}
|
||||
|
||||
void WiFiService::manageSTA() {
|
||||
if (WiFi.isConnected() || state().wifiSettings.empty()) return;
|
||||
if (WiFi.isConnected() || state().wifi_networks_count == 0) return;
|
||||
if ((WiFi.getMode() & WIFI_STA) == 0) connectToWiFi();
|
||||
}
|
||||
|
||||
void WiFiService::connectToWiFi() {
|
||||
for (auto &network : state().wifiSettings) {
|
||||
network.available = false;
|
||||
}
|
||||
|
||||
int scanResult = WiFi.scanNetworks();
|
||||
if (scanResult == WIFI_SCAN_FAILED) {
|
||||
ESP_LOGE("WiFiSettingsService", "WiFi scan failed.");
|
||||
@@ -132,7 +131,7 @@ void WiFiService::connectToWiFi() {
|
||||
} else {
|
||||
ESP_LOGI("WiFiSettingsService", "%d networks found.", scanResult);
|
||||
|
||||
wifi_settings_t *bestNetwork = nullptr;
|
||||
WiFiNetwork *bestNetwork = nullptr;
|
||||
int32_t bestNetworkDb = FACTORY_WIFI_RSSI_THRESHOLD;
|
||||
|
||||
for (int i = 0; i < scanResult; ++i) {
|
||||
@@ -144,10 +143,11 @@ void WiFiService::connectToWiFi() {
|
||||
|
||||
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
|
||||
|
||||
for (auto &network : state().wifiSettings) {
|
||||
if (ssid_scan == network.ssid.c_str()) {
|
||||
for (pb_size_t j = 0; j < state().wifi_networks_count; j++) {
|
||||
WiFiNetwork &network = state().wifi_networks[j];
|
||||
if (ssid_scan == network.ssid) {
|
||||
if (rssi_scan >= FACTORY_WIFI_RSSI_THRESHOLD) {
|
||||
network.available = true;
|
||||
// Network is available
|
||||
}
|
||||
if (rssi_scan > bestNetworkDb) {
|
||||
bestNetworkDb = rssi_scan;
|
||||
@@ -157,18 +157,22 @@ void WiFiService::connectToWiFi() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!state().priorityBySignalStrength) {
|
||||
for (auto &network : state().wifiSettings) {
|
||||
if (network.available == true) {
|
||||
ESP_LOGI("WiFiSettingsService", "Connecting to first available network: %s", network.ssid.c_str());
|
||||
configureNetwork(network);
|
||||
break;
|
||||
if (!state().priority_rssi) {
|
||||
for (pb_size_t j = 0; j < state().wifi_networks_count; j++) {
|
||||
WiFiNetwork &network = state().wifi_networks[j];
|
||||
// Check if this network was found in scan
|
||||
for (int i = 0; i < scanResult; ++i) {
|
||||
if (WiFi.SSID(i) == network.ssid) {
|
||||
ESP_LOGI("WiFiSettingsService", "Connecting to first available network: %s", network.ssid);
|
||||
configureNetwork(network);
|
||||
WiFi.scanDelete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (state().priorityBySignalStrength && bestNetwork) {
|
||||
ESP_LOGI("WiFiSettingsService", "Connecting to strongest network: %s", bestNetwork->ssid.c_str());
|
||||
} else if (bestNetwork) {
|
||||
ESP_LOGI("WiFiSettingsService", "Connecting to strongest network: %s", bestNetwork->ssid);
|
||||
configureNetwork(*bestNetwork);
|
||||
WiFi.begin(bestNetwork->ssid.c_str(), bestNetwork->password.c_str());
|
||||
} else {
|
||||
ESP_LOGI("WiFiSettingsService", "No known networks found.");
|
||||
}
|
||||
@@ -177,15 +181,16 @@ void WiFiService::connectToWiFi() {
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiService::configureNetwork(wifi_settings_t &network) {
|
||||
if (network.staticIPConfig) {
|
||||
WiFi.config(network.localIP, network.gatewayIP, network.subnetMask, network.dnsIP1, network.dnsIP2);
|
||||
void WiFiService::configureNetwork(WiFiNetwork &network) {
|
||||
if (network.static_ip_config) {
|
||||
WiFi.config(IPAddress(network.local_ip), IPAddress(network.gateway_ip),
|
||||
IPAddress(network.subnet_mask), IPAddress(network.dns_ip_1), IPAddress(network.dns_ip_2));
|
||||
} else {
|
||||
WiFi.config(IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0));
|
||||
}
|
||||
WiFi.setHostname(state().hostname.c_str());
|
||||
WiFi.setHostname(state().hostname);
|
||||
|
||||
WiFi.begin(network.ssid.c_str(), network.password.c_str());
|
||||
WiFi.begin(network.ssid, network.password);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||
|
||||
Reference in New Issue
Block a user