mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-10 14:41:37 +02:00
0.8.45
* start implementing a wizard for initial (WiFi) configuration #1199
This commit is contained in:
parent
617cf0a92a
commit
5ca26895a1
9 changed files with 158 additions and 9 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
## 0.8.45 - 2024-01-05
|
||||
* fix MqTT total values #1326
|
||||
* start implementing a wizard for initial (WiFi) configuration #1199
|
||||
|
||||
## 0.8.44 - 2024-01-05
|
||||
* fix MqTT transmission of data #1326
|
||||
|
|
12
src/app.h
12
src/app.h
|
@ -150,6 +150,18 @@ class app : public IApp, public ah::Scheduler {
|
|||
return mWifi.getAvailNetworks(obj);
|
||||
}
|
||||
|
||||
void setupStation(void) {
|
||||
mWifi.setupStation();
|
||||
}
|
||||
|
||||
void setStopApAllowedMode(bool allowed) {
|
||||
mWifi.setStopApAllowedMode(allowed);
|
||||
}
|
||||
|
||||
String getStationIp(void) {
|
||||
return mWifi.getStationIp();
|
||||
}
|
||||
|
||||
#endif /* !defined(ETHERNET) */
|
||||
|
||||
void setRebootFlag() {
|
||||
|
|
|
@ -37,6 +37,9 @@ class IApp {
|
|||
#if !defined(ETHERNET)
|
||||
virtual void scanAvailNetworks() = 0;
|
||||
virtual bool getAvailNetworks(JsonObject obj) = 0;
|
||||
virtual void setupStation(void) = 0;
|
||||
virtual void setStopApAllowedMode(bool allowed) = 0;
|
||||
virtual String getStationIp(void) = 0;
|
||||
#endif /* defined(ETHERNET) */
|
||||
|
||||
virtual uint32_t getUptime() = 0;
|
||||
|
|
|
@ -100,6 +100,7 @@ class RestApi {
|
|||
else if(path == "setup") getSetup(request, root);
|
||||
#if !defined(ETHERNET)
|
||||
else if(path == "setup/networks") getNetworks(root);
|
||||
else if(path == "setup/getip") getWifiIp(root);
|
||||
#endif /* !defined(ETHERNET) */
|
||||
else if(path == "live") getLive(request,root);
|
||||
else {
|
||||
|
@ -754,6 +755,9 @@ class RestApi {
|
|||
void getNetworks(JsonObject obj) {
|
||||
mApp->getAvailNetworks(obj);
|
||||
}
|
||||
void getWifiIp(JsonObject obj) {
|
||||
obj[F("ip")] = mApp->getStationIp();
|
||||
}
|
||||
#endif /* !defined(ETHERNET) */
|
||||
|
||||
void getLive(AsyncWebServerRequest *request, JsonObject obj) {
|
||||
|
@ -834,7 +838,13 @@ class RestApi {
|
|||
mTimezoneOffset = jsonIn[F("val")];
|
||||
else if(F("discovery_cfg") == jsonIn[F("cmd")])
|
||||
mApp->setMqttDiscoveryFlag(); // for homeassistant
|
||||
else if(F("save_iv") == jsonIn[F("cmd")]) {
|
||||
else if(F("save_wifi") == jsonIn[F("cmd")]) {
|
||||
snprintf(mConfig->sys.stationSsid, SSID_LEN, "%s", jsonIn[F("ssid")].as<const char*>());
|
||||
snprintf(mConfig->sys.stationPwd, PWD_LEN, "%s", jsonIn[F("pwd")].as<const char*>());
|
||||
mApp->saveSettings(false); // without reboot
|
||||
mApp->setStopApAllowedMode(false);
|
||||
mApp->setupStation();
|
||||
} else if(F("save_iv") == jsonIn[F("cmd")]) {
|
||||
Inverter<> *iv = mSys->getInverterByPos(jsonIn[F("id")], false);
|
||||
iv->config->enabled = jsonIn[F("en")];
|
||||
iv->config->serial.u64 = jsonIn[F("ser")];
|
||||
|
|
|
@ -814,3 +814,20 @@ ul {
|
|||
background-color: var(--input-bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.d-flex {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.jc {
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.aic {
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
|
87
src/web/html/wizard.html
Normal file
87
src/web/html/wizard.html
Normal file
|
@ -0,0 +1,87 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Setup Wizard</title>
|
||||
{#HTML_HEADER}
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div class="container d-flex aic jc">
|
||||
<div id="con"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var v;
|
||||
var found = false;
|
||||
var c = document.getElementById("con");
|
||||
|
||||
function sect(e1, e2) {
|
||||
return ml("div", {class: "row"}, [
|
||||
ml("div", {class: "col-12"}, ml("p", {}, e1)),
|
||||
ml("div", {class: "col-12"}, e2)
|
||||
])
|
||||
}
|
||||
|
||||
function wifi() {
|
||||
return ml("div", {}, [
|
||||
ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "Welcome to AhoyDTU"))),
|
||||
ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "Network Setup"))),
|
||||
sect("Choose your WiFi Network", ml("select", {id: "net", onchange: () => {if(found) clearInterval(v)}}, ml("option", {value: "-1"}, "---"))),
|
||||
sect("... or name it manually", ml("input", {id: "man", type: "text"})),
|
||||
sect("WiFi Password", ml("input", {id: "pwd", type: "password"})),
|
||||
ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn", value: "next", onclick: () => {saveWifi()}}, null))),
|
||||
ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "stop wizard")))
|
||||
])
|
||||
}
|
||||
|
||||
function checkWifi() {
|
||||
c.replaceChildren(
|
||||
ml("div", {class: "row my-5"}, ml("div", {class: "col"}, ml("span", {class: "fs-1"}, "Welcome to AhoyDTU"))),
|
||||
ml("div", {class: "row"}, ml("div", {class: "col"}, ml("span", {class: "fs-5"}, "Test Connection"))),
|
||||
sect("AhoyDTU is trying to connect to your WiFi", ml("span", {id: "state"}, "connecting ...")),
|
||||
ml("div", {class: "row my-4"}, ml("div", {class: "col a-r"}, ml("input", {type: "button", class:"btn hide", id: "btn", value: "Finish", onclick: () => {redirect()}}, null))),
|
||||
ml("div", {class: "row mt-5"}, ml("div", {class: "col a-c"}, ml("a", {href: "http://192.168.4.1/"}, "stop wizard")))
|
||||
)
|
||||
v = setInterval(() => {getAjax('/api/setup/getip', printIp)}, 2500);
|
||||
}
|
||||
|
||||
function redirect() {
|
||||
window.location.replace("http://192.168.4.1/")
|
||||
}
|
||||
|
||||
function printIp(obj) {
|
||||
if("0.0.0.0" != obj["ip"]) {
|
||||
clearInterval(v)
|
||||
setHide("btn", false)
|
||||
document.getElementById("state").innerHTML = "success, got following IP in your network: " + obj.ip
|
||||
}
|
||||
}
|
||||
|
||||
function saveWifi() {
|
||||
var ssid = document.getElementById("net").value;
|
||||
if(-1 == ssid)
|
||||
ssid = document.getElementById("man").value;
|
||||
getAjax("/api/setup", ((o) => {if(!o.error) checkWifi()}), "POST", JSON.stringify({cmd: "save_wifi", ssid: ssid, pwd: document.getElementById("pwd").value}));
|
||||
}
|
||||
|
||||
function nets(obj) {
|
||||
var e = document.getElementById("net");
|
||||
if(obj.networks.length > 0) {
|
||||
var a = []
|
||||
a.push(ml("option", {value: -1}, obj.networks.length + " Network(s) found"))
|
||||
for(n of obj.networks) {
|
||||
a.push(ml("option", {value: n.ssid}, n.ssid + " (" + n.rssi + "dBm)"))
|
||||
found = true;
|
||||
}
|
||||
e.replaceChildren(...a)
|
||||
}
|
||||
getAjax("/api/setup", ((o) => {}), "POST", JSON.stringify({cmd: "scan_wifi"}));
|
||||
}
|
||||
|
||||
getAjax("/api/setup", ((o) => {}), "POST", JSON.stringify({cmd: "scan_wifi"}));
|
||||
c.append(wifi())
|
||||
|
||||
v = setInterval(() => {getAjax('/api/setup/networks', nets)}, 2500);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -36,6 +36,7 @@
|
|||
#include "html/h/update_html.h"
|
||||
#include "html/h/visualization_html.h"
|
||||
#include "html/h/about_html.h"
|
||||
#include "html/h/wizard_html.h"
|
||||
|
||||
#define WEB_SERIAL_BUF_SIZE 2048
|
||||
|
||||
|
@ -77,6 +78,7 @@ class Web {
|
|||
mWeb.on("/factorytrue", HTTP_ANY, std::bind(&Web::showHtml, this, std::placeholders::_1));
|
||||
|
||||
mWeb.on("/setup", HTTP_GET, std::bind(&Web::onSetup, this, std::placeholders::_1));
|
||||
mWeb.on("/wizard", HTTP_GET, std::bind(&Web::onWizard, this, std::placeholders::_1));
|
||||
mWeb.on("/save", HTTP_POST, std::bind(&Web::showSave, this, std::placeholders::_1));
|
||||
|
||||
mWeb.on("/live", HTTP_ANY, std::bind(&Web::onLive, this, std::placeholders::_1));
|
||||
|
@ -422,7 +424,7 @@ class Web {
|
|||
|
||||
void showNotFound(AsyncWebServerRequest *request) {
|
||||
checkProtection(request);
|
||||
request->redirect("/setup");
|
||||
request->redirect("/wizard");
|
||||
}
|
||||
|
||||
void onReboot(AsyncWebServerRequest *request) {
|
||||
|
@ -444,6 +446,13 @@ class Web {
|
|||
getPage(request, PROT_MASK_SETUP, setup_html, setup_html_len);
|
||||
}
|
||||
|
||||
void onWizard(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html; charset=UTF-8"), wizard_html, wizard_html_len);
|
||||
response->addHeader(F("Content-Encoding"), "gzip");
|
||||
response->addHeader(F("content-type"), "text/html; charset=UTF-8");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void showSave(AsyncWebServerRequest *request) {
|
||||
DPRINTLN(DBG_VERBOSE, F("showSave"));
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb) {
|
|||
mCnt = 0;
|
||||
mScanActive = false;
|
||||
mScanCnt = 0;
|
||||
mStopApAllowed = true;
|
||||
|
||||
#if defined(ESP8266)
|
||||
wifiConnectHandler = WiFi.onStationModeConnected(std::bind(&ahoywifi::onConnect, this, std::placeholders::_1));
|
||||
|
@ -94,7 +95,7 @@ void ahoywifi::tickWifiLoop() {
|
|||
#endif
|
||||
return;
|
||||
case IN_AP_MODE:
|
||||
if (WiFi.softAPgetStationNum() == 0) {
|
||||
if ((WiFi.softAPgetStationNum() == 0) || (!mStopApAllowed)) {
|
||||
mCnt = 0;
|
||||
mDns.stop();
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
|
@ -105,7 +106,7 @@ void ahoywifi::tickWifiLoop() {
|
|||
}
|
||||
break;
|
||||
case DISCONNECTED:
|
||||
if (WiFi.softAPgetStationNum() > 0) {
|
||||
if ((WiFi.softAPgetStationNum() > 0) && (mStopApAllowed)) {
|
||||
mStaConn = IN_AP_MODE;
|
||||
// first time switch to AP Mode
|
||||
if (mScanActive) {
|
||||
|
@ -182,10 +183,12 @@ void ahoywifi::tickWifiLoop() {
|
|||
break;
|
||||
case GOT_IP:
|
||||
welcome(WiFi.localIP().toString(), F(" (Station)"));
|
||||
WiFi.softAPdisconnect();
|
||||
WiFi.mode(WIFI_STA);
|
||||
DBGPRINTLN(F("[WiFi] AP disabled"));
|
||||
delay(100);
|
||||
if(mStopApAllowed) {
|
||||
WiFi.softAPdisconnect();
|
||||
WiFi.mode(WIFI_STA);
|
||||
DBGPRINTLN(F("[WiFi] AP disabled"));
|
||||
delay(100);
|
||||
}
|
||||
mAppWifiCb(true);
|
||||
mGotDisconnect = false;
|
||||
mStaConn = IN_STA_MODE;
|
||||
|
|
|
@ -28,6 +28,13 @@ class ahoywifi {
|
|||
bool getNtpTime(void);
|
||||
void scanAvailNetworks(void);
|
||||
bool getAvailNetworks(JsonObject obj);
|
||||
void setStopApAllowedMode(bool allowed) {
|
||||
mStopApAllowed = allowed;
|
||||
}
|
||||
String getStationIp(void) {
|
||||
return WiFi.localIP().toString();
|
||||
}
|
||||
void setupStation(void);
|
||||
|
||||
private:
|
||||
typedef enum WiFiStatus {
|
||||
|
@ -43,7 +50,6 @@ class ahoywifi {
|
|||
|
||||
void setupWifi(bool startAP);
|
||||
void setupAp(void);
|
||||
void setupStation(void);
|
||||
void sendNTPpacket(IPAddress& address);
|
||||
void sortRSSI(int *sort, int n);
|
||||
bool getBSSIDs(void);
|
||||
|
@ -78,6 +84,7 @@ class ahoywifi {
|
|||
bool mScanActive;
|
||||
bool mGotDisconnect;
|
||||
std::list<uint8_t> mBSSIDList;
|
||||
bool mStopApAllowed;
|
||||
};
|
||||
|
||||
#endif /*__AHOYWIFI_H__*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue