mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 15:36: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() {
|
app::app() : Main() {
|
||||||
mHoymiles = new hoymiles();
|
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();
|
mSendTicker = new Ticker();
|
||||||
mFlagSend = false;
|
mFlagSend = false;
|
||||||
|
|
||||||
|
mMqttTicker = NULL;
|
||||||
|
mMqttEvt = false;
|
||||||
|
|
||||||
memset(mCmds, 0, sizeof(uint32_t));
|
memset(mCmds, 0, sizeof(uint32_t));
|
||||||
memset(mChannelStat, 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) {
|
void app::setup(const char *ssid, const char *pwd, uint32_t timeout) {
|
||||||
Main::setup(ssid, pwd, timeout);
|
Main::setup(ssid, pwd, timeout);
|
||||||
|
|
||||||
mWeb->on("/", std::bind(&app::showIndex, this));
|
mWeb->on("/", std::bind(&app::showIndex, this));
|
||||||
mWeb->on("/setup", std::bind(&app::showSetup, this));
|
mWeb->on("/setup", std::bind(&app::showSetup, this));
|
||||||
mWeb->on("/save", std::bind(&app::showSave, this));
|
mWeb->on("/save", std::bind(&app::showSave, this));
|
||||||
mWeb->on("/cmdstat", std::bind(&app::showCmdStatistics, this));
|
mWeb->on("/cmdstat", std::bind(&app::showCmdStatistics, this));
|
||||||
mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this));
|
mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this));
|
||||||
mWeb->on("/livedata", std::bind(&app::showLiveData, this));
|
mWeb->on("/livedata", std::bind(&app::showLiveData, this));
|
||||||
|
mWeb->on("/mqttstate", std::bind(&app::showMqtt, this));
|
||||||
|
|
||||||
if(mSettingsValid)
|
if(mSettingsValid) {
|
||||||
mEep->read(ADDR_HOY_ADDR, mHoymiles->mAddrBytes, HOY_ADDR_LEN);
|
uint16_t interval;
|
||||||
else
|
|
||||||
|
// 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);
|
memset(mHoymiles->mAddrBytes, 0, 6);
|
||||||
|
}
|
||||||
mHoymiles->serial2RadioId();
|
mHoymiles->serial2RadioId();
|
||||||
|
|
||||||
initRadio();
|
initRadio();
|
||||||
|
|
||||||
if(mSettingsValid)
|
if(!mSettingsValid)
|
||||||
mSendTicker->attach_ms(1000, std::bind(&app::sendTicker, this));
|
|
||||||
else
|
|
||||||
Serial.println("Warn: your settings are not valid! check [IP]/setup");
|
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)) {
|
if(mHoymiles->checkCrc(p->packet, &len, &rptCnt)) {
|
||||||
// process buffer only on first occurrence
|
// process buffer only on first occurrence
|
||||||
if((0 != len) && (0 == rptCnt)) {
|
if((0 != len) && (0 == rptCnt)) {
|
||||||
Serial.println("CMD " + String(p->packet[11], HEX));
|
//Serial.println("CMD " + String(p->packet[11], HEX));
|
||||||
mHoymiles->dumpBuf("Payload ", p->packet, len);
|
//mHoymiles->dumpBuf("Payload ", p->packet, len);
|
||||||
|
|
||||||
mDecoder->convert(&p->packet[11], len);
|
mDecoder->convert(&p->packet[11], len);
|
||||||
|
|
||||||
|
@ -109,6 +143,14 @@ void app::loop(void) {
|
||||||
|
|
||||||
mSendCnt++;
|
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) {
|
void app::showIndex(void) {
|
||||||
String html = index_html;
|
String html = index_html;
|
||||||
|
@ -233,6 +281,8 @@ void app::showIndex(void) {
|
||||||
void app::showSetup(void) {
|
void app::showSetup(void) {
|
||||||
// overrides same method in main.cpp
|
// overrides same method in main.cpp
|
||||||
|
|
||||||
|
uint16_t interval;
|
||||||
|
|
||||||
String html = setup_html;
|
String html = setup_html;
|
||||||
html.replace("{SSID}", mStationSsid);
|
html.replace("{SSID}", mStationSsid);
|
||||||
// PWD will be left at the default value (for protection)
|
// PWD will be left at the default value (for protection)
|
||||||
|
@ -240,11 +290,37 @@ void app::showSetup(void) {
|
||||||
|
|
||||||
char addr[20] = {0};
|
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]);
|
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("{DEVICE}", String(mDeviceName));
|
||||||
html.replace("{VERSION}", String(mVersion));
|
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);
|
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) {
|
void app::saveValues(bool webSend = true) {
|
||||||
Main::saveValues(false); // general configuration
|
Main::saveValues(false); // general configuration
|
||||||
|
@ -319,17 +404,42 @@ void app::saveValues(bool webSend = true) {
|
||||||
char *p;
|
char *p;
|
||||||
char addr[20] = {0};
|
char addr[20] = {0};
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
|
uint16_t interval;
|
||||||
|
|
||||||
|
// hoymiles
|
||||||
memset(mHoymiles->mAddrBytes, 0, 6);
|
memset(mHoymiles->mAddrBytes, 0, 6);
|
||||||
mWeb->arg("hoy_addr").toCharArray(addr, 20);
|
mWeb->arg("inv0Addr").toCharArray(addr, 20);
|
||||||
|
|
||||||
p = strtok(addr, ":");
|
p = strtok(addr, ":");
|
||||||
while(NULL != p) {
|
while(NULL != p) {
|
||||||
mHoymiles->mAddrBytes[i++] = strtol(p, NULL, 16);
|
mHoymiles->mAddrBytes[i++] = strtol(p, NULL, 16);
|
||||||
p = strtok(NULL, ":");
|
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();
|
updateCrc();
|
||||||
if((mWeb->arg("reboot") == "on"))
|
if((mWeb->arg("reboot") == "on"))
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "hoymiles.h"
|
#include "hoymiles.h"
|
||||||
#include "hm1200Decode.h"
|
#include "hm1200Decode.h"
|
||||||
|
|
||||||
|
#include "mqtt.h"
|
||||||
|
|
||||||
|
|
||||||
class app : public Main {
|
class app : public Main {
|
||||||
public:
|
public:
|
||||||
|
@ -26,6 +28,7 @@ class app : public Main {
|
||||||
void sendPacket(uint8_t data[], uint8_t length);
|
void sendPacket(uint8_t data[], uint8_t length);
|
||||||
|
|
||||||
void sendTicker(void);
|
void sendTicker(void);
|
||||||
|
void mqttTicker(void);
|
||||||
|
|
||||||
void showIndex(void);
|
void showIndex(void);
|
||||||
void showSetup(void);
|
void showSetup(void);
|
||||||
|
@ -33,6 +36,7 @@ class app : public Main {
|
||||||
void showCmdStatistics(void);
|
void showCmdStatistics(void);
|
||||||
void showHoymiles(void);
|
void showHoymiles(void);
|
||||||
void showLiveData(void);
|
void showLiveData(void);
|
||||||
|
void showMqtt(void);
|
||||||
|
|
||||||
void saveValues(bool webSend);
|
void saveValues(bool webSend);
|
||||||
void dumpBuf(uint8_t buf[], uint8_t len);
|
void dumpBuf(uint8_t buf[], uint8_t len);
|
||||||
|
@ -55,6 +59,11 @@ class app : public Main {
|
||||||
|
|
||||||
uint32_t mCmds[6];
|
uint32_t mCmds[6];
|
||||||
uint32_t mChannelStat[4];
|
uint32_t mChannelStat[4];
|
||||||
|
|
||||||
|
// mqtt
|
||||||
|
mqtt mMqtt;
|
||||||
|
Ticker *mMqttTicker;
|
||||||
|
bool mMqttEvt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__APP_H__*/
|
#endif /*__APP_H__*/
|
||||||
|
|
|
@ -15,27 +15,47 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 1
|
#define VERSION_MINOR 1
|
||||||
#define VERSION_PATCH 10
|
#define VERSION_PATCH 11
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// EEPROM
|
// EEPROM
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define SSID_LEN 32
|
#define SSID_LEN 32
|
||||||
#define PWD_LEN 64
|
#define PWD_LEN 32
|
||||||
#define DEVNAME_LEN 32
|
#define DEVNAME_LEN 16
|
||||||
#define CRC_LEN 2
|
#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_START 0
|
||||||
#define ADDR_SSID ADDR_START
|
#define ADDR_SSID ADDR_START
|
||||||
#define ADDR_PWD ADDR_SSID + SSID_LEN
|
#define ADDR_PWD ADDR_SSID + SSID_LEN
|
||||||
#define ADDR_DEVNAME ADDR_PWD + PWD_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__*/
|
#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"/>
|
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
getAjax('/livedata', 'livedata')
|
getAjax('/livedata', 'livedata');
|
||||||
window.setInterval("getAjax('/livedata', 'livedata')", 10000);
|
window.setInterval("getAjax('/livedata', 'livedata')", 10000);
|
||||||
|
|
||||||
function getAjax(url, resid) {
|
function getAjax(url, resid) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.setInterval("getAjax('/uptime', 'uptime')", 1000);
|
window.setInterval("getAjax('/uptime', 'uptime')", 1000);
|
||||||
window.setInterval("getAjax('/time', 'time')", 1000);
|
window.setInterval("getAjax('/time', 'time')", 1000);
|
||||||
|
window.setInterval("getAjax('/mqttstate', 'mqtt')", 2000);
|
||||||
window.setInterval("getAjax('/cmdstat', 'cmds')", 2000);
|
window.setInterval("getAjax('/cmdstat', 'cmds')", 2000);
|
||||||
|
|
||||||
function getAjax(url, resid) {
|
function getAjax(url, resid) {
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
</p>
|
</p>
|
||||||
<p><span class="des">Uptime: </span><span id="uptime"></span></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">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>
|
<p><span class="des">Statistics: </span><pre id="cmds"></pre></p>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
|
|
|
@ -22,21 +22,51 @@
|
||||||
<input type="password" class="inputText" name="pwd" value="{PWD}" required/>
|
<input type="password" class="inputText" name="pwd" value="{PWD}" required/>
|
||||||
<span class="floating_label">PASSWORD</span>
|
<span class="floating_label">PASSWORD</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<p class="des">Device Host Name</p>
|
<p class="des">Device Host Name</p>
|
||||||
<div class="inputWrp">
|
<div class="inputWrp">
|
||||||
<input type="text" class="inputText" name="device" value="{DEVICE}" required/>
|
<input type="text" class="inputText" name="device" value="{DEVICE}" required/>
|
||||||
<span class="floating_label">DEVICE NAME</span>
|
<span class="floating_label">DEVICE NAME</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="des">General</p>
|
|
||||||
|
|
||||||
|
<p class="des">Inverter</p>
|
||||||
<div class="inputWrp">
|
<div class="inputWrp">
|
||||||
<input type="text" class="inputText" name="hoy_addr" value="{HOY_ADDR}" required/>
|
<input type="text" class="inputText" name="inv0Addr" value="{INV0_ADDR}" required/>
|
||||||
<span class="floating_label">HOYMILES ADDRESS (eg. 11:22:33:44:55:66)</span>
|
<span class="floating_label">INVERTER 0 ADDRESS (eg. 11:22:33:44:55:66)</span>
|
||||||
</div>
|
</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"/>
|
<input type="checkbox" class="cb" name="reboot"/>
|
||||||
<label for="reboot">Reboot device after successful save</label>
|
<label for="reboot">Reboot device after successful save</label>
|
||||||
|
|
||||||
<input type="submit" value="save" class="button" />
|
<input type="submit" value="save" class="button" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</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