Files
mixly3-server/arduino-libs/arduino-cli/libraries/Blynk/examples/Blynk.Inject/Template_ESP32/ConfigMode.h

262 lines
7.2 KiB
C

/**************************************************************
* This is a DEMO. You can use it only for development and testing.
*
* If you would like to add these features to your product,
* please contact Blynk for Business:
*
* http://www.blynk.io/
*
**************************************************************/
#include <WiFiClient.h>
#include <WebServer.h>
#include <DNSServer.h>
WebServer server(WIFI_AP_CONFIG_PORT);
DNSServer dnsServer;
const byte DNS_PORT = 53;
const char* config_form = R"html(
<!DOCTYPE HTML>
<html>
<head>
<title>WiFi setup</title>
<style>
body {
background-color: #fcfcfc;
box-sizing: border-box;
}
body, input {
font-family: Roboto, sans-serif;
font-weight: 400;
font-size: 16px;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: #ccc;
border-radius: 4px;
}
td { padding:0 0 0 5px; }
label { white-space:nowrap; }
input { width: 20em; }
input[name="port"] { width: 5em; }
input[type="submit"], img { margin: auto; display: block; width: 30%; }
</style>
</head>
<body>
<div class="centered">
<form method="get" action="config">
<table>
<tr><td><label for="ssid">WiFi SSID:</label></td> <td><input type="text" name="ssid" length=64 required="required"></td></tr>
<tr><td><label for="pass">Password:</label></td> <td><input type="text" name="pass" length=64></td></tr>
<tr><td><label for="blynk">Auth token:</label></td><td><input type="text" name="blynk" placeholder="a0b1c2d..." pattern="[a-zA-Z0-9]{32}" maxlength="32" required="required"></td></tr>
<tr><td><label for="host">Host:</label></td> <td><input type="text" name="host" length=64></td></tr>
<tr><td><label for="port">Port:</label></td> <td><input type="number" name="port" value="80" min="1" max="65535"></td></tr>
</table><br/>
<input type="submit" value="Apply">
</form>
</div>
</body>
</html>
)html";
void restartMCU() {
ESP.restart();
}
void enterConfigMode()
{
randomSeed(ESP.getEfuseMac() & 0xFFFFFF);
const uint32_t unique = random(0xFFFFF);
char ssidBuff[64];
snprintf(ssidBuff, sizeof(ssidBuff), "%s-%05X", PRODUCT_WIFI_SSID, unique);
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(WIFI_AP_IP, WIFI_AP_IP, WIFI_AP_Subnet);
WiFi.softAP(ssidBuff);
delay(500);
IPAddress myIP = WiFi.softAPIP();
DEBUG_PRINT(String("AP SSID: ") + ssidBuff);
DEBUG_PRINT(String("AP IP: ") + myIP[0] + "." + myIP[1] + "." + myIP[2] + "." + myIP[3]);
// Set up DNS Server
dnsServer.setTTL(300); // Time-to-live 300s
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure); // Return code for non-accessible domains
#ifdef WIFI_CAPTIVE_PORTAL_ENABLE
dnsServer.start(DNS_PORT, "*", WiFi.softAPIP()); // Point all to our IP
server.onNotFound(handleRoot);
#else
dnsServer.start(DNS_PORT, BOARD_CONFIG_AP_URL, WiFi.softAPIP());
DEBUG_PRINT(String("AP URL: ") + BOARD_CONFIG_AP_URL);
#endif
server.on("/", []() {
server.send(200, "text/html", config_form);
});
server.on("/config", []() {
String ssid = server.arg("ssid");
String ssidManual = server.arg("ssidManual");
String pass = server.arg("pass");
if (ssidManual != "") {
ssid = ssidManual;
}
String token = server.arg("blynk");
String host = server.arg("host");
String port = server.arg("port");
String content;
unsigned statusCode;
DEBUG_PRINT(String("WiFi SSID: ") + ssid + " Pass: " + pass);
DEBUG_PRINT(String("Blynk cloud: ") + token + " @ " + host + ":" + port);
if (token.length() == 32 && ssid.length() > 0) {
configStore.flagConfig = false;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(token, configStore.cloudToken);
if (host.length()) {
CopyString(host, configStore.cloudHost);
}
if (port.length()) {
configStore.cloudPort = port.toInt();
}
content = R"json({"status":"ok","msg":"Configuration saved"})json";
statusCode = 200;
server.send(statusCode, "application/json", content);
BlynkState::set(MODE_SWITCH_TO_STA);
} else {
DEBUG_PRINT("Configuration invalid");
content = R"json({"status":"error","msg":"Configuration invalid"})json";
statusCode = 404;
server.send(statusCode, "application/json", content);
}
});
server.on("/board_info.json", []() {
char buff[256];
snprintf(buff, sizeof(buff),
R"json({"board":"%s","vendor":"%s","tmpl_id":"%s","fw_ver":"%s","hw_ver":"%s"})json",
BOARD_NAME,
BOARD_VENDOR,
BOARD_TEMPLATE_ID,
BOARD_FIRMWARE_VERSION,
BOARD_HARDWARE_VERSION
);
server.send(200, "application/json", buff);
});
server.on("/reset", []() {
BlynkState::set(MODE_RESET_CONFIG);
server.send(200, "application/json", R"json({"status":"ok","msg":"Configuration reset"})json");
});
server.on("/reboot", []() {
restartMCU();
});
server.begin();
while (BlynkState::is(MODE_WAIT_CONFIG) || BlynkState::is(MODE_CONFIGURING)) {
dnsServer.processNextRequest();
server.handleClient();
if (BlynkState::is(MODE_WAIT_CONFIG) && WiFi.softAPgetStationNum() > 0) {
BlynkState::set(MODE_CONFIGURING);
} else if (BlynkState::is(MODE_CONFIGURING) && WiFi.softAPgetStationNum() == 0) {
BlynkState::set(MODE_WAIT_CONFIG);
}
}
server.stop();
}
void enterConnectNet() {
BlynkState::set(MODE_CONNECTING_NET);
DEBUG_PRINT(String("Connecting to WiFi: ") + configStore.wifiSSID);
WiFi.begin(configStore.wifiSSID, configStore.wifiPass);
unsigned long timeoutMs = millis() + WIFI_NET_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) && (WiFi.status() != WL_CONNECTED))
{
delay(100);
if (!BlynkState::is(MODE_CONNECTING_NET)) {
WiFi.disconnect();
return;
}
}
if (WiFi.status() == WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_CLOUD);
} else {
BlynkState::set(MODE_ERROR);
}
}
void enterConnectCloud() {
BlynkState::set(MODE_CONNECTING_CLOUD);
Blynk.disconnect();
Blynk.config(configStore.cloudToken, configStore.cloudHost, configStore.cloudPort);
Blynk.connect(0);
unsigned long timeoutMs = millis() + WIFI_CLOUD_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) &&
(Blynk.connected() == false))
{
Blynk.run();
if (!BlynkState::is(MODE_CONNECTING_CLOUD)) {
Blynk.disconnect();
return;
}
}
if (Blynk.connected()) {
BlynkState::set(MODE_RUNNING);
if (!configStore.flagConfig) {
configStore.flagConfig = true;
config_save();
DEBUG_PRINT("Configuration stored to flash");
}
} else {
BlynkState::set(MODE_ERROR);
}
}
void enterSwitchToSTA() {
BlynkState::set(MODE_SWITCH_TO_STA);
DEBUG_PRINT("Switching to STA...");
WiFi.mode(WIFI_OFF);
delay(1000);
WiFi.mode(WIFI_STA);
BlynkState::set(MODE_CONNECTING_NET);
}
void enterError() {
BlynkState::set(MODE_ERROR);
unsigned long timeoutMs = millis() + 10000;
while (timeoutMs > millis() || g_buttonPressed)
{
delay(10);
if (!BlynkState::is(MODE_ERROR)) {
return;
}
}
DEBUG_PRINT("Restarting after error.");
delay(10);
restartMCU();
}