Skip to content

Commit eae2260

Browse files
committed
Extract WiFiSettings class
1 parent 5be4c7a commit eae2260

8 files changed

Lines changed: 227 additions & 143 deletions

File tree

src/influxdb.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ APB::InfluxDb &APB::InfluxDb::Instance = *new APB::InfluxDb{};
1818
#define TZ_INFO "UTC1"
1919

2020
void setPointSource(Point &point) {
21-
point.addTag("source", APB::Settings::Instance.apConfiguration().essid);
21+
point.addTag("source", APB::Settings::Instance.wifi().hostname());
2222
}
2323

2424
InfluxDBClient influxDbClient(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);

src/settings.cpp

Lines changed: 11 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,23 @@
77

88
#define APB_PREFS_VERSION 1
99
#define APB_KEY_VERSION "version"
10-
#define APB_KEY_AP_ESSID "ap_essid"
11-
#define APB_KEY_AP_PSK "ap_psk"
12-
13-
#define APB_KEY_STATION_X_ESSID "station_%d_essid"
14-
#define APB_KEY_STATION_X_PSK "station_%d_psk"
1510

1611
#define APB_KEY_STATUS_LED_DUTY "status_led_duty"
1712

18-
1913
#define LOG_SCOPE "APB::Configuration - "
2014

2115
using namespace std::placeholders;
2216

2317
APB::Settings &APB::Settings::Instance = *new APB::Settings();
2418

25-
namespace {
26-
Preferences prefs;
27-
}
28-
29-
bool APB::Settings::WiFiStation::empty() const {
30-
return strlen(essid) == 0;
31-
}
32-
33-
bool APB::Settings::WiFiStation::open() const {
34-
return strlen(psk) == 0;
35-
}
3619

