Skip to content

Commit

Permalink
0.8.45
Browse files Browse the repository at this point in the history
* start implementing a wizard for initial (WiFi) configuration #1199
  • Loading branch information
lumapu committed Jan 6, 2024
1 parent 617cf0a commit 5ca2689
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions src/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
3 changes: 3 additions & 0 deletions src/appInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 11 additions & 1 deletion src/web/RestApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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")];
Expand Down
17 changes: 17 additions & 0 deletions src/web/html/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 87 additions & 0 deletions src/web/html/wizard.html
Original file line number Diff line number Diff line change
@@ -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>
11 changes: 10 additions & 1 deletion src/web/web.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -422,7 +424,7 @@ class Web {

void showNotFound(AsyncWebServerRequest *request) {
checkProtection(request);
request->redirect("/setup");
request->redirect("/wizard");
}

void onReboot(AsyncWebServerRequest *request) {
Expand All @@ -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"));

Expand Down
15 changes: 9 additions & 6 deletions src/wifi/ahoywifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 8 additions & 1 deletion src/wifi/ahoywifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -78,6 +84,7 @@ class ahoywifi {
bool mScanActive;
bool mGotDisconnect;
std::list<uint8_t> mBSSIDList;
bool mStopApAllowed;
};

#endif /*__AHOYWIFI_H__*/
Expand Down

0 comments on commit 5ca2689

Please sign in to comment.