diff --git a/lib/HanConfigAp/src/HanConfigAp.cpp b/lib/HanConfigAp/src/HanConfigAp.cpp
index 06a6c0fc..43933e0a 100644
--- a/lib/HanConfigAp/src/HanConfigAp.cpp
+++ b/lib/HanConfigAp/src/HanConfigAp.cpp
@@ -1,4 +1,6 @@
#include "HanConfigAp.h"
+#include "config_html.h"
+#include "style_css.h"
#if defined(ESP8266)
ESP8266WebServer HanConfigAp::server(80);
@@ -66,30 +68,34 @@ void HanConfigAp::setup(int accessPointButtonPin, Stream* debugger)
/* Setup the DNS server redirecting all the domains to this IP */
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
dnsServer.start(DNS_PORT, "*", WiFi.softAPIP());
-
- server.on("/", handleRoot);
- server.on("/save", handleSave);
- server.begin(); // Web server start
-
- print("Web server is ready for config at http://");
- print(WiFi.softAPIP());
- println("/");
}
}
+void HanConfigAp::enableWeb() {
+ server.on("/", handleRoot);
+ server.on("/style.css", handleStyle);
+ server.on("/save", handleSave);
+ server.begin(); // Web server start
+
+ print("Web server is ready for config at http://");
+ if(isActivated) {
+ print(WiFi.softAPIP());
+ } else {
+ print(WiFi.localIP());
+ }
+ println("/");
+}
+
bool HanConfigAp::loop() {
- if (isActivated)
- {
+ if(isActivated) {
//DNS
dnsServer.processNextRequest();
- //HTTP
- server.handleClient();
- return true;
- }
- else
- {
- return false;
}
+
+ //HTTP
+ server.handleClient();
+
+ return isActivated;
}
/** Handle root or redirect to captive portal */
@@ -99,11 +105,72 @@ void HanConfigAp::handleRoot() {
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
- server.setContentLength(CONTENT_LENGTH_UNKNOWN);
- String html = String("\r\n\r\n
\r\n\t\r\n\r\n\r\n\r\n\t\r\n\r\n\t\r\n\r\n");
+ String html = CONFIG_HTML;
+
+ configuration *config = new configuration();
+ config->load();
+
+ if(config->hasConfig()) {
+ html.replace("${config.ssid}", config->ssid);
+ html.replace("${config.ssidPassword}", config->ssidPassword);
+ switch (config->meterType) {
+ case 1:
+ html.replace("${config.meterType0}", "");
+ html.replace("${config.meterType1}", "selected");
+ html.replace("${config.meterType2}", "");
+ html.replace("${config.meterType3}", "");
+ break;
+ case 2:
+ html.replace("${config.meterType0}", "");
+ html.replace("${config.meterType1}", "");
+ html.replace("${config.meterType2}", "selected");
+ html.replace("${config.meterType3}", "");
+ break;
+ case 3:
+ html.replace("${config.meterType0}", "");
+ html.replace("${config.meterType1}", "");
+ html.replace("${config.meterType2}", "");
+ html.replace("${config.meterType3}", "selected");
+ break;
+ default:
+ html.replace("${config.meterType0}", "selected");
+ html.replace("${config.meterType1}", "");
+ html.replace("${config.meterType2}", "");
+ html.replace("${config.meterType3}", "");
+ }
+ html.replace("${config.mqtt}", config->mqtt);
+ html.replace("${config.mqttPort}", String(config->mqttPort));
+ html.replace("${config.mqttClientID}", config->mqttClientID);
+ html.replace("${config.mqttPublishTopic}", config->mqttPublishTopic);
+ html.replace("${config.mqttSubscribeTopic}", config->mqttSubscribeTopic);
+ html.replace("${config.mqttUser}", config->mqttUser);
+ html.replace("${config.mqttPass}", config->mqttPass);
+ } else {
+ html.replace("${config.ssid}", "");
+ html.replace("${config.ssidPassword}", "");
+ html.replace("${config.meterType0}", "selected");
+ html.replace("${config.meterType1}", "");
+ html.replace("${config.meterType2}", "");
+ html.replace("${config.meterType3}", "");
+ html.replace("${config.mqtt}", "");
+ html.replace("${config.mqttPort}", "1883");
+ html.replace("${config.mqttClientID}", "");
+ html.replace("${config.mqttPublishTopic}", "");
+ html.replace("${config.mqttSubscribeTopic}", "");
+ html.replace("${config.mqttUser}", "");
+ html.replace("${config.mqttPass}", "");
+ }
server.send(200, "text/html", html);
}
+void HanConfigAp::handleStyle() {
+ println("Serving /style.css over http...");
+
+ server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
+ server.sendHeader("Pragma", "no-cache");
+ server.sendHeader("Expires", "-1");
+ server.send(200, "text/html", STYLE_CSS, sizeof(STYLE_CSS));
+}
void HanConfigAp::handleSave() {
configuration *config = new configuration();
@@ -151,7 +218,7 @@ void HanConfigAp::handleSave() {
if (HanConfigAp::debugger) config->print(HanConfigAp::debugger);
if (config->save())
{
- println("Successfully saved. Will roboot now.");
+ println("Successfully saved. Will reboot now.");
String html = "Successfully Saved!
Device is restarting now...
";
server.send(200, "text/html", html);
#if defined(ESP8266)
diff --git a/lib/HanConfigAp/src/HanConfigAp.h b/lib/HanConfigAp/src/HanConfigAp.h
index 42eab7c6..d1e01d85 100644
--- a/lib/HanConfigAp/src/HanConfigAp.h
+++ b/lib/HanConfigAp/src/HanConfigAp.h
@@ -27,6 +27,7 @@
class HanConfigAp {
public:
void setup(int accessPointButtonPin, Stream* debugger);
+ void enableWeb();
bool loop();
bool hasConfig();
configuration config;
@@ -46,6 +47,7 @@ private:
// Web server
static void handleRoot();
+ static void handleStyle();
static void handleSave();
#if defined(ESP8266)
static ESP8266WebServer server;
diff --git a/lib/HanConfigAp/src/config_html.h b/lib/HanConfigAp/src/config_html.h
new file mode 100644
index 00000000..ff2ea9a7
--- /dev/null
+++ b/lib/HanConfigAp/src/config_html.h
@@ -0,0 +1,72 @@
+const char CONFIG_HTML[] PROGMEM = R"=="==(
+
+
+
+
+
+
+
+
+ AMS2MQTT - configuration
+
+
+
+
+
+)=="==";
diff --git a/lib/HanConfigAp/src/style_css.h b/lib/HanConfigAp/src/style_css.h
new file mode 100644
index 00000000..9b28b09c
--- /dev/null
+++ b/lib/HanConfigAp/src/style_css.h
@@ -0,0 +1,135 @@
+const char STYLE_CSS[] PROGMEM = R"=="==(
+body,div,input {
+ font-family: "Roboto", Arial, Lucida Grande;
+}
+.wrapper {
+ width: 500px;
+ position: absolute;
+ padding: 30px;
+ background-color: #FFF;
+ border-radius: 1px;
+ color: #333;
+ border-color: rgba(0, 0, 0, 0.03);
+ box-shadow: 0 2px 2px rgba(0, 0, 0, .24), 0 0 2px rgba(0, 0, 0, .12);
+ margin-left: 20px;
+ margin-top: 20px;
+}
+div {
+ padding-bottom: 5px;
+}
+label {
+ font-family: "Roboto", "Helvetica Neue", sans-serif;
+ font-size: 14px;
+ line-height: 16px;
+ width: 100px;
+ display: inline-block;
+}
+input {
+ font-family: "Roboto", "Helvetica Neue", sans-serif;
+ font-size: 14px;
+ line-height: 16px;
+ bottom: 30px;
+ border: none;
+ border-bottom: 1px solid #d4d4d4;
+ padding: 10px;
+ background: transparent;
+ transition: all .25s ease;
+}
+input[type=number] {
+ width: 70px;
+ margin-left: 5px;
+}
+input:focus {
+ outline: none;
+ border-bottom: 1px solid #3f51b5;
+}
+h2 {
+ text-align: left;
+ font-size: 20px;
+ font-weight: bold;
+ letter-spacing: 3px;
+ line-height: 28px;
+}
+.submit-button {
+ position: absolute;
+ text-align: right;
+ border-radius: 20px;
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+ background-color: #3f51b5;
+ color: #FFF;
+ padding: 12px 25px;
+ display: inline-block;
+ font-size: 12px;
+ font-weight: bold;
+ letter-spacing: 2px;
+ right: 0px;
+ bottom: 10px;
+ cursor: pointer;
+ transition: all .25s ease;
+ box-shadow: 0 2px 2px rgba(0, 0, 0, .24), 0 0 2px rgba(0, 0, 0, .12);
+ width: 100px;
+}
+.select-style {
+ border-top: 10px solid white;
+ border-bottom: 1px solid #d4d4d4;
+ color: #ffffff;
+ cursor: pointer;
+ display: block;
+ font-family: Roboto, "Helvetica Neue", sans-serif;
+ font-size: 14px;
+ font-weight: 400;
+ height: 16px;
+ line-height: 14px;
+ min-width: 200px;
+ padding-bottom: 7px;
+ padding-left: 0px;
+ padding-right: 0px;
+ position: relative;
+ text-align: left;
+ width: 80%;
+ -webkit-box-direction: normal;
+ overflow: hidden;
+ background: #ffffff url("data:image/png;base64,R0lGODlhDwAUAIABAAAAAP///yH5BAEAAAEALAAAAAAPABQAAAIXjI+py+0Po5wH2HsXzmw//lHiSJZmUAAAOw==") no-repeat 98% 50%;
+}
+.disabled-option {
+ color: #d4d4d4;
+}
+.select-style select {
+ padding: 5px 8px;
+ width: 100%;
+ border: none;
+ box-shadow: none;
+ background: transparent;
+ background-image: none;
+ -webkit-appearance: none;
+}
+.select-style select:focus {
+ outline: none;
+ border: none;
+}
+@media only screen and (max-width: 1000px) {
+ .wrapper {
+ width: 80%;
+ }
+}
+@media only screen and (max-width: 300px) {
+ .wrapper {
+ width: 75%;
+ }
+}
+@media only screen and (max-width: 600px) {
+ .wrapper {
+ width: 80%;
+ margin-left: 0px;
+ margin-top: 0px;
+ }
+ .submit-button {
+ bottom: 0px;
+ width: 70px;
+ }
+ input {
+ width: 100%;
+ }
+}
+)=="==";
diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino
index 79cec03c..b3279749 100644
--- a/src/AmsToMqttBridge.ino
+++ b/src/AmsToMqttBridge.ino
@@ -59,10 +59,11 @@ HardwareSerial* debugger = NULL;
HanReader hanReader;
// the setup function runs once when you press reset or power the board
-void setup()
-{
- // Uncomment to debug over the same port as used for HAN communication
- //debugger = &Serial;
+void setup() {
+
+#if DEBUG_MODE
+ debugger = &Serial;
+#endif
if (debugger) {
// Setup serial port for debugging
@@ -100,6 +101,8 @@ void setup()
// Compensate for the known Kaifa bug
hanReader.compensateFor09HeaderBug = (ap.config.meterType == 1);
}
+
+ ap.enableWeb();
}
// the loop function runs over and over again until power down or reset