37-
APB::Settings::Settings() {
20+
APB::Settings::Settings() :
21+
#ifdef APB_DEFAULT_HOSTNAME
22+
wifiSettings{prefs, LittleFS, APB_DEFAULT_HOSTNAME, false}
23+
#else
24+
wifiSettings{prefs, LittleFS, "AstroPowerBox-", true}
25+
#endif
26+
{
3827

3928
}
4029

@@ -46,11 +35,6 @@ void APB::Settings::setup() {
4635
Log.infoln(LOG_SCOPE "Setup finished");
4736
}
4837

49-
void runOnFormatKey(const char *format, uint16_t index, std::function<void(const char *)> apply) {
50-
char key[256];
51-
sprintf(key, format, index);
52-
apply(key);
53-
}
5438

5539
void APB::Settings::load() {
5640
Log.traceln(LOG_SCOPE "Loading APB Settings");
@@ -59,102 +43,21 @@ void APB::Settings::load() {
5943
loadDefaults();
6044
return;
6145
}
62-
size_t apSSIDChars = prefs.getString(APB_KEY_AP_ESSID, _apConfiguration.essid, APB_MAX_ESSID_PSK_SIZE);
63-
Log.traceln(LOG_SCOPE "%s characters: %d", APB_KEY_AP_ESSID, apSSIDChars);
64-
if(apSSIDChars > 0 && _apConfiguration ) {
65-
prefs.getString(APB_KEY_AP_PSK, _apConfiguration.psk, APB_MAX_ESSID_PSK_SIZE);
66-
Log.traceln(LOG_SCOPE "Loaded AP Settings: essid=`%s`, psk=`%s`", _apConfiguration.essid, _apConfiguration.psk);
67-
} else {
68-
loadDefaults();
69-
}
70-
for(uint8_t i=0; i<APB_MAX_STATIONS; i++) {
71-
runOnFormatKey(APB_KEY_STATION_X_ESSID, i, [this, i](const char *key) { prefs.getString(key, _stations[i].essid, APB_MAX_ESSID_PSK_SIZE); });
72-
runOnFormatKey(APB_KEY_STATION_X_PSK, i, [this, i](const char *key) { prefs.getString(key, _stations[i].psk, APB_MAX_ESSID_PSK_SIZE); });
73-
Log.traceln(LOG_SCOPE "Station %d: essid=`%s`, psk=`%s`", i, _stations[i].essid, _stations[i].psk);
74-
}
75-
76-
if(std::none_of(_stations.begin(), _stations.end(), std::bind(&WiFiStation::valid, _1))) {
77-
loadDefaultStations();
78-
}
7946
_statusLedDuty = prefs.getFloat(APB_KEY_STATUS_LED_DUTY, 1);
47+
wifiSettings.load();
8048
Log.infoln(LOG_SCOPE "Preferences loaded");
8149
}
8250

8351
void APB::Settings::loadDefaults() {
84-
#ifdef APB_DEFAULT_HOSTNAME
85-
sprintf(_apConfiguration.essid, APB_DEFAULT_HOSTNAME);
86-
#else
87-
String mac = WiFi.macAddress();
88-
Log.traceln(LOG_SCOPE "Found mac address: `%s`", mac.c_str());
89-
mac.replace(F(":"), F(""));
90-
mac = mac.substring(6);
91-
sprintf(_apConfiguration.essid, "AstroPowerBox-%s", mac.c_str());
92-
#endif
93-
memset(_apConfiguration.psk, 0, APB_MAX_ESSID_PSK_SIZE);
94-
Log.traceln(LOG_SCOPE "Using default ESSID: `%s`", _apConfiguration.essid);
95-
loadDefaultStations();
52+
wifiSettings.loadDefaults();
9653
}
9754

98-
void APB::Settings::loadDefaultStations() {
99-
if(LittleFS.exists("/wifi.json")) {
100-
fs::File wifiJson = LittleFS.open("/wifi.json");
101-
JsonDocument doc;
102-
DeserializationError error = deserializeJson(doc, wifiJson);
103-
if (error) {
104-
Log.warningln(F("Failed to read file \"/wifi.json\", using empty wifi configuration"));
105-
wifiJson.close();
106-
return;
107-
}
108-
wifiJson.close();
109-
JsonArray stations = doc.as<JsonArray>();
110-
Log.infoln("Found valid /wifi.json settings file, loading default wifi settings with %d stations", stations.size());
111-
for(int i=0; i<stations.size() && i<APB_MAX_STATIONS; i++) {
112-
String ssid = stations[i]["ssid"];
113-
String psk = stations[i]["psk"];
114-
Log.infoln("Adding station: %s", ssid);
115-
_stations[i] = WiFiStation{};
116-
strcpy(_stations[i].essid, ssid.c_str());
117-
strcpy(_stations[i].psk, psk.c_str());
118-
119-
}
120-
save();
121-
}
122-
}
55+
12356

12457
void APB::Settings::save() {
12558
Log.traceln(LOG_SCOPE "Saving APB Settings");
12659
prefs.putUShort(APB_KEY_VERSION, APB_PREFS_VERSION);
127-
prefs.putString(APB_KEY_AP_ESSID, _apConfiguration.essid);
128-
prefs.putString(APB_KEY_AP_PSK, _apConfiguration.psk);
129-
130-
for(uint8_t i=0; i<APB_MAX_STATIONS; i++) {
131-
runOnFormatKey(APB_KEY_STATION_X_ESSID, i, [this, i](const char *key) { prefs.putString(key, _stations[i].essid); });
132-
runOnFormatKey(APB_KEY_STATION_X_PSK, i, [this, i](const char *key) { prefs.putString(key, _stations[i].psk); });
133-
}
60+
wifiSettings.save();
13461
prefs.putFloat(APB_KEY_STATUS_LED_DUTY, _statusLedDuty);
13562
Log.infoln(LOG_SCOPE "Preferences saved");
13663
}
137-
138-
void APB::Settings::setAPConfiguration(const char *essid, const char *psk) {
139-
strcpy(_apConfiguration.essid, essid);
140-
strcpy(_apConfiguration.psk, psk);
141-
}
142-
143-
void APB::Settings::setStationConfiguration(uint8_t index, const char *essid, const char *psk) {
144-
strcpy(_stations[index].essid, essid);
145-
strcpy(_stations[index].psk, psk);
146-
}
147-
148-
bool APB::Settings::hasStation(const String &essid) const {
149-
return std::any_of(
150-
std::begin(_stations),
151-
std::end(_stations),
152-
[&essid](const WiFiStation &station){
153-
return essid == station.essid;
154-
}
155-
);
156-
}
157-
158-
bool APB::Settings::hasValidStations() const {
159-
return std::any_of(_stations.begin(), _stations.end(), std::bind(&APB::Settings::WiFiStation::valid, _1));
160-
}

src/settings.h

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,26 @@
33
#include <array>
44
#include "configuration.h"
55
#include <WString.h>
6+
#include "wifisettings.h"
67

7-
#define APB_MAX_ESSID_PSK_SIZE 256
88

99
namespace APB {
1010
class Settings {
1111
public:
1212
static Settings &Instance;
13-
struct WiFiStation {
14-
char essid[APB_MAX_ESSID_PSK_SIZE] = {0};
15-
char psk[APB_MAX_ESSID_PSK_SIZE] = {0};
16-
operator bool() const { return valid(); }
17-
bool valid() const { return !empty(); }
18-
bool empty() const;
19-
bool open() const;
20-
};
2113
Settings();
2214
void setup();
2315
void load();
2416
void save();
17+
GuLinux::WiFiSettings &wifi() { return wifiSettings; }
2518

26-
void setAPConfiguration(const char *essid, const char *psk);
27-
void setStationConfiguration(uint8_t index, const char *essid, const char *psk);
28-
WiFiStation apConfiguration() const { return _apConfiguration; }
29-
WiFiStation station(uint8_t index) const { return _stations[index]; }
30-
bool hasStation(const String &essid) const;
31-
bool hasValidStations() const;
3219
float statusLedDuty() const { return _statusLedDuty; };
3320
void setStatusLedDuty(float duty) { _statusLedDuty = duty; }
34-
std::array<WiFiStation, APB_MAX_STATIONS> stations() const { return _stations; }
3521
private:
36-
std::array<WiFiStation, APB_MAX_STATIONS> _stations;
37-
WiFiStation _apConfiguration;
22+
Preferences prefs;
23+
GuLinux::WiFiSettings wifiSettings;
3824
float _statusLedDuty;
3925
void loadDefaults();
40-
void loadDefaultStations();
4126
};
4227
}
4328
#endif

src/webserver.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ void APB::WebServer::onGetStatus(AsyncWebServerRequest *request) {
103103

104104
void APB::WebServer::onGetConfig(AsyncWebServerRequest *request) {
105105
JsonResponse response(request);
106-
response.root()["accessPoint"]["essid"] = Settings::Instance.apConfiguration().essid;
107-
response.root()["accessPoint"]["psk"] = Settings::Instance.apConfiguration().psk;
106+
response.root()["accessPoint"]["essid"] = Settings::Instance.wifi().apConfiguration().essid;
107+
response.root()["accessPoint"]["psk"] = Settings::Instance.wifi().apConfiguration().psk;
108108
for(uint8_t i=0; i<APB_MAX_STATIONS; i++) {
109-
auto station = Settings::Instance.station(i);
109+
auto station = Settings::Instance.wifi().station(i);
110110
response.root()["stations"][i]["essid"] = station.essid;
111111
response.root()["stations"][i]["psk"] = station.psk;
112112
}
@@ -132,7 +132,7 @@ void APB::WebServer::onNotFound(AsyncWebServerRequest *request) {
132132
void APB::WebServer::onConfigAccessPoint(AsyncWebServerRequest *request, JsonVariant &json) {
133133
if(request->method() == HTTP_DELETE) {
134134
Log.traceln(LOG_SCOPE "onConfigAccessPoint: method=%d (%s)", request->method(), request->methodToString());
135-
Settings::Instance.setAPConfiguration("", "");
135+
Settings::Instance.wifi().setAPConfiguration("", "");
136136
}
137137
if(request->method() == HTTP_POST) {
138138
if(Validation{request, json}.required<const char*>({"essid", "psk"}).notEmpty("essid").invalid()) return;
@@ -141,7 +141,7 @@ void APB::WebServer::onConfigAccessPoint(AsyncWebServerRequest *request, JsonVar
141141
String psk = json["psk"];
142142
Log.traceln(LOG_SCOPE "onConfigAccessPoint: essid=%s, psk=%s, method=%d (%s)",
143143
essid.c_str(), psk.c_str(), request->method(), request->methodToString());
144-
Settings::Instance.setAPConfiguration(essid.c_str(), psk.c_str());
144+
Settings::Instance.wifi().setAPConfiguration(essid.c_str(), psk.c_str());
145145

146146
}
147147
onGetConfig(request);
@@ -163,9 +163,9 @@ void APB::WebServer::onConfigStation(AsyncWebServerRequest *request, JsonVariant
163163
Log.traceln(LOG_SCOPE "onConfigStation: `%d`, essid=`%s`, psk=`%s`, method=%d (%s)",
164164
stationIndex, essid.c_str(), psk.c_str(), request->method(), request->methodToString());
165165
if(request->method() == HTTP_POST) {
166-
Settings::Instance.setStationConfiguration(stationIndex, essid.c_str(), psk.c_str());
166+
Settings::Instance.wifi().setStationConfiguration(stationIndex, essid.c_str(), psk.c_str());
167167
} else if(request->method() == HTTP_DELETE) {
168-
Settings::Instance.setStationConfiguration(stationIndex, "", "");
168+
Settings::Instance.wifi().setStationConfiguration(stationIndex, "", "");
169169
}
170170
onGetConfig(request);
171171
}
@@ -242,7 +242,7 @@ void APB::WebServer::onGetPower(AsyncWebServerRequest *request) {
242242
}
243243

244244
void APB::WebServer::onGetMetrics(AsyncWebServerRequest *request) {
245-
MetricsResponse metricsResponse(request, MetricsResponse::Labels().add("source", Settings::Instance.apConfiguration().essid));
245+
MetricsResponse metricsResponse(request, MetricsResponse::Labels().add("source", Settings::Instance.wifi().hostname()));
246246
const auto powerMonitorReading = PowerMonitor::Instance.status();
247247
metricsResponse
248248
.gauge("powermonitor", powerMonitorReading.busVoltage, MetricsResponse::Labels().unit("V").field("voltage"))

src/wifimanager.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void APB::WiFiManager::onScanDone(const wifi_event_sta_scan_done_t &scan_done) {
2525
return;
2626
}
2727
for(uint8_t i=0; i<scan_done.number; i++) {
28-
if(Settings::Instance.hasStation(WiFi.SSID(i))) {
28+
if(wifiSettings->hasStation(WiFi.SSID(i))) {
2929
Log.infoln(LOG_SCOPE "[EVENT] Found at least one AP from configuration, scheduling reconnection");
3030
scheduleReconnect = true;
3131
return;
@@ -76,12 +76,13 @@ void APB::WiFiManager::onEvent(arduino_event_id_t event, arduino_event_info_t in
7676

7777
void APB::WiFiManager::setup(Scheduler &scheduler) {
7878
Log.traceln(LOG_SCOPE "setup");
79+
wifiSettings = &Settings::Instance.wifi();
7980
scheduler.addTask(rescanWiFiTask);
8081

81-
WiFi.setHostname(Settings::Instance.apConfiguration().essid);
82+
WiFi.setHostname(wifiSettings->hostname());
8283
_status = Status::Connecting;
8384
for(uint8_t i=0; i<APB_MAX_STATIONS; i++) {
84-
auto station = Settings::Instance.station(i);
85+
auto station = wifiSettings->station(i);
8586
if(station) {
8687
Log.infoln(LOG_SCOPE "found valid station: %s", station.essid);
8788
wifiMulti.addAP(station.essid, station.psk);
@@ -93,14 +94,14 @@ void APB::WiFiManager::setup(Scheduler &scheduler) {
9394

9495
void APB::WiFiManager::setApMode() {
9596
Log.infoln(LOG_SCOPE "Starting softAP with essid=`%s`, ip address=`%s`",
96-
Settings::Instance.apConfiguration().essid, WiFi.softAPIP().toString().c_str());
97-
WiFi.softAP(Settings::Instance.apConfiguration().essid,
98-
Settings::Instance.apConfiguration().open() ? nullptr : Settings::Instance.apConfiguration().psk);
97+
wifiSettings->apConfiguration().essid, WiFi.softAPIP().toString().c_str());
98+
WiFi.softAP(wifiSettings->apConfiguration().essid,
99+
wifiSettings->apConfiguration().open() ? nullptr : wifiSettings->apConfiguration().psk);
99100
}
100101

101102
void APB::WiFiManager::connect() {
102103
connectionFailed = false;
103-
bool hasValidStations = Settings::Instance.hasValidStations();
104+
bool hasValidStations = wifiSettings->hasValidStations();
104105
if(!hasValidStations) {
105106
Log.warningln(LOG_SCOPE "No valid stations found");
106107
setApMode();

src/wifimanager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <vector>
77
#include "settings.h"
88
#include <TaskSchedulerDeclarations.h>
9+
#include "wifisettings.h"
910

1011
namespace APB {
1112

@@ -26,6 +27,7 @@ class WiFiManager {
2627
void loop();
2728
void addOnConnectedListener(const OnConnectCallback &onConnected);
2829
private:
30+
GuLinux::WiFiSettings *wifiSettings;
2931
WiFiMulti wifiMulti;
3032
Status _status;
3133
bool scheduleReconnect = false;

0 commit comments

Comments
 (0)