-
Notifications
You must be signed in to change notification settings - Fork 2
/
system_wifi.cpp
154 lines (139 loc) · 5.69 KB
/
system_wifi.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
Wifi Configuration and connection
Based on the example from https://github.com/Juerd/ESP-WiFiSettings
*/
#include "_settings.h" // Settings for what to include etc
#ifdef SYSTEM_WIFI_WANT
// #include <Arduino.h>
#if ESP8266
#include <ESP8266WiFi.h> // for WiFiClient
#else
#include <WiFi.h> // This will be platform dependent, will work on ESP32 but most likely want configurration for other chips/boards
#endif
#include "system_wifi.h"
// TODO find a way to store in eeprom rather than SPIFFS.
#ifdef ESP32
#define ESPFS SPIFFS
#include <SPIFFS.h>
#elif ESP8266
#define ESPFS LittleFS
#include <LittleFS.h>
#else
#error "This example only supports ESP32 and ESP8266"
#endif
#include <WiFiSettings.h> // https://github.com/Juerd/ESP-WiFiSettings
namespace xWifi {
String mqtt_host;
String discovery_project;
String device_name;
// This is called - blocking - by xWiFi.setup, but can also be called if discover no longer connected
void connect() {
// Use stored credentials to connect to your WiFi access point.
// If no credentials are stored or if the access point is out of reach,
// an access point will be started with a captive portal to configure WiFi.
WiFiSettings.connect();
// If WiFi connected, returns true, if WiFi fails then puts up portal and never returns - portal initiates reset
}
// Blocking attempt at reconnecting - can be called by MQTT
void checkConnected() {
if (WiFi.status() != WL_CONNECTED) {
#ifdef SYSTEM_WIFI_DEBUG
Serial.println(F("WiFi not connected, forcing reconnect"));
#endif
connect();
}
}
#ifdef SYSTEM_WIFI_SSID
bool spurt(const String& fn, const String& content) {
File f = ESPFS.open(fn, "w");
if (!f) return false;
auto w = f.print(content);
f.close();
return w == content.length();
}
#endif
#ifdef SYSTEM_WIFI_PORTAL_RESTART
// A watchdog on the portal, that will reset after SYSTEM_WIFI_PORTAL_RESTART ms
// Adding ability to reset if wanted wifi appears.
void portalWatchdog() {
static unsigned long OPWLrestart = millis() + SYSTEM_WIFI_PORTAL_RESTART; // initialized first time this is called
if (OPWLrestart < millis()) {
#ifdef SYSTEM_WIFI_DEBUG
Serial.println(F("WiFiSettings Rescanning"));
#endif
// Note this rescan wont be reflected in a any open portal as the HTML generated is static
const int num_networks = WiFi.scanNetworks();
int i;
for (i = 0; (i < num_networks) && (WiFiSettings.ssid != WiFi.SSID(i)); i++) { } // i will be ssid o num_networks if not found
if (i != num_networks) { // we found it
#ifdef SYSTEM_WIFI_DEBUG
Serial.print(F("WiFiSettings portal timed out and restarting cos now see")); Serial.println(WiFiSettings.ssid);
#endif
if (WiFiSettings.onRestart) { WiFiSettings.onRestart(); } // We aren't setting it here so should do nothing
ESP.restart();
} else {
OPWLrestart = millis() + SYSTEM_WIFI_PORTAL_RESTART;
}
}
}
#endif // SYSTEM_WIFI_PORTAL_RESTART
String &clientid() {
WiFiSettings.begin(); // Ensure WiFi has created variables
return WiFiSettings.hostname;
}
// Note this is blocking - so order is important, in particular it must complete this before trying xMqtt::setup
void setup() {
#ifdef ESP32
SPIFFS.begin(true); // Will format on the first run after failing to mount
#elif ESP8266
LittleFS.begin();
#else
#error "This example only supports ESP32 and ESP8266"
#endif
#ifdef SYSTEM_WIFI_SSID
Serial.println(F("Overriding WiFi SSID / Password for dev"));
spurt(F("/wifi-ssid"), SYSTEM_WIFI_SSID);
spurt(F("/wifi-password"), SYSTEM_WIFI_PASSWORD);
#endif // SYSTEM_WIFI_SSID
// Custom configuration variables, these will read configured values if previously set and return default values if not.
/*
int integer(String name, [long min, long max,] int init = 0, String label = name);
String string(String name, [[unsigned int min_length,] unsigned int max_length,] String init = "", String label = name);
bool checkbox(String name, bool init = false, String label = name);
*/
#ifndef SYSTEM_WIFI_DEVICE
#define SYSTEM_WIFI_DEVICE "device"
#endif
#ifndef SYSTEM_WIFI_PROJECT
#define SYSTEM_WIFI_PROJECT "project"
#endif
mqtt_host = WiFiSettings.string(F("mqtt_host"), 4,40, F(SYSTEM_MQTT_SERVER), F("MQTT Host"));
// TODO-29 turn discovery_project into a dropdown, use an ifdef for the ORGANIZATION in configuration.h not support by ESPWifi-Settings yet.
discovery_project = WiFiSettings.string(F("discovery_project"), 3,20, F(SYSTEM_WIFI_PROJECT), F("Project"));
device_name = WiFiSettings.string(F("device_name"), 3,20, F(SYSTEM_WIFI_DEVICE), F("Device Name"));
#ifdef SYSTEM_WIFI_DEBUG
Serial.print(F("MQTT host = ")); Serial.println(mqtt_host);
Serial.print(F("Project = ")); Serial.println(discovery_project);
Serial.print(F("Device Name = ")); Serial.println(device_name);
#endif
// Cases of connect and portal
// a: no SSID; portal run without attempting to connect - never resets
// b: SSID but connect fails, we have settings, so set a watchdog on portal
// c: Something (e.g. MQTT) calls checkConnected, which calls connect - SSID will be set, so should attempt, and if fail - do portal with watchdog
#ifdef SYSTEM_WIFI_PORTAL_RESTART
WiFiSettings.onFailure = []() {
#ifdef SYSTEM_WIFI_DEBUG
Serial.print(F("Setting portal watchdog for ms"));
Serial.println(SYSTEM_WIFI_PORTAL_RESTART);
#endif
WiFiSettings.onPortalWaitLoop = portalWatchdog;
};
#endif // SYSTEM_WIFI_PORTAL_RESTART
#ifdef SYSTEM_WIFI_DEBUG
Serial.print(F("WiFi hostname="));
Serial.println(clientid());
#endif // SYSTEM_WIFI_DEBUG
connect();
}
} // namespace xWifi
#endif // SYSTEM_WIFI_WANT