Browse Source

* added config.h for general configuration

* added option to compile WiFi SSID + PWD to firmware
* added option to configure WiFi access point name and password
* added feature to retry connect to station WiFi (configurable timeouts)
* updated index.html
* added option for factory reset
* added info about project on index.html
* moved "update" and "home" to footer
* fixed #23 HM1200 yield day unit
* fixed DNS name of ESP after setup (some commits before)
pull/25/head
lumapu 2 years ago
parent
commit
539d4f73c1
  1. 24
      tools/esp8266/app.cpp
  2. 1
      tools/esp8266/app.h
  3. 42
      tools/esp8266/config.h
  4. 15
      tools/esp8266/defines.h
  5. 4
      tools/esp8266/esp8266.ino
  6. 2
      tools/esp8266/hmDefines.h
  7. 2
      tools/esp8266/html/h/hoymiles_html.h
  8. 2
      tools/esp8266/html/h/index_html.h
  9. 2
      tools/esp8266/html/h/setup_html.h
  10. 2
      tools/esp8266/html/h/style_css.h
  11. 2
      tools/esp8266/html/hoymiles.html
  12. 15
      tools/esp8266/html/index.html
  13. 2
      tools/esp8266/html/setup.html
  14. 36
      tools/esp8266/html/style.css
  15. 82
      tools/esp8266/main.cpp
  16. 17
      tools/esp8266/main.h

24
tools/esp8266/app.cpp

@ -39,7 +39,6 @@ void app::setup(const char *ssid, const char *pwd, uint32_t timeout) {
mWeb->on("/cmdstat", std::bind(&app::showStatistics, this));
mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this));
mWeb->on("/livedata", std::bind(&app::showLiveData, this));
mWeb->on("/mqttstate", std::bind(&app::showMqtt, this));
if(mSettingsValid) {
uint64_t invSerial;
@ -154,7 +153,7 @@ void app::loop(void) {
mSys->BufCtrl.popBack();
}
if(checkTicker(&mSendTicker, &mSendInterval)) {
if(checkTicker(&mSendTicker, mSendInterval)) {
Inverter<> *inv;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
inv = mSys->getInverterByPos(i);
@ -168,7 +167,7 @@ void app::loop(void) {
// mqtt
mMqtt.loop();
if(checkTicker(&mMqttTicker, &mMqttInterval)) {
if(checkTicker(&mMqttTicker, mMqttInterval)) {
mMqtt.isConnected(true);
char topic[30], val[10];
for(uint8_t id = 0; id < mSys->getNumInverters(); id++) {
@ -360,11 +359,19 @@ void app::showStatistics(void) {
content += String("75: ") + String(mChannelStat[3]) + String("\n");*/
if(!mSys->Radio.isChipConnected())
content += "WARNING! your NRF24 module can't be reached, check the wiring\n";
content += "WARNING! your NRF24 module can't be reached, check the wiring and pinout (<a href=\"/setup\">setup</a>)\n";
if(mShowRebootRequest)
content += "INFO: reboot your ESP to apply all your configuration changes!\n";
if(!mSettingsValid)
content += "INFO: your settings are invalid, please switch to <a href=\"/setup\">setup</a> to correct this.\n";
content += "MQTT: ";
if(!mMqtt.isConnected())
content += "not ";
content += "connected\n";
mWeb->send(200, "text/plain", content);
}
@ -448,15 +455,6 @@ void app::showLiveData(void) {
}
//-----------------------------------------------------------------------------
void app::showMqtt(void) {
String txt = "connected";
if(!mMqtt.isConnected())
txt = "not " + txt;
mWeb->send(200, "text/plain", txt);
}
//-----------------------------------------------------------------------------
void app::saveValues(bool webSend = true) {
Main::saveValues(false); // general configuration

1
tools/esp8266/app.h

@ -47,7 +47,6 @@ class app : public Main {
void showStatistics(void);
void showHoymiles(void);
void showLiveData(void);
void showMqtt(void);
void saveValues(bool webSend);
void updateCrc(void);

42
tools/esp8266/config.h

@ -0,0 +1,42 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
// fallback WiFi info
#define FB_WIFI_SSID "YOUR_WIFI_SSID"
#define FB_WIFI_PWD "YOUR_WIFI_PWD"
// access point info
#define WIFI_AP_SSID "AHOY DTU"
#define WIFI_AP_PWD "esp_8266"
//-------------------------------------
// CONFIGURATION - COMPILE TIME
//-------------------------------------
// time in seconds how long the station info (ssid + pwd) will be tried
#define WIFI_TRY_CONNECT_TIME 15
// time during the ESP will act as access point on connection failure (to
// station) in seconds
#define WIFI_AP_ACTIVE_TIME 3*60
// default device name
#define DEF_DEVICE_NAME "ESP-DTU"
// number of packets hold in buffer
#define PACKET_BUFFER_SIZE 30
// number of configurable inverters
#define MAX_NUM_INVERTERS 3
// maximum human readable inverter name length
#define MAX_NAME_LENGTH 16
// maximum buffer length of packet received / sent to RF24 module
#define MAX_RF_PAYLOAD_SIZE 64
// changes the style of "/setup" page, visualized = nicer
#define LIVEDATA_VISUALIZED
#endif /*__CONFIG_H__*/

15
tools/esp8266/defines.h

@ -1,31 +1,22 @@
#ifndef __DEFINES_H__
#define __DEFINES_H__
#include "config.h"
//-------------------------------------
// PINOUT
// PINOUT (Default, can be changed in setup)
//-------------------------------------
#define RF24_CS_PIN 15
#define RF24_CE_PIN 2
#define RF24_IRQ_PIN 0
//-------------------------------------
// CONFIGURATION - COMPILE TIME
//-------------------------------------
#define PACKET_BUFFER_SIZE 30
#define MAX_NUM_INVERTERS 3
#define MAX_NAME_LENGTH 16
#define MAX_RF_PAYLOAD_SIZE 64
#define LIVEDATA_VISUALIZED // show live data pv-module wise or as dump
//-------------------------------------
// VERSION
//-------------------------------------
#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_PATCH 3
#define VERSION_PATCH 4
//-------------------------------------

4
tools/esp8266/esp8266.ino

@ -8,13 +8,13 @@
#include <ESP8266HTTPUpdateServer.h>
#include "app.h"
#include "config.h"
app myApp;
//-----------------------------------------------------------------------------
void setup() {
// AP name, password, timeout
myApp.setup("ESP AHOY", "esp_8266", 15);
myApp.setup(WIFI_AP_SSID, WIFI_AP_PWD, WIFI_TRY_CONNECT_TIME);
// TODO: move to HmRadio
attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING);

2
tools/esp8266/hmDefines.h

@ -146,8 +146,8 @@ const byteAssign_t hm1200assignment[] = {
{ FLD_F, UNIT_HZ, CH0, CMD84, 1, 2, 100 },
{ FLD_PCT, UNIT_PCT, CH0, CMD84, 9, 2, 10 },
{ FLD_T, UNIT_C, CH0, CMD84, 11, 2, 10 },
{ FLD_YD, UNIT_WH, CH0, CMDFF, CALC_YD_CH0, 0, 0 },
{ FLD_YT, UNIT_KWH, CH0, CMDFF, CALC_YT_CH0, 0, 0 },
{ FLD_YD, UNIT_KWH, CH0, CMDFF, CALC_YD_CH0, 0, 0 },
{ FLD_UDC, UNIT_V, CH2, CMDFF, CALC_UDC_CH, CH1, 0 },
{ FLD_UDC, UNIT_V, CH4, CMDFF, CALC_UDC_CH, CH3, 0 }
};

2
tools/esp8266/html/h/hoymiles_html.h

@ -1,4 +1,4 @@
#ifndef __HOYMILES_H__
#define __HOYMILES_H__
const char hoymiles_html[] PROGMEM = "<!doctype html><html><head><title>Index - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><script type=\"text/javascript\">getAjax('/livedata', 'livedata');window.setInterval(\"getAjax('/livedata', 'livedata')\", 10000);function getAjax(url, resid) {var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"GET\", url, true);http.onreadystatechange = print;http.send(null);}function print() {if(http.readyState == 4) {document.getElementById(resid).innerHTML = http.responseText;}}}</script><style type=\"text/css\"></style></head><body><h1>AHOY - {DEVICE}</h1><div id=\"content\" class=\"content\"><p><a href=\"/\">Home</a><br/></p><div id=\"livedata\"></div><p>Every 10 seconds the values are updated</p></div><div id=\"footer\"><p class=\"left\">&copy 2022</p><p class=\"right\">AHOY :: {VERSION}</p></div></body></html>";
const char hoymiles_html[] PROGMEM = "<!doctype html><html><head><title>Index - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><script type=\"text/javascript\">getAjax('/livedata', 'livedata');window.setInterval(\"getAjax('/livedata', 'livedata')\", 10000);function getAjax(url, resid) {var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"GET\", url, true);http.onreadystatechange = print;http.send(null);}function print() {if(http.readyState == 4) {document.getElementById(resid).innerHTML = http.responseText;}}}</script><style type=\"text/css\"></style></head><body><h1>AHOY - {DEVICE}</h1><div id=\"content\" class=\"content\"><div id=\"livedata\"></div><p>Every 10 seconds the values are updated</p></div><div id=\"footer\"><p class=\"left\">&copy 2022</p><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"right\">AHOY :: {VERSION}</p></div></body></html>";
#endif /*__HOYMILES_H__*/

2
tools/esp8266/html/h/index_html.h

@ -1,4 +1,4 @@
#ifndef __INDEX_H__
#define __INDEX_H__
const char index_html[] PROGMEM = "<!doctype html><html><head><title>Index - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><script type=\"text/javascript\">window.setInterval(\"getAjax('/uptime', 'uptime')\", 1000);window.setInterval(\"getAjax('/time', 'time')\", 1000);window.setInterval(\"getAjax('/mqttstate', 'mqtt')\", 2000);window.setInterval(\"getAjax('/cmdstat', 'cmds')\", 2000);function getAjax(url, resid) {var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"GET\", url, true);http.onreadystatechange = print;http.send(null);}function print() {if(http.readyState == 4) {document.getElementById(resid).innerHTML = http.responseText;}}}</script></head><body><h1>AHOY - {DEVICE}</h1><div id=\"content\" class=\"content\"><p><a href=\"/hoymiles\">Hoymiles</a><br/><a href=\"/update\">Update</a><br/><br/><a href=\"/setup\">Setup</a><br/><a href=\"/reboot\">Reboot</a></p><p><span class=\"des\">Uptime: </span><span id=\"uptime\"></span></p><p><span class=\"des\">Time: </span><span id=\"time\"></span></p><p><span class=\"des\">MQTT: </span><span id=\"mqtt\"></span></p><p><span class=\"des\">Statistics: </span><pre id=\"cmds\"></pre></p></div><div id=\"footer\"><p class=\"left\">&copy 2022</p><p class=\"right\">AHOY :: {VERSION}</p></div></body></html>";
const char index_html[] PROGMEM = "<!doctype html><html><head><title>Index - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><script type=\"text/javascript\">window.setInterval(\"getAjax('/uptime', 'uptime')\", 1000);window.setInterval(\"getAjax('/time', 'time')\", 1000);window.setInterval(\"getAjax('/cmdstat', 'cmds')\", 2000);function getAjax(url, resid) {var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"GET\", url, true);http.onreadystatechange = print;http.send(null);}function print() {if(http.readyState == 4) {document.getElementById(resid).innerHTML = http.responseText;}}}</script></head><body><h1>AHOY - {DEVICE}</h1><div id=\"content\" class=\"content\"><p><a href=\"/hoymiles\">Visualization</a><br/><br/><a href=\"/setup\">Setup</a><br/></p><p><span class=\"des\">Uptime: </span><span id=\"uptime\"></span></p><p><span class=\"des\">Time: </span><span id=\"time\"></span></p><p><span class=\"des\">Statistics: </span><pre id=\"cmds\"></pre></p><div id=\"note\">This project was started from <a href=\"https://www.mikrocontroller.net/topic/525778\" target=\"_blank\">this (Mikrocontroller.net)</a>discussion.<br/>New updates can be found on Github: <a href=\"https://github.com/grindylow/ahoy\" target=\"_blank\">https://github.com/grindylow/ahoy</a><br/><br/>Please report issues using the feature provided by Github. </div></div><div id=\"footer\"><p class=\"left\">&copy 2022</p><p class=\"left\"><a href=\"/update\">Update Firmware</a></p><p class=\"right\">AHOY :: {VERSION}</p><p class=\"right\"><a href=\"/reboot\">Reboot</a></p></div></body></html>";
#endif /*__INDEX_H__*/

2
tools/esp8266/html/h/setup_html.h

@ -1,4 +1,4 @@
#ifndef __SETUP_H__
#define __SETUP_H__
const char setup_html[] PROGMEM = "<!doctype html><html><head><title>Setup - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body><h1>Setup</h1><div id=\"setup\" class=\"content\"><div id=\"content\"><p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information. </p><form method=\"post\" action=\"/save\"><p class=\"des\">WiFi</p><label for=\"ssid\">SSID</label><input type=\"text\" class=\"text\" name=\"ssid\" value=\"{SSID}\"/><label for=\"pwd\">Password</label><input type=\"password\" class=\"text\" name=\"pwd\" value=\"{PWD}\"/><p class=\"des\">Device Host Name</p><label for=\"device\">Device Name</label><input type=\"text\" class=\"text\" name=\"device\" value=\"{DEVICE}\"/><a class=\"erase\" href=\"/erase\">ERASE SETTINGS (not WiFi)</a><p class=\"des\">Inverter</p>{INVERTERS}<br/><p class=\"subdes\">General</p><label for=\"invInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"invInterval\" value=\"{INV_INTERVAL}\"/><p class=\"des\">Pinout (Wemos)</p>{PINOUT}<p class=\"des\">Radio (NRF24L01+)</p><label for=\"rf24Power\">Amplifier Power Level</label><select name=\"rf24Power\">{RF24}</select><p class=\"des\">MQTT</p><label for=\"mqttAddr\">Broker / Server IP</label><input type=\"text\" class=\"text\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\"/><label for=\"mqttPort\">Port</label><input type=\"text\" class=\"text\" name=\"mqttPort\" value=\"{MQTT_PORT}\"/><label for=\"mqttUser\">Username (optional)</label><input type=\"text\" class=\"text\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><label for=\"mqttPwd\">Password (optional)</label><input type=\"text\" class=\"text\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><label for=\"mqttTopic\">Topic</label><input type=\"text\" class=\"text\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\"/><label for=\"mqttInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\"/><p class=\"des\">&nbsp;</p><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"btn\" /></form></div></div><div id=\"footer\"><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"left\"><a href=\"/update\">Update Firmware</a></p><p class=\"right\">AHOY - {VERSION}</p></div></body></html>";
const char setup_html[] PROGMEM = "<!doctype html><html><head><title>Setup - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body><h1>Setup</h1><div id=\"setup\" class=\"content\"><div id=\"content\"><p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information. </p><form method=\"post\" action=\"/save\"><p class=\"des\">WiFi</p><label for=\"ssid\">SSID</label><input type=\"text\" class=\"text\" name=\"ssid\" value=\"{SSID}\"/><label for=\"pwd\">Password</label><input type=\"password\" class=\"text\" name=\"pwd\" value=\"{PWD}\"/><p class=\"des\">Device Host Name</p><label for=\"device\">Device Name</label><input type=\"text\" class=\"text\" name=\"device\" value=\"{DEVICE}\"/><a class=\"erase\" href=\"/erase\">ERASE SETTINGS (not WiFi)</a><p class=\"des\">Inverter</p>{INVERTERS}<br/><p class=\"subdes\">General</p><label for=\"invInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"invInterval\" value=\"{INV_INTERVAL}\"/><p class=\"des\">Pinout (Wemos)</p>{PINOUT}<p class=\"des\">Radio (NRF24L01+)</p><label for=\"rf24Power\">Amplifier Power Level</label><select name=\"rf24Power\">{RF24}</select><p class=\"des\">MQTT</p><label for=\"mqttAddr\">Broker / Server IP</label><input type=\"text\" class=\"text\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\"/><label for=\"mqttPort\">Port</label><input type=\"text\" class=\"text\" name=\"mqttPort\" value=\"{MQTT_PORT}\"/><label for=\"mqttUser\">Username (optional)</label><input type=\"text\" class=\"text\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><label for=\"mqttPwd\">Password (optional)</label><input type=\"text\" class=\"text\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><label for=\"mqttTopic\">Topic</label><input type=\"text\" class=\"text\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\"/><label for=\"mqttInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\"/><p class=\"des\">&nbsp;</p><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"btn\" /></form></div></div><div id=\"footer\"><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"left\"><a href=\"/update\">Update Firmware</a></p><p class=\"right\">AHOY - {VERSION}</p><p class=\"right\"><a href=\"/factory\">Factory Reset</a></p><p class=\"right\"><a href=\"/reboot\">Reboot</a></p></div></body></html>";
#endif /*__SETUP_H__*/

2
tools/esp8266/html/h/style_css.h

@ -1,4 +1,4 @@
#ifndef __STYLE_H__
#define __STYLE_H__
const char style_css[] PROGMEM = "h1 {margin:0;padding:20pt;font-size:22pt;color:#fff;background-color:#006ec0;display:block;text-transform:uppercase;}html, body {font-family:Arial;margin:0;padding:0;}p {text-align:justify;font-size:13pt;}.des {margin-top:35px;font-size:14pt;color:#006ec0;}.subdes {font-size:13pt;color:#006ec0;margin-left:7px;}.fw {width:60px;display:block;float:left;}.color {width:50px;height:50px;border:1px solid #ccc;}.range {width:300px;}a:link, a:visited {text-decoration:none;font-size:13pt;color:#006ec0;}a:hover, a:focus {color:#f00;}a.erase {background-color:#006ec0;color:#fff;padding:7px;display:inline-block;margin-top:30px;float:right;}#content {padding:15px 15px 60px 15px;}#footer {position:fixed;bottom:0px;height:45px;background-color:#006ec0;width:100%;}#footer p {color:#fff;padding-left:20px;padding-right:20px;font-size:10pt !important;}#footer a {color:#fff;}div.content {background-color:#fff;padding-bottom:65px;overflow:auto;}input, select {padding:7px;font-size:13pt;}input.text, select {width:70%;box-sizing:border-box;margin-bottom:10px;border:1px solid #ccc;}input.btn {background-color:#006ec0;color:#fff;border:0px;float:right;margin:10px 0 30px;text-transform:uppercase;}input.cb {margin-bottom:20px;}label {width:20%;display:inline-block;font-size:12pt;padding-right:10px;margin-left:10px;}.left {float:left;}.right {float:right;}div.ch-iv {width:100%;background-color:#32b004;display:inline-block;margin-bottom:20px;padding-bottom:20px;overflow:auto;}div.ch {width:250px;height:550px;background-color:#006ec0;display:inline-block;margin-right:20px;margin-bottom:20px;overflow:auto;}div.ch .value, div.ch .info, div.ch .head, div.ch-iv .value, div.ch-iv .info, div.ch-iv .head {color:#fff;display:block;width:100%;text-align:center;}.subgrp {float:left;width:250px;}div.ch .unit, div.ch-iv .unit {font-size:19px;margin-left:10px;}div.ch .value, div.ch-iv .value {margin-top:20px;font-size:30px;}div.ch .info, div.ch-iv .info {margin-top:3px;font-size:10px;}div.ch .head {background-color:#003c80;padding:10px 0 10px 0;}div.ch-iv .head {background-color:#1c6800;padding:10px 0 10px 0;}div.iv {max-width:1060px;}div.ch:last-child {margin-right:0px !important;}";
const char style_css[] PROGMEM = "h1 {margin:0;padding:20pt;font-size:22pt;color:#fff;background-color:#006ec0;display:block;text-transform:uppercase;}html, body {font-family:Arial;margin:0;padding:0;}p {text-align:justify;font-size:13pt;}.des {margin-top:35px;font-size:13pt;color:#006ec0;}.subdes {font-size:12pt;color:#006ec0;margin-left:7px;}a:link, a:visited {text-decoration:none;font-size:13pt;color:#006ec0;}a:hover, a:focus {color:#f00;}a.erase {background-color:#006ec0;color:#fff;padding:7px;display:inline-block;margin-top:30px;float:right;}#content {padding:15px 15px 60px 15px;}#footer {position:fixed;bottom:0px;height:45px;background-color:#006ec0;width:100%;border-top:5px solid #fff;}#footer p, #footer a {color:#fff;padding-left:20px;padding-right:20px;font-size:10pt !important;}div.content {background-color:#fff;padding-bottom:65px;overflow:auto;}input, select {padding:7px;font-size:13pt;}input.text, select {width:70%;box-sizing:border-box;margin-bottom:10px;border:1px solid #ccc;}input.btn {background-color:#006ec0;color:#fff;border:0px;float:right;margin:10px 0 30px;text-transform:uppercase;}input.cb {margin-bottom:20px;}label {width:20%;display:inline-block;font-size:12pt;padding-right:10px;margin-left:10px;}.left {float:left;}.right {float:right;}div.ch-iv {width:100%;background-color:#32b004;display:inline-block;margin-bottom:20px;padding-bottom:20px;overflow:auto;}div.ch {width:250px;min-height:420px;background-color:#006ec0;display:inline-block;margin-right:20px;margin-bottom:20px;overflow:auto;padding-bottom:20px;}div.ch .value, div.ch .info, div.ch .head, div.ch-iv .value, div.ch-iv .info, div.ch-iv .head {color:#fff;display:block;width:100%;text-align:center;}.subgrp {float:left;width:250px;}div.ch .unit, div.ch-iv .unit {font-size:19px;margin-left:10px;}div.ch .value, div.ch-iv .value {margin-top:20px;font-size:30px;}div.ch .info, div.ch-iv .info {margin-top:3px;font-size:10px;}div.ch .head {background-color:#003c80;padding:10px 0 10px 0;}div.ch-iv .head {background-color:#1c6800;padding:10px 0 10px 0;}div.iv {max-width:1060px;}div.ch:last-child {margin-right:0px !important;}#note {margin:50px 10px 10px 10px;padding-top:10px;width:100%;border-top:1px solid #bbb;}";
#endif /*__STYLE_H__*/

2
tools/esp8266/html/hoymiles.html

@ -30,12 +30,12 @@
<body>
<h1>AHOY - {DEVICE}</h1>
<div id="content" class="content">
<p><a href="/">Home</a><br/></p>
<div id="livedata"></div>
<p>Every 10 seconds the values are updated</p>
</div>
<div id="footer">
<p class="left">&copy 2022</p>
<p class="left"><a href="/">Home</a></p>
<p class="right">AHOY :: {VERSION}</p>
</div>
</body>

15
tools/esp8266/html/index.html

@ -7,7 +7,6 @@
<script type="text/javascript">
window.setInterval("getAjax('/uptime', 'uptime')", 1000);
window.setInterval("getAjax('/time', 'time')", 1000);
window.setInterval("getAjax('/mqttstate', 'mqtt')", 2000);
window.setInterval("getAjax('/cmdstat', 'cmds')", 2000);
function getAjax(url, resid) {
@ -31,20 +30,26 @@
<h1>AHOY - {DEVICE}</h1>
<div id="content" class="content">
<p>
<a href="/hoymiles">Hoymiles</a><br/>
<a href="/update">Update</a><br/>
<a href="/hoymiles">Visualization</a><br/>
<br/>
<a href="/setup">Setup</a><br/>
<a href="/reboot">Reboot</a>
</p>
<p><span class="des">Uptime: </span><span id="uptime"></span></p>
<p><span class="des">Time: </span><span id="time"></span></p>
<p><span class="des">MQTT: </span><span id="mqtt"></span></p>
<p><span class="des">Statistics: </span><pre id="cmds"></pre></p>
<div id="note">
This project was started from <a href="https://www.mikrocontroller.net/topic/525778" target="_blank">this (Mikrocontroller.net)</a> discussion.<br/>
New updates can be found on Github: <a href="https://github.com/grindylow/ahoy" target="_blank">https://github.com/grindylow/ahoy</a><br/>
<br/>
Please report issues using the feature provided by Github.
</div>
</div>
<div id="footer">
<p class="left">&copy 2022</p>
<p class="left"><a href="/update">Update Firmware</a></p>
<p class="right">AHOY :: {VERSION}</p>
<p class="right"><a href="/reboot">Reboot</a></p>
</div>
</body>
</html>

2
tools/esp8266/html/setup.html

@ -64,6 +64,8 @@
<p class="left"><a href="/">Home</a></p>
<p class="left"><a href="/update">Update Firmware</a></p>
<p class="right">AHOY - {VERSION}</p>
<p class="right"><a href="/factory">Factory Reset</a></p>
<p class="right"><a href="/reboot">Reboot</a></p>
</div>
</body>
</html>

36
tools/esp8266/html/style.css

@ -21,31 +21,16 @@ p {
.des {
margin-top: 35px;
font-size: 14pt;
font-size: 13pt;
color: #006ec0;
}
.subdes {
font-size: 13pt;
font-size: 12pt;
color: #006ec0;
margin-left: 7px;
}
.fw {
width: 60px;
display: block;
float: left;
}
.color {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
.range {
width: 300px;
}
a:link, a:visited {
text-decoration: none;
@ -76,19 +61,16 @@ a.erase {
height: 45px;
background-color: #006ec0;
width: 100%;
border-top: 5px solid #fff;
}
#footer p {
#footer p, #footer a {
color: #fff;
padding-left: 20px;
padding-right: 20px;
font-size: 10pt !important;
}
#footer a {
color: #fff;
}
div.content {
background-color: #fff;
padding-bottom: 65px;
@ -147,12 +129,13 @@ div.ch-iv {
div.ch {
width: 250px;
height: 550px;
min-height: 420px;
background-color: #006ec0;
display: inline-block;
margin-right: 20px;
margin-bottom: 20px;
overflow: auto;
padding-bottom: 20px;
}
div.ch .value, div.ch .info, div.ch .head, div.ch-iv .value, div.ch-iv .info, div.ch-iv .head {
color: #fff;
@ -198,3 +181,10 @@ div.iv {
div.ch:last-child {
margin-right: 0px !important;
}
#note {
margin: 50px 10px 10px 10px;
padding-top: 10px;
width: 100%;
border-top: 1px solid #bbb;
}

82
tools/esp8266/main.cpp

@ -16,6 +16,9 @@ Main::Main(void) {
mWifiSettingsValid = false;
mSettingsValid = false;
mLimit = 10;
mNextTryTs = 0;
snprintf(mVersion, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
memset(&mDeviceName, 0, DEVNAME_LEN);
@ -32,14 +35,16 @@ Main::Main(void) {
//-----------------------------------------------------------------------------
void Main::setup(const char *ssid, const char *pwd, uint32_t timeout) {
bool startAp = mApActive;
mLimit = timeout;
mWeb->on("/setup", std::bind(&Main::showSetup, this));
mWeb->on("/save", std::bind(&Main::showSave, this));
mWeb->on("/uptime", std::bind(&Main::showUptime, this));
mWeb->on("/time", std::bind(&Main::showTime, this));
mWeb->on("/style.css", std::bind(&Main::showCss, this));
mWeb->on("/reboot", std::bind(&Main::showReboot, this));
mWeb->onNotFound (std::bind(&Main::showNotFound, this));
mWeb->on("/setup", std::bind(&Main::showSetup, this));
mWeb->on("/save", std::bind(&Main::showSave, this));
mWeb->on("/uptime", std::bind(&Main::showUptime, this));
mWeb->on("/time", std::bind(&Main::showTime, this));
mWeb->on("/style.css", std::bind(&Main::showCss, this));
mWeb->on("/reboot", std::bind(&Main::showReboot, this));
mWeb->on("/factory", std::bind(&Main::showFactoryRst, this));
mWeb->onNotFound ( std::bind(&Main::showNotFound, this));
startAp = getConfig();
@ -63,11 +68,17 @@ void Main::setup(const char *ssid, const char *pwd, uint32_t timeout) {
//-----------------------------------------------------------------------------
void Main::loop(void) {
if(mApActive)
if(mApActive) {
mDns->processNextRequest();
if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) {
mApActive = setupStation(mLimit);
if(mApActive)
setupAp(WIFI_AP_SSID, WIFI_AP_PWD);
}
}
mWeb->handleClient();
if(checkTicker(&mUptimeTicker, &mUptimeInterval)) {
if(checkTicker(&mUptimeTicker, mUptimeInterval)) {
mUptimeSecs++;
mTimestamp++;
}
@ -87,13 +98,16 @@ bool Main::getConfig(void) {
mEep->read(ADDR_DEVNAME, mDeviceName, DEVNAME_LEN);
}
else {
mApActive = true;
/*mApActive = true;
memset(mStationSsid, 0, SSID_LEN);
memset(mStationPwd, 0, PWD_LEN);
memset(mDeviceName, 0, DEVNAME_LEN);
// erase application settings except wifi settings
eraseSettings();
eraseSettings();*/
snprintf(mStationSsid, SSID_LEN, "%s", FB_WIFI_SSID);
snprintf(mStationPwd, PWD_LEN, "%s", FB_WIFI_PWD);
snprintf(mDeviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME);
}
return mApActive;
@ -123,15 +137,22 @@ void Main::setupAp(const char *ssid, const char *pwd) {
//-----------------------------------------------------------------------------
bool Main::setupStation(uint32_t timeout) {
int32_t cnt = timeout * 10;
int32_t cnt;
bool startAp = false;
if(timeout >= 3)
cnt = (timeout - 3) / 2 * 10;
else {
timeout = 1;
cnt = 1;
}
WiFi.mode(WIFI_STA);
WiFi.begin(mStationSsid, mStationPwd);
if(String(mDeviceName) != "")
WiFi.hostname(mDeviceName);
delay(5000);
delay(2000);
Serial.println("wait for network");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
@ -142,8 +163,10 @@ bool Main::setupStation(uint32_t timeout) {
if(timeout > 0) { // limit == 0 -> no limit
if(--cnt <= 0) {
startAp = true;
WiFi.disconnect();
if(WiFi.status() != WL_CONNECTED) {
startAp = true;
WiFi.disconnect();
}
delay(100);
break;
}
@ -275,6 +298,35 @@ void Main::showReboot(void) {
}
//-----------------------------------------------------------------------------
void Main::showFactoryRst(void) {
String content = "";
int refresh = 3;
if(mWeb->args() > 0) {
if(mWeb->arg("reset").toInt() == 1) {
eraseSettings(true);
content = "factory reset: success\n\nrebooting ... ";
refresh = 10;
}
else {
content = "factory reset: aborted";
refresh = 3;
}
}
else {
content = "<h1>Factory Reset</h1>";
content += "<p><a href=\"/factory?reset=1\">RESET</a><br/><br/><a href=\"/factory?reset=0\">CANCEL</a><br/></p>";
refresh = 120;
}
mWeb->send(200, "text/html", "<!doctype html><html><head><title>Factory Reset</title><meta http-equiv=\"refresh\" content=\"" + String(refresh) + "; URL=/\"></head><body>" + content + "</body></html>");
if(refresh == 10) {
delay(1000);
ESP.restart();
}
}
//-----------------------------------------------------------------------------
time_t Main::getNtpTime(void) {
time_t date = 0;

17
tools/esp8266/main.h

@ -52,9 +52,10 @@ class Main {
return (crcCheck == crcRd);
}
void eraseSettings(void) {
void eraseSettings(bool all = false) {
uint8_t buf[64] = {0};
uint16_t addr = ADDR_START_SETTINGS, end;
uint16_t addr = (all) ? ADDR_START : ADDR_START_SETTINGS;
uint16_t end;
do {
end = addr += 64;
if(end > (ADDR_SETTINGS_CRC + 2))
@ -63,14 +64,14 @@ class Main {
} while(addr < ADDR_START_SETTINGS);
}
inline bool checkTicker(uint32_t *ticker, uint16_t *interval) {
inline bool checkTicker(uint32_t *ticker, uint32_t interval) {
uint32_t mil = millis();
if(mil >= *ticker) {
*ticker = mil + *interval;
*ticker = mil + interval;
return true;
}
else if(mil < (*ticker - *interval)) {
*ticker = mil + *interval;
else if(mil < (*ticker - interval)) {
*ticker = mil + interval;
return true;
}
@ -87,7 +88,8 @@ class Main {
char mDeviceName[DEVNAME_LEN];
eep *mEep;
uint32_t mTimestamp;
uint32_t mLimit;
uint32_t mNextTryTs;
private:
bool getConfig(void);
@ -100,6 +102,7 @@ class Main {
void showUptime(void);
void showTime(void);
void showCss(void);
void showFactoryRst(void);
time_t getNtpTime(void);
void sendNTPpacket(IPAddress& address);

Loading…
Cancel
Save