mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 07:26:38 +02:00
* added mqtt
This commit is contained in:
parent
8bfbd8d45b
commit
c00be7bb35
10 changed files with 299 additions and 38 deletions
|
@ -7,13 +7,15 @@ extern String setup_html;
|
|||
//-----------------------------------------------------------------------------
|
||||
app::app() : Main() {
|
||||
mHoymiles = new hoymiles();
|
||||
mDecoder = new hm1200Decode();
|
||||
mDecoder = new hm1200Decode();
|
||||
mBufCtrl = new CircularBuffer(mBuffer, PACKET_BUFFER_SIZE);
|
||||
|
||||
mBufCtrl = new CircularBuffer(mBuffer, PACKET_BUFFER_SIZE);
|
||||
|
||||
mSendCnt = 0;
|
||||
mSendCnt = 0;
|
||||
mSendTicker = new Ticker();
|
||||
mFlagSend = false;
|
||||
mFlagSend = false;
|
||||
|
||||
mMqttTicker = NULL;
|
||||
mMqttEvt = false;
|
||||
|
||||
memset(mCmds, 0, sizeof(uint32_t));
|
||||
memset(mChannelStat, 0, sizeof(uint32_t));
|
||||
|
@ -30,24 +32,56 @@ app::~app(void) {
|
|||
void app::setup(const char *ssid, const char *pwd, uint32_t timeout) {
|
||||
Main::setup(ssid, pwd, timeout);
|
||||
|
||||
mWeb->on("/", std::bind(&app::showIndex, this));
|
||||
mWeb->on("/setup", std::bind(&app::showSetup, this));
|
||||
mWeb->on("/save", std::bind(&app::showSave, this));
|
||||
mWeb->on("/cmdstat", std::bind(&app::showCmdStatistics, this));
|
||||
mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this));
|
||||
mWeb->on("/livedata", std::bind(&app::showLiveData, this));
|
||||
mWeb->on("/", std::bind(&app::showIndex, this));
|
||||
mWeb->on("/setup", std::bind(&app::showSetup, this));
|
||||
mWeb->on("/save", std::bind(&app::showSave, this));
|
||||
mWeb->on("/cmdstat", std::bind(&app::showCmdStatistics, 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)
|
||||
mEep->read(ADDR_HOY_ADDR, mHoymiles->mAddrBytes, HOY_ADDR_LEN);
|
||||
else
|
||||
if(mSettingsValid) {
|
||||
uint16_t interval;
|
||||
|
||||
// hoymiles
|
||||
mEep->read(ADDR_INV0_ADDR, mHoymiles->mAddrBytes, INV_ADDR_LEN);
|
||||
mEep->read(ADDR_INV_INTERVAL, &interval);
|
||||
|
||||
if(interval < 1000)
|
||||
interval = 1000;
|
||||
mSendTicker->attach_ms(interval, std::bind(&app::sendTicker, this));
|
||||
|
||||
|
||||
// mqtt
|
||||
uint8_t mqttAddr[MQTT_ADDR_LEN];
|
||||
char mqttUser[MQTT_USER_LEN];
|
||||
char mqttPwd[MQTT_PWD_LEN];
|
||||
char mqttTopic[MQTT_TOPIC_LEN];
|
||||
mEep->read(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN);
|
||||
mEep->read(ADDR_MQTT_USER, mqttUser, MQTT_USER_LEN);
|
||||
mEep->read(ADDR_MQTT_PWD, mqttPwd, MQTT_PWD_LEN);
|
||||
mEep->read(ADDR_MQTT_TOPIC, mqttTopic, MQTT_TOPIC_LEN);
|
||||
mEep->read(ADDR_MQTT_INTERVAL, &interval);
|
||||
|
||||
char addr[16] = {0};
|
||||
sprintf(addr, "%d.%d.%d.%d", mqttAddr[0], mqttAddr[1], mqttAddr[2], mqttAddr[3]);
|
||||
|
||||
if(interval < 1000)
|
||||
interval = 1000;
|
||||
mMqtt.setup(addr, mqttTopic, mqttUser, mqttPwd);
|
||||
mMqttTicker = new Ticker();
|
||||
mMqttTicker->attach_ms(interval, std::bind(&app::mqttTicker, this));
|
||||
|
||||
mMqtt.sendMsg("version", mVersion);
|
||||
}
|
||||
else {
|
||||
memset(mHoymiles->mAddrBytes, 0, 6);
|
||||
}
|
||||
mHoymiles->serial2RadioId();
|
||||
|
||||
initRadio();
|
||||
|
||||
if(mSettingsValid)
|
||||
mSendTicker->attach_ms(1000, std::bind(&app::sendTicker, this));
|
||||
else
|
||||
if(!mSettingsValid)
|
||||
Serial.println("Warn: your settings are not valid! check [IP]/setup");
|
||||
}
|
||||
|
||||
|
@ -65,8 +99,8 @@ void app::loop(void) {
|
|||
if(mHoymiles->checkCrc(p->packet, &len, &rptCnt)) {
|
||||
// process buffer only on first occurrence
|
||||
if((0 != len) && (0 == rptCnt)) {
|
||||
Serial.println("CMD " + String(p->packet[11], HEX));
|
||||
mHoymiles->dumpBuf("Payload ", p->packet, len);
|
||||
//Serial.println("CMD " + String(p->packet[11], HEX));
|
||||
//mHoymiles->dumpBuf("Payload ", p->packet, len);
|
||||
|
||||
mDecoder->convert(&p->packet[11], len);
|
||||
|
||||
|
@ -109,6 +143,14 @@ void app::loop(void) {
|
|||
|
||||
mSendCnt++;
|
||||
}
|
||||
|
||||
|
||||
// mqtt
|
||||
mMqtt.loop();
|
||||
if(mMqttEvt) {
|
||||
mMqttEvt = false;
|
||||
mMqtt.isConnected(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,6 +262,12 @@ void app::sendTicker(void) {
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::mqttTicker(void) {
|
||||
mMqttEvt = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::showIndex(void) {
|
||||
String html = index_html;
|
||||
|
@ -233,6 +281,8 @@ void app::showIndex(void) {
|
|||
void app::showSetup(void) {
|
||||
// overrides same method in main.cpp
|
||||
|
||||
uint16_t interval;
|
||||
|
||||
String html = setup_html;
|
||||
html.replace("{SSID}", mStationSsid);
|
||||
// PWD will be left at the default value (for protection)
|
||||
|
@ -240,11 +290,37 @@ void app::showSetup(void) {
|
|||
|
||||
char addr[20] = {0};
|
||||
sprintf(addr, "%02X:%02X:%02X:%02X:%02X:%02X", mHoymiles->mAddrBytes[0], mHoymiles->mAddrBytes[1], mHoymiles->mAddrBytes[2], mHoymiles->mAddrBytes[3], mHoymiles->mAddrBytes[4], mHoymiles->mAddrBytes[5]);
|
||||
html.replace("{HOY_ADDR}", String(addr));
|
||||
html.replace("{INV0_ADDR}", String(addr));
|
||||
|
||||
html.replace("{DEVICE}", String(mDeviceName));
|
||||
html.replace("{VERSION}", String(mVersion));
|
||||
|
||||
if(mSettingsValid) {
|
||||
mEep->read(ADDR_INV_INTERVAL, &interval);
|
||||
html.replace("{INV_INTERVAL}", String(interval));
|
||||
|
||||
uint8_t mqttAddr[MQTT_ADDR_LEN] = {0};
|
||||
mEep->read(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN);
|
||||
mEep->read(ADDR_MQTT_INTERVAL, &interval);
|
||||
|
||||
char addr[16] = {0};
|
||||
sprintf(addr, "%d.%d.%d.%d", mqttAddr[0], mqttAddr[1], mqttAddr[2], mqttAddr[3]);
|
||||
html.replace("{MQTT_ADDR}", String(addr));
|
||||
html.replace("{MQTT_USER}", String(mMqtt.getUser()));
|
||||
html.replace("{MQTT_PWD}", String(mMqtt.getPwd()));
|
||||
html.replace("{MQTT_TOPIC}", String(mMqtt.getTopic()));
|
||||
html.replace("{MQTT_INTERVAL}", String(interval));
|
||||
}
|
||||
else {
|
||||
html.replace("{INV_INTERVAL}", "1000");
|
||||
|
||||
html.replace("{MQTT_ADDR}", "");
|
||||
html.replace("{MQTT_USER}", "");
|
||||
html.replace("{MQTT_PWD}", "");
|
||||
html.replace("{MQTT_TOPIC}", "/inverter");
|
||||
html.replace("{MQTT_INTERVAL}", "10000");
|
||||
}
|
||||
|
||||
mWeb->send(200, "text/html", html);
|
||||
}
|
||||
|
||||
|
@ -311,6 +387,15 @@ 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
|
||||
|
@ -319,17 +404,42 @@ void app::saveValues(bool webSend = true) {
|
|||
char *p;
|
||||
char addr[20] = {0};
|
||||
uint8_t i = 0;
|
||||
uint16_t interval;
|
||||
|
||||
// hoymiles
|
||||
memset(mHoymiles->mAddrBytes, 0, 6);
|
||||
mWeb->arg("hoy_addr").toCharArray(addr, 20);
|
||||
|
||||
mWeb->arg("inv0Addr").toCharArray(addr, 20);
|
||||
p = strtok(addr, ":");
|
||||
while(NULL != p) {
|
||||
mHoymiles->mAddrBytes[i++] = strtol(p, NULL, 16);
|
||||
p = strtok(NULL, ":");
|
||||
}
|
||||
interval = mWeb->arg("invInterval").toInt();
|
||||
mEep->write(ADDR_INV0_ADDR, mHoymiles->mAddrBytes, INV_ADDR_LEN);
|
||||
mEep->write(ADDR_INV_INTERVAL, interval);
|
||||
|
||||
mEep->write(ADDR_HOY_ADDR, mHoymiles->mAddrBytes, HOY_ADDR_LEN);
|
||||
|
||||
// mqtt
|
||||
uint8_t mqttAddr[MQTT_ADDR_LEN] = {0};
|
||||
char mqttUser[MQTT_USER_LEN];
|
||||
char mqttPwd[MQTT_PWD_LEN];
|
||||
char mqttTopic[MQTT_TOPIC_LEN];
|
||||
mWeb->arg("mqttAddr").toCharArray(addr, 20);
|
||||
i = 0;
|
||||
p = strtok(addr, ".");
|
||||
while(NULL != p) {
|
||||
mqttAddr[i++] = atoi(p);
|
||||
p = strtok(NULL, ".");
|
||||
}
|
||||
mWeb->arg("mqttUser").toCharArray(mqttUser, MQTT_USER_LEN);
|
||||
mWeb->arg("mqttPwd").toCharArray(mqttPwd, MQTT_PWD_LEN);
|
||||
mWeb->arg("mqttTopic").toCharArray(mqttTopic, MQTT_TOPIC_LEN);
|
||||
interval = mWeb->arg("mqttInterval").toInt();
|
||||
mEep->write(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN);
|
||||
mEep->write(ADDR_MQTT_USER, mqttUser, MQTT_USER_LEN);
|
||||
mEep->write(ADDR_MQTT_PWD, mqttPwd, MQTT_PWD_LEN);
|
||||
mEep->write(ADDR_MQTT_TOPIC, mqttTopic, MQTT_TOPIC_LEN);
|
||||
mEep->write(ADDR_MQTT_INTERVAL, interval);
|
||||
|
||||
updateCrc();
|
||||
if((mWeb->arg("reboot") == "on"))
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "hoymiles.h"
|
||||
#include "hm1200Decode.h"
|
||||
|
||||
#include "mqtt.h"
|
||||
|
||||
|
||||
class app : public Main {
|
||||
public:
|
||||
|
@ -26,6 +28,7 @@ class app : public Main {
|
|||
void sendPacket(uint8_t data[], uint8_t length);
|
||||
|
||||
void sendTicker(void);
|
||||
void mqttTicker(void);
|
||||
|
||||
void showIndex(void);
|
||||
void showSetup(void);
|
||||
|
@ -33,6 +36,7 @@ class app : public Main {
|
|||
void showCmdStatistics(void);
|
||||
void showHoymiles(void);
|
||||
void showLiveData(void);
|
||||
void showMqtt(void);
|
||||
|
||||
void saveValues(bool webSend);
|
||||
void dumpBuf(uint8_t buf[], uint8_t len);
|
||||
|
@ -55,6 +59,11 @@ class app : public Main {
|
|||
|
||||
uint32_t mCmds[6];
|
||||
uint32_t mChannelStat[4];
|
||||
|
||||
// mqtt
|
||||
mqtt mMqtt;
|
||||
Ticker *mMqttTicker;
|
||||
bool mMqttEvt;
|
||||
};
|
||||
|
||||
#endif /*__APP_H__*/
|
||||
|
|
|
@ -15,27 +15,47 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_PATCH 10
|
||||
#define VERSION_PATCH 11
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
// EEPROM
|
||||
//-------------------------------------
|
||||
#define SSID_LEN 32
|
||||
#define PWD_LEN 64
|
||||
#define DEVNAME_LEN 32
|
||||
#define PWD_LEN 32
|
||||
#define DEVNAME_LEN 16
|
||||
#define CRC_LEN 2
|
||||
|
||||
#define HOY_ADDR_LEN 6
|
||||
#define INV_ADDR_LEN 6
|
||||
#define INV_INTERVAL_LEN 2 // uint16_t
|
||||
|
||||
|
||||
#define MQTT_ADDR_LEN 4 // IP
|
||||
#define MQTT_USER_LEN 16
|
||||
#define MQTT_PWD_LEN 32
|
||||
#define MQTT_TOPIC_LEN 32
|
||||
#define MQTT_INTERVAL_LEN 2 // uint16_t
|
||||
|
||||
|
||||
#define ADDR_START 0
|
||||
#define ADDR_SSID ADDR_START
|
||||
#define ADDR_PWD ADDR_SSID + SSID_LEN
|
||||
#define ADDR_DEVNAME ADDR_PWD + PWD_LEN
|
||||
#define ADDR_HOY_ADDR ADDR_DEVNAME + DEVNAME_LEN
|
||||
#define ADDR_INV0_ADDR ADDR_DEVNAME + DEVNAME_LEN
|
||||
#define ADDR_INV_INTERVAL ADDR_INV0_ADDR + INV_ADDR_LEN
|
||||
|
||||
#define ADDR_NEXT ADDR_HOY_ADDR + HOY_ADDR_LEN
|
||||
#define ADDR_MQTT_ADDR ADDR_INV_INTERVAL + INV_INTERVAL_LEN
|
||||
#define ADDR_MQTT_USER ADDR_MQTT_ADDR + MQTT_ADDR_LEN
|
||||
#define ADDR_MQTT_PWD ADDR_MQTT_USER + MQTT_USER_LEN
|
||||
#define ADDR_MQTT_TOPIC ADDR_MQTT_PWD + MQTT_PWD_LEN
|
||||
#define ADDR_MQTT_INTERVAL ADDR_MQTT_TOPIC + MQTT_TOPIC_LEN
|
||||
|
||||
#define ADDR_SETTINGS_CRC 200
|
||||
#define ADDR_NEXT ADDR_MQTT_INTERVAL + MQTT_INTERVAL_LEN
|
||||
|
||||
#define ADDR_SETTINGS_CRC 400
|
||||
|
||||
#if(ADDR_SETTINGS_CRC <= ADDR_NEXT)
|
||||
#error address overlap!
|
||||
#endif
|
||||
|
||||
#endif /*__DEFINES_H__*/
|
||||
|
|
|
@ -1 +1 @@
|
|||
String hoymiles_html = "<!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>";
|
||||
String hoymiles_html = "<!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>";
|
||||
|
|
|
@ -1 +1 @@
|
|||
String index_html = "<!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\">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\">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>";
|
||||
String index_html = "<!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>";
|
||||
|
|
|
@ -1 +1 @@
|
|||
String setup_html = "<!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><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"ssid\" value=\"{SSID}\" required/><span class=\"floating_label\">SSID</span></div><div class=\"inputWrp\"><input type=\"password\" class=\"inputText\" name=\"pwd\" value=\"{PWD}\" required/><span class=\"floating_label\">PASSWORD</span></div><p class=\"des\">Device Host Name</p><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"device\" value=\"{DEVICE}\" required/><span class=\"floating_label\">DEVICE NAME</span></div><p class=\"des\">General</p><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"hoy_addr\" value=\"{HOY_ADDR}\" required/><span class=\"floating_label\">HOYMILES ADDRESS (eg. 11:22:33:44:55:66)</span></div><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"button\" /></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>";
|
||||
String setup_html = "<!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><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"ssid\" value=\"{SSID}\" required/><span class=\"floating_label\">SSID</span></div><div class=\"inputWrp\"><input type=\"password\" class=\"inputText\" name=\"pwd\" value=\"{PWD}\" required/><span class=\"floating_label\">PASSWORD</span></div><p class=\"des\">Device Host Name</p><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"device\" value=\"{DEVICE}\" required/><span class=\"floating_label\">DEVICE NAME</span></div><p class=\"des\">Inverter</p><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"inv0Addr\" value=\"{INV0_ADDR}\" required/><span class=\"floating_label\">INVERTER 0 ADDRESS (eg. 11:22:33:44:55:66)</span></div><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"invInterval\" value=\"{INV_INTERVAL}\" required/><span class=\"floating_label\">INTERVAL (ms)</span></div><p class=\"des\">MQTT</p><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\" required/><span class=\"floating_label\">BROKER (Server IP)</span></div><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><span class=\"floating_label\">USERNAME (optional)</span></div><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><span class=\"floating_label\">PASSWORD (optional)</span></div><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\" required/><span class=\"floating_label\">TOPIC</span></div><div class=\"inputWrp\"><input type=\"text\" class=\"inputText\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\" required/><span class=\"floating_label\">INTERVAL (ms)</span></div><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"button\" /></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>";
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<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')
|
||||
getAjax('/livedata', 'livedata');
|
||||
window.setInterval("getAjax('/livedata', 'livedata')", 10000);
|
||||
|
||||
function getAjax(url, resid) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<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) {
|
||||
|
@ -38,6 +39,7 @@
|
|||
</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">
|
||||
|
|
|
@ -22,21 +22,51 @@
|
|||
<input type="password" class="inputText" name="pwd" value="{PWD}" required/>
|
||||
<span class="floating_label">PASSWORD</span>
|
||||
</div>
|
||||
|
||||
|
||||
<p class="des">Device Host Name</p>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="device" value="{DEVICE}" required/>
|
||||
<span class="floating_label">DEVICE NAME</span>
|
||||
</div>
|
||||
|
||||
<p class="des">General</p>
|
||||
|
||||
<p class="des">Inverter</p>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="hoy_addr" value="{HOY_ADDR}" required/>
|
||||
<span class="floating_label">HOYMILES ADDRESS (eg. 11:22:33:44:55:66)</span>
|
||||
<input type="text" class="inputText" name="inv0Addr" value="{INV0_ADDR}" required/>
|
||||
<span class="floating_label">INVERTER 0 ADDRESS (eg. 11:22:33:44:55:66)</span>
|
||||
</div>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="invInterval" value="{INV_INTERVAL}" required/>
|
||||
<span class="floating_label">INTERVAL (ms)</span>
|
||||
</div>
|
||||
|
||||
|
||||
<p class="des">MQTT</p>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="mqttAddr" value="{MQTT_ADDR}" required/>
|
||||
<span class="floating_label">BROKER (Server IP)</span>
|
||||
</div>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="mqttUser" value="{MQTT_USER}"/>
|
||||
<span class="floating_label">USERNAME (optional)</span>
|
||||
</div>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="mqttPwd" value="{MQTT_PWD}"/>
|
||||
<span class="floating_label">PASSWORD (optional)</span>
|
||||
</div>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="mqttTopic" value="{MQTT_TOPIC}" required/>
|
||||
<span class="floating_label">TOPIC</span>
|
||||
</div>
|
||||
<div class="inputWrp">
|
||||
<input type="text" class="inputText" name="mqttInterval" value="{MQTT_INTERVAL}" required/>
|
||||
<span class="floating_label">INTERVAL (ms)</span>
|
||||
</div>
|
||||
|
||||
|
||||
<input type="checkbox" class="cb" name="reboot"/>
|
||||
<label for="reboot">Reboot device after successful save</label>
|
||||
|
||||
<input type="submit" value="save" class="button" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
90
tools/esp8266/mqtt.h
Normal file
90
tools/esp8266/mqtt.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
#ifndef __MQTT_H__
|
||||
#define __MQTT_H__
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include "defines.h"
|
||||
|
||||
class mqtt {
|
||||
public:
|
||||
mqtt() {
|
||||
mClient = new PubSubClient(mEspClient);
|
||||
mAddressSet = false;
|
||||
|
||||
memset(mUser, 0, MQTT_USER_LEN);
|
||||
memset(mPwd, 0, MQTT_PWD_LEN);
|
||||
memset(mTopic, 0, MQTT_TOPIC_LEN);
|
||||
}
|
||||
|
||||
~mqtt() {
|
||||
delete mClient;
|
||||
}
|
||||
|
||||
void setup(const char *broker, const char *topic, const char *user, const char *pwd) {
|
||||
mAddressSet = true;
|
||||
mClient->setServer(broker, 1883);
|
||||
|
||||
snprintf(mUser, MQTT_USER_LEN, "%s", user);
|
||||
snprintf(mPwd, MQTT_PWD_LEN, "%s", pwd);
|
||||
snprintf(mTopic, MQTT_TOPIC_LEN, "%s", topic);
|
||||
}
|
||||
|
||||
void sendMsg(const char *topic, const char *msg) {
|
||||
if(mAddressSet) {
|
||||
uint8_t len = MQTT_TOPIC_LEN + strlen(msg);
|
||||
char top[len];
|
||||
snprintf(top, len, "%s/%s", mTopic, topic);
|
||||
|
||||
if(!mClient->connected())
|
||||
reconnect();
|
||||
mClient->publish(top, msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool isConnected(bool doRecon = false) {
|
||||
if(doRecon)
|
||||
reconnect();
|
||||
return mClient->connected();
|
||||
}
|
||||
|
||||
char *getUser(void) {
|
||||
return mUser;
|
||||
}
|
||||
|
||||
char *getPwd(void) {
|
||||
return mUser;
|
||||
}
|
||||
|
||||
char *getTopic(void) {
|
||||
return mTopic;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//if(!mClient->connected())
|
||||
// reconnect();
|
||||
mClient->loop();
|
||||
}
|
||||
|
||||
private:
|
||||
void reconnect(void) {
|
||||
if(!mClient->connected()) {
|
||||
String mqttId = "ESP-" + String(random(0xffff), HEX);
|
||||
if((strlen(mUser) > 0) && (strlen(mPwd) > 0)) {
|
||||
mClient->connect(mqttId.c_str(), mUser, mPwd);
|
||||
}
|
||||
else {
|
||||
mClient->connect(mqttId.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WiFiClient mEspClient;
|
||||
PubSubClient *mClient;
|
||||
|
||||
bool mAddressSet;
|
||||
char mUser[MQTT_USER_LEN];
|
||||
char mPwd[MQTT_PWD_LEN];
|
||||
char mTopic[MQTT_TOPIC_LEN];
|
||||
};
|
||||
|
||||
#endif /*__MQTT_H_*/
|
Loading…
Add table
Add a link
Reference in a new issue