mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 23:46:37 +02:00
* 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)
This commit is contained in:
parent
c4b731708a
commit
539d4f73c1
16 changed files with 166 additions and 84 deletions
|
@ -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
|
||||
|
|
|
@ -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
Normal file
42
tools/esp8266/config.h
Normal file
|
@ -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__*/
|
|
@ -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
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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\">© 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\">© 2022</p><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"right\">AHOY :: {VERSION}</p></div></body></html>";
|
||||
#endif /*__HOYMILES_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\">© 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\">© 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__*/
|
||||
|
|
|
@ -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\"> </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\"> </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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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">© 2022</p>
|
||||
<p class="left"><a href="/">Home</a></p>
|
||||
<p class="right">AHOY :: {VERSION}</p>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -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">© 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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,6 +35,7 @@ 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));
|
||||
|
@ -39,6 +43,7 @@ void Main::setup(const char *ssid, const char *pwd, uint32_t timeout) {
|
|||
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) {
|
||||
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;
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue