mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-30 21:51:52 +00:00
Merge remote-tracking branch 'upstream/dev-v1.3.0' into add_domoticz
This commit is contained in:
@@ -160,6 +160,15 @@ void AmsConfiguration::setMqttPayloadFormat(int mqttPayloadFormat) {
|
||||
this->mqttPayloadFormat = mqttPayloadFormat;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isMqttSsl() {
|
||||
return this->mqttSsl;
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttSsl(bool mqttSsl) {
|
||||
mqttChanged |= this->mqttSsl != mqttSsl;
|
||||
this->mqttSsl = mqttSsl;
|
||||
}
|
||||
|
||||
void AmsConfiguration::clearMqtt() {
|
||||
setMqttHost("");
|
||||
setMqttPort(1883);
|
||||
@@ -170,6 +179,10 @@ void AmsConfiguration::clearMqtt() {
|
||||
setMqttPassword("");
|
||||
}
|
||||
|
||||
void AmsConfiguration::setMqttChanged() {
|
||||
mqttChanged = true;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isMqttChanged() {
|
||||
return mqttChanged;
|
||||
}
|
||||
@@ -341,7 +354,7 @@ bool AmsConfiguration::hasConfig() {
|
||||
case 75:
|
||||
case 80:
|
||||
case 81:
|
||||
case 91: // domoticz (based on 81)
|
||||
case 82:
|
||||
return true;
|
||||
default:
|
||||
configVersion = 0;
|
||||
@@ -374,8 +387,8 @@ bool AmsConfiguration::load() {
|
||||
case 81:
|
||||
success = loadConfig81(address);
|
||||
break;
|
||||
case 91:
|
||||
success = loadConfig91(address);
|
||||
case 82:
|
||||
success = loadConfig82(address);
|
||||
break;
|
||||
}
|
||||
EEPROM.end();
|
||||
@@ -678,9 +691,9 @@ bool AmsConfiguration::loadConfig81(int address) {
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// domoticz (based on 81)
|
||||
//
|
||||
bool AmsConfiguration::loadConfig91(int address) {
|
||||
//
|
||||
bool AmsConfiguration::loadConfig82(int address) {
|
||||
char* temp;
|
||||
|
||||
address += readString(address, &temp);
|
||||
@@ -785,9 +798,7 @@ bool AmsConfiguration::loadConfig91(int address) {
|
||||
int domoCL1IDX;
|
||||
address += readInt(address, &domoCL1IDX);
|
||||
setDomoCL1IDX(domoCL1IDX);
|
||||
// address += readString(address, &temp);
|
||||
// domoEnergy = String(temp).toDouble();
|
||||
// setDomoEnergy(domoEnergy);
|
||||
|
||||
} else {
|
||||
clearDomo();
|
||||
}
|
||||
@@ -797,6 +808,101 @@ bool AmsConfiguration::loadConfig91(int address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::loadConfig82(int address) {
|
||||
char* temp;
|
||||
|
||||
address += readString(address, &temp);
|
||||
setWifiSsid(temp);
|
||||
address += readString(address, &temp);
|
||||
setWifiPassword(temp);
|
||||
|
||||
bool staticIp = false;
|
||||
address += readBool(address, &staticIp);
|
||||
if(staticIp) {
|
||||
address += readString(address, &temp);
|
||||
setWifiIp(temp);
|
||||
address += readString(address, &temp);
|
||||
setWifiGw(temp);
|
||||
address += readString(address, &temp);
|
||||
setWifiSubnet(temp);
|
||||
address += readString(address, &temp);
|
||||
setWifiDns1(temp);
|
||||
address += readString(address, &temp);
|
||||
setWifiDns2(temp);
|
||||
}
|
||||
address += readString(address, &temp);
|
||||
setWifiHostname(temp);
|
||||
bool mqtt = false;
|
||||
address += readBool(address, &mqtt);
|
||||
if(mqtt) {
|
||||
address += readString(address, &temp);
|
||||
setMqttHost(temp);
|
||||
int port;
|
||||
address += readInt(address, &port);
|
||||
setMqttPort(port);
|
||||
address += readString(address, &temp);
|
||||
setMqttClientId(temp);
|
||||
address += readString(address, &temp);
|
||||
setMqttPublishTopic(temp);
|
||||
address += readString(address, &temp);
|
||||
setMqttSubscribeTopic(temp);
|
||||
|
||||
bool secure = false;
|
||||
address += readBool(address, &secure);
|
||||
if (secure)
|
||||
{
|
||||
address += readString(address, &temp);
|
||||
setMqttUser(temp);
|
||||
address += readString(address, &temp);
|
||||
setMqttPassword(temp);
|
||||
} else {
|
||||
setMqttUser("");
|
||||
setMqttPassword("");
|
||||
}
|
||||
int payloadFormat;
|
||||
address += readInt(address, &payloadFormat);
|
||||
setMqttPayloadFormat(payloadFormat);
|
||||
bool ssl = false;
|
||||
address += readBool(address, &ssl);
|
||||
setMqttSsl(ssl);
|
||||
} else {
|
||||
clearMqtt();
|
||||
}
|
||||
|
||||
address += readByte(address, &authSecurity);
|
||||
if (authSecurity > 0) {
|
||||
address += readString(address, &temp);
|
||||
setAuthUser(temp);
|
||||
address += readString(address, &temp);
|
||||
setAuthPassword(temp);
|
||||
} else {
|
||||
clearAuth();
|
||||
}
|
||||
|
||||
int i;
|
||||
address += readInt(address, &i);
|
||||
setMeterType(i);
|
||||
address += readInt(address, &i);
|
||||
setDistributionSystem(i);
|
||||
address += readInt(address, &i);
|
||||
setMainFuse(i);
|
||||
address += readInt(address, &i);
|
||||
setProductionCapacity(i);
|
||||
|
||||
bool debugTelnet = false;
|
||||
address += readBool(address, &debugTelnet);
|
||||
setDebugTelnet(debugTelnet);
|
||||
bool debugSerial = false;
|
||||
address += readBool(address, &debugSerial);
|
||||
setDebugSerial(debugSerial);
|
||||
address += readInt(address, &i);
|
||||
setDebugLevel(i);
|
||||
|
||||
ackWifiChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AmsConfiguration::save() {
|
||||
int address = EEPROM_CONFIG_ADDRESS;
|
||||
|
||||
@@ -832,6 +938,7 @@ bool AmsConfiguration::save() {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
address += saveInt(address, mqttPayloadFormat);
|
||||
address += saveBool(address, mqttSsl);
|
||||
} else {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
@@ -860,7 +967,6 @@ bool AmsConfiguration::save() {
|
||||
address += saveInt(address, domoVL2IDX);
|
||||
address += saveInt(address, domoVL3IDX);
|
||||
address += saveInt(address, domoCL1IDX);
|
||||
//address += saveString(address, String(domoEnergy).c_str());
|
||||
} else {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
|
||||
@@ -48,8 +48,11 @@ public:
|
||||
void setMqttPassword(String mqttPassword);
|
||||
int getMqttPayloadFormat();
|
||||
void setMqttPayloadFormat(int mqttPayloadFormat);
|
||||
bool isMqttSsl();
|
||||
void setMqttSsl(bool mqttSsl);
|
||||
void clearMqtt();
|
||||
|
||||
void setMqttChanged();
|
||||
bool isMqttChanged();
|
||||
void ackMqttChange();
|
||||
|
||||
@@ -121,6 +124,7 @@ private:
|
||||
String mqttUser;
|
||||
String mqttPassword;
|
||||
int mqttPayloadFormat = 0;
|
||||
bool mqttSsl;
|
||||
bool mqttChanged = false;
|
||||
|
||||
byte authSecurity;
|
||||
@@ -144,15 +148,14 @@ private:
|
||||
bool domoChanged;
|
||||
|
||||
const int EEPROM_SIZE = 512;
|
||||
const int EEPROM_CHECK_SUM = 91; // Used to check if config is stored. Change if structure changes
|
||||
const int EEPROM_CHECK_SUM = 82; // Used to check if config is stored. Change if structure changes
|
||||
const int EEPROM_CONFIG_ADDRESS = 0;
|
||||
|
||||
bool loadConfig72(int address);
|
||||
bool loadConfig75(int address);
|
||||
bool loadConfig80(int address);
|
||||
bool loadConfig81(int address);
|
||||
bool loadConfig91(int address); // domoticz
|
||||
|
||||
bool loadConfig82(int address);
|
||||
|
||||
int saveString(int pAddress, const char* pString);
|
||||
int readString(int pAddress, char* pString[]);
|
||||
|
||||
10
src/AmsStorage.h
Normal file
10
src/AmsStorage.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef _AMSSTORAGE_H
|
||||
#define _AMSSTORAGE_H
|
||||
|
||||
#define FILE_FIRMWARE "/firmware.bin"
|
||||
|
||||
#define FILE_MQTT_CA "/mqtt-ca.pem"
|
||||
#define FILE_MQTT_CERT "/mqtt-cert.pem"
|
||||
#define FILE_MQTT_KEY "/mqtt-key.pem"
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <ESP8266mDNS.h>
|
||||
#elif defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include "SPIFFS.h"
|
||||
#include "Update.h"
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
*/
|
||||
|
||||
#include "AmsToMqttBridge.h"
|
||||
#include "AmsStorage.h"
|
||||
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e9
|
||||
#include <ArduinoJson.h>
|
||||
#include <MQTT.h>
|
||||
#include <DNSServer.h>
|
||||
#include <NTPClient.h>
|
||||
|
||||
#if defined(ESP8266)
|
||||
ADC_MODE(ADC_VCC);
|
||||
@@ -46,13 +48,15 @@ HwTools hw;
|
||||
|
||||
DNSServer dnsServer;
|
||||
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 60000);
|
||||
|
||||
AmsConfiguration config;
|
||||
|
||||
RemoteDebug Debug;
|
||||
|
||||
AmsWebServer ws(&Debug);
|
||||
|
||||
WiFiClient *client;
|
||||
MQTTClient mqtt(512);
|
||||
|
||||
HanReader hanReader;
|
||||
@@ -122,7 +126,7 @@ void setup() {
|
||||
|
||||
if(spiffs) {
|
||||
bool flashed = false;
|
||||
if(SPIFFS.exists("/firmware.bin")) {
|
||||
if(SPIFFS.exists(FILE_FIRMWARE)) {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) debugI("Found firmware");
|
||||
#if defined(ESP8266)
|
||||
WiFi.setSleepMode(WIFI_LIGHT_SLEEP);
|
||||
@@ -141,7 +145,7 @@ void setup() {
|
||||
}
|
||||
|
||||
if(Debug.isActive(RemoteDebug::INFO)) debugI(" flashing");
|
||||
File firmwareFile = SPIFFS.open("/firmware.bin", "r");
|
||||
File firmwareFile = SPIFFS.open(FILE_FIRMWARE, "r");
|
||||
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
|
||||
if (!Update.begin(maxSketchSpace, U_FLASH)) {
|
||||
if(Debug.isActive(RemoteDebug::ERROR)) {
|
||||
@@ -157,7 +161,7 @@ void setup() {
|
||||
flashed = Update.end(true);
|
||||
}
|
||||
firmwareFile.close();
|
||||
SPIFFS.remove("/firmware.bin");
|
||||
SPIFFS.remove(FILE_FIRMWARE);
|
||||
}
|
||||
SPIFFS.end();
|
||||
if(flashed) {
|
||||
@@ -188,7 +192,6 @@ void setup() {
|
||||
if(config.hasConfig()) {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) config.print(&Debug);
|
||||
WiFi_connect();
|
||||
client = new WiFiClient();
|
||||
} else {
|
||||
if(Debug.isActive(RemoteDebug::INFO)) {
|
||||
debugI("No configuration, booting AP");
|
||||
@@ -229,6 +232,7 @@ void setup() {
|
||||
}
|
||||
|
||||
ws.setup(&config, &mqtt);
|
||||
timeClient.begin();
|
||||
|
||||
#if HAS_RGB_LED
|
||||
//Signal startup by blinking red / green / yellow
|
||||
@@ -295,6 +299,8 @@ void loop() {
|
||||
errorBlink();
|
||||
}
|
||||
|
||||
timeClient.update();
|
||||
|
||||
// Only do normal stuff if we're not booted as AP
|
||||
if (WiFi.getMode() != WIFI_AP) {
|
||||
led_off();
|
||||
@@ -468,7 +474,7 @@ void readHanPort() {
|
||||
//
|
||||
// Start DOMOTICZ
|
||||
//
|
||||
} else if(config.getMqttPayloadFormat() == 2) {
|
||||
} else if(config.getMqttPayloadFormat() == 3) {
|
||||
StaticJsonDocument<512> json;
|
||||
hanToJson(json, data, hw, temperature);
|
||||
if (Debug.isActive(RemoteDebug::INFO)) {
|
||||
@@ -613,7 +619,7 @@ void readHanPort() {
|
||||
//
|
||||
// End DOMOTICZ
|
||||
//
|
||||
} else if(config.getMqttPayloadFormat() == 1) {
|
||||
} else if(config.getMqttPayloadFormat() == 1 || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/dlms/timestamp", String(data.getPackageTimestamp()));
|
||||
switch(data.getListType()) {
|
||||
case 3:
|
||||
@@ -627,41 +633,41 @@ void readHanPort() {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/export/active/accumulated", String(data.getActiveExportCounter(), 2));
|
||||
case 2:
|
||||
// Only send data if changed. ID and Type is sent on the 10s interval only if changed
|
||||
if(lastMqttData.getMeterId() != data.getMeterId()) {
|
||||
if(lastMqttData.getMeterId() != data.getMeterId() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/id", data.getMeterId());
|
||||
}
|
||||
if(lastMqttData.getMeterType() != data.getMeterType()) {
|
||||
if(lastMqttData.getMeterType() != data.getMeterType() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/type", data.getMeterType());
|
||||
}
|
||||
if(lastMqttData.getL1Current() != data.getL1Current()) {
|
||||
if(lastMqttData.getL1Current() != data.getL1Current() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/l1/current", String(data.getL1Current(), 2));
|
||||
}
|
||||
if(lastMqttData.getL1Voltage() != data.getL1Voltage()) {
|
||||
if(lastMqttData.getL1Voltage() != data.getL1Voltage() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/l1/voltage", String(data.getL1Voltage(), 2));
|
||||
}
|
||||
if(lastMqttData.getL2Current() != data.getL2Current()) {
|
||||
if(lastMqttData.getL2Current() != data.getL2Current() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/l2/current", String(data.getL2Current(), 2));
|
||||
}
|
||||
if(lastMqttData.getL2Voltage() != data.getL2Voltage()) {
|
||||
if(lastMqttData.getL2Voltage() != data.getL2Voltage() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/l2/voltage", String(data.getL2Voltage(), 2));
|
||||
}
|
||||
if(lastMqttData.getL3Current() != data.getL3Current()) {
|
||||
if(lastMqttData.getL3Current() != data.getL3Current() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/l3/current", String(data.getL3Current(), 2));
|
||||
}
|
||||
if(lastMqttData.getL3Voltage() != data.getL3Voltage()) {
|
||||
if(lastMqttData.getL3Voltage() != data.getL3Voltage() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/l3/voltage", String(data.getL3Voltage(), 2));
|
||||
}
|
||||
if(lastMqttData.getReactiveExportPower() != data.getReactiveExportPower()) {
|
||||
if(lastMqttData.getReactiveExportPower() != data.getReactiveExportPower() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/export/reactive", String(data.getReactiveExportPower()));
|
||||
}
|
||||
if(lastMqttData.getActiveExportPower() != data.getActiveExportPower()) {
|
||||
if(lastMqttData.getActiveExportPower() != data.getActiveExportPower() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/export/active", String(data.getActiveExportPower()));
|
||||
}
|
||||
if(lastMqttData.getReactiveImportPower() != data.getReactiveImportPower()) {
|
||||
if(lastMqttData.getReactiveImportPower() != data.getReactiveImportPower() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/import/reactive", String(data.getReactiveImportPower()));
|
||||
}
|
||||
case 1:
|
||||
if(lastMqttData.getActiveImportPower() != data.getActiveImportPower()) {
|
||||
if(lastMqttData.getActiveImportPower() != data.getActiveImportPower() || config.getMqttPayloadFormat() == 2) {
|
||||
mqtt.publish(config.getMqttPublishTopic() + "/meter/import/active", String(data.getActiveImportPower()));
|
||||
}
|
||||
}
|
||||
@@ -774,7 +780,7 @@ void MQTT_connect() {
|
||||
if(Debug.isActive(RemoteDebug::WARNING)) debugW("No MQTT config");
|
||||
return;
|
||||
}
|
||||
if(millis() - lastMqttRetry < 5000) {
|
||||
if(millis() - lastMqttRetry < (mqtt.lastError() == 0 ? 5000 : 60000)) {
|
||||
yield();
|
||||
return;
|
||||
}
|
||||
@@ -786,8 +792,51 @@ void MQTT_connect() {
|
||||
mqtt.disconnect();
|
||||
yield();
|
||||
|
||||
WiFiClientSecure *secureClient;
|
||||
Client *client;
|
||||
if(config.isMqttSsl()) {
|
||||
debugI("MQTT SSL is configured");
|
||||
|
||||
if(!timeClient.update()) debugW("NTP time is not ready");
|
||||
|
||||
secureClient = new WiFiClientSecure();
|
||||
#if defined(ESP8266)
|
||||
secureClient->setBufferSizes(512, 512);
|
||||
#endif
|
||||
|
||||
if(SPIFFS.begin()) {
|
||||
char *ca = NULL;
|
||||
char *cert = NULL;
|
||||
char *key = NULL;
|
||||
|
||||
if(SPIFFS.exists(FILE_MQTT_CA)) {
|
||||
debugI("Found MQTT CA file");
|
||||
File file = SPIFFS.open(FILE_MQTT_CA, "r");
|
||||
secureClient->loadCACert(file, file.size());
|
||||
}
|
||||
if(SPIFFS.exists(FILE_MQTT_CERT)) {
|
||||
debugI("Found MQTT certificate file");
|
||||
File file = SPIFFS.open(FILE_MQTT_CERT, "r");
|
||||
secureClient->loadCertificate(file, file.size());
|
||||
}
|
||||
if(SPIFFS.exists(FILE_MQTT_KEY)) {
|
||||
debugI("Found MQTT key file");
|
||||
File file = SPIFFS.open(FILE_MQTT_KEY, "r");
|
||||
secureClient->loadPrivateKey(file, file.size());
|
||||
}
|
||||
SPIFFS.end();
|
||||
}
|
||||
client = secureClient;
|
||||
} else {
|
||||
client = new WiFiClient();
|
||||
}
|
||||
|
||||
mqtt.begin(config.getMqttHost().c_str(), config.getMqttPort(), *client);
|
||||
|
||||
#if defined(ESP8266)
|
||||
if(secureClient) secureClient->setX509Time(timeClient.getEpochTime());
|
||||
#endif
|
||||
|
||||
// Connect to a unsecure or secure MQTT server
|
||||
if ((config.getMqttUser().isEmpty() && mqtt.connect(config.getMqttClientId().c_str())) ||
|
||||
(!config.getMqttUser().isEmpty() && mqtt.connect(config.getMqttClientId().c_str(), config.getMqttUser().c_str(), config.getMqttPassword().c_str()))) {
|
||||
@@ -807,7 +856,14 @@ void MQTT_connect() {
|
||||
}
|
||||
} else {
|
||||
if (Debug.isActive(RemoteDebug::ERROR)) {
|
||||
debugI("Failed to connect to MQTT");
|
||||
debugE("Failed to connect to MQTT");
|
||||
#if defined(ESP8266)
|
||||
if(secureClient) {
|
||||
char buf[256];
|
||||
secureClient->getLastSSLError(buf,256);
|
||||
Debug.println(buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
yield();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "AmsWebServer.h"
|
||||
#include "version.h"
|
||||
#include "AmsStorage.h"
|
||||
|
||||
#include "root/index_html.h"
|
||||
#include "root/index_js.h"
|
||||
#include "root/configmeter_html.h"
|
||||
#include "root/configwifi_html.h"
|
||||
#include "root/configmqtt_html.h"
|
||||
@@ -11,6 +13,8 @@
|
||||
#include "root/restartwait_html.h"
|
||||
#include "root/boot_css.h"
|
||||
#include "root/gaugemeter_js.h"
|
||||
#include "root/upload_html.h"
|
||||
#include "root/delete_html.h"
|
||||
|
||||
#include "Base64.h"
|
||||
|
||||
@@ -22,7 +26,8 @@ void AmsWebServer::setup(AmsConfiguration* config, MQTTClient* mqtt) {
|
||||
this->config = config;
|
||||
this->mqtt = mqtt;
|
||||
|
||||
server.on("/", std::bind(&AmsWebServer::indexHtml, this));
|
||||
server.on("/", HTTP_GET, std::bind(&AmsWebServer::indexHtml, this));
|
||||
server.on("/index.js", HTTP_GET, std::bind(&AmsWebServer::indexJs, this));
|
||||
server.on("/config-meter", HTTP_GET, std::bind(&AmsWebServer::configMeterHtml, this));
|
||||
server.on("/config-wifi", HTTP_GET, std::bind(&AmsWebServer::configWifiHtml, this));
|
||||
server.on("/config-mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this));
|
||||
@@ -32,13 +37,23 @@ void AmsWebServer::setup(AmsConfiguration* config, MQTTClient* mqtt) {
|
||||
server.on("/gaugemeter.js", HTTP_GET, std::bind(&AmsWebServer::gaugemeterJs, this));
|
||||
server.on("/data.json", HTTP_GET, std::bind(&AmsWebServer::dataJson, this));
|
||||
|
||||
server.on("/save", std::bind(&AmsWebServer::handleSave, this));
|
||||
server.on("/save", HTTP_POST, std::bind(&AmsWebServer::handleSave, this));
|
||||
|
||||
server.on("/config-system", HTTP_GET, std::bind(&AmsWebServer::configSystemHtml, this));
|
||||
server.on("/config-system", HTTP_POST, std::bind(&AmsWebServer::configSystemPost, this), std::bind(&AmsWebServer::configSystemUpload, this));
|
||||
server.on("/config-system", HTTP_POST, std::bind(&AmsWebServer::uploadPost, this), std::bind(&AmsWebServer::configSystemUpload, this));
|
||||
server.on("/restart-wait", HTTP_GET, std::bind(&AmsWebServer::restartWaitHtml, this));
|
||||
server.on("/is-alive", HTTP_GET, std::bind(&AmsWebServer::isAliveCheck, this));
|
||||
|
||||
server.on("/mqtt-ca", HTTP_GET, std::bind(&AmsWebServer::mqttCa, this));
|
||||
server.on("/mqtt-ca", HTTP_POST, std::bind(&AmsWebServer::uploadPost, this), std::bind(&AmsWebServer::mqttCaUpload, this));
|
||||
server.on("/mqtt-ca/delete", HTTP_POST, std::bind(&AmsWebServer::mqttCaDelete, this));
|
||||
server.on("/mqtt-cert", HTTP_GET, std::bind(&AmsWebServer::mqttCert, this));
|
||||
server.on("/mqtt-cert", HTTP_POST, std::bind(&AmsWebServer::uploadPost, this), std::bind(&AmsWebServer::mqttCertUpload, this));
|
||||
server.on("/mqtt-cert/delete", HTTP_POST, std::bind(&AmsWebServer::mqttCertDelete, this));
|
||||
server.on("/mqtt-key", HTTP_GET, std::bind(&AmsWebServer::mqttKey, this));
|
||||
server.on("/mqtt-key", HTTP_POST, std::bind(&AmsWebServer::uploadPost, this), std::bind(&AmsWebServer::mqttKeyUpload, this));
|
||||
server.on("/mqtt-key/delete", HTTP_POST, std::bind(&AmsWebServer::mqttKeyDelete, this));
|
||||
|
||||
server.begin(); // Web server start
|
||||
}
|
||||
|
||||
@@ -87,6 +102,10 @@ bool AmsWebServer::checkSecurity(byte level) {
|
||||
server.setContentLength(0);
|
||||
server.send(401, "text/html", "");
|
||||
}
|
||||
if(access)
|
||||
printD(" access granted");
|
||||
else
|
||||
printD(" access denied");
|
||||
return access;
|
||||
}
|
||||
|
||||
@@ -157,6 +176,13 @@ void AmsWebServer::indexHtml() {
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::indexJs() {
|
||||
printD("Serving /index.js over http...");
|
||||
|
||||
server.sendHeader("Cache-Control", "public, max-age=3600");
|
||||
server.send_P(200, "application/javascript", INDEX_JS);
|
||||
}
|
||||
|
||||
void AmsWebServer::configMeterHtml() {
|
||||
printD("Serving /config-meter.html over http...");
|
||||
|
||||
@@ -254,6 +280,26 @@ void AmsWebServer::configMqttHtml() {
|
||||
html.replace("${config.mqttPayloadFormat" + String(i) + "}", config->getMqttPayloadFormat() == i ? "selected" : "");
|
||||
}
|
||||
|
||||
html.replace("${config.mqttSsl}", config->isMqttSsl() ? "checked" : "");
|
||||
html.replace("${display.ssl}", config->isMqttSsl() ? "" : "none");
|
||||
|
||||
if(SPIFFS.begin()) {
|
||||
html.replace("${display.ca.upload}", SPIFFS.exists(FILE_MQTT_CA) ? "none" : "");
|
||||
html.replace("${display.ca.file}", SPIFFS.exists(FILE_MQTT_CA) ? "" : "none");
|
||||
html.replace("${display.cert.upload}", SPIFFS.exists(FILE_MQTT_CERT) ? "none" : "");
|
||||
html.replace("${display.cert.file}", SPIFFS.exists(FILE_MQTT_CERT) ? "" : "none");
|
||||
html.replace("${display.key.upload}", SPIFFS.exists(FILE_MQTT_KEY) ? "none" : "");
|
||||
html.replace("${display.key.file}", SPIFFS.exists(FILE_MQTT_KEY) ? "" : "none");
|
||||
SPIFFS.end();
|
||||
} else {
|
||||
html.replace("${display.ca.upload}", "");
|
||||
html.replace("${display.ca.file}", "none");
|
||||
html.replace("${display.cert.upload}", "");
|
||||
html.replace("${display.cert.file}", "none");
|
||||
html.replace("${display.key.upload}", "");
|
||||
html.replace("${display.key.file}", "none");
|
||||
}
|
||||
|
||||
server.setContentLength(html.length());
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
@@ -322,23 +368,15 @@ void AmsWebServer::configWebHtml() {
|
||||
void AmsWebServer::bootCss() {
|
||||
printD("Serving /boot.css over http...");
|
||||
|
||||
String css = String((const __FlashStringHelper*) BOOT_CSS);
|
||||
|
||||
server.sendHeader("Cache-Control", "public, max-age=3600");
|
||||
|
||||
server.setContentLength(css.length());
|
||||
server.send(200, "text/css", css);
|
||||
server.send_P(200, "text/css", BOOT_CSS);
|
||||
}
|
||||
|
||||
void AmsWebServer::gaugemeterJs() {
|
||||
printD("Serving /gaugemeter.js over http...");
|
||||
|
||||
String js = String((const __FlashStringHelper*) GAUGEMETER_JS);
|
||||
|
||||
server.sendHeader("Cache-Control", "public, max-age=3600");
|
||||
|
||||
server.setContentLength(js.length());
|
||||
server.send(200, "application/javascript", js);
|
||||
server.send_P(200, "application/javascript", GAUGEMETER_JS);
|
||||
}
|
||||
|
||||
void AmsWebServer::dataJson() {
|
||||
@@ -537,6 +575,7 @@ void AmsWebServer::handleSave() {
|
||||
config->setMqttUser(server.arg("mqttUser"));
|
||||
config->setMqttPassword(server.arg("mqttPassword"));
|
||||
config->setMqttPayloadFormat(server.arg("mqttPayloadFormat").toInt());
|
||||
config->setMqttSsl(server.arg("mqttSsl") == "true");
|
||||
} else {
|
||||
config->clearMqtt();
|
||||
}
|
||||
@@ -634,42 +673,60 @@ void AmsWebServer::configSystemHtml() {
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::configSystemPost() {
|
||||
void AmsWebServer::uploadPost() {
|
||||
server.send(200);
|
||||
}
|
||||
|
||||
void AmsWebServer::configSystemUpload() {
|
||||
void AmsWebServer::uploadFile(const char* path) {
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_START){
|
||||
String filename = upload.filename;
|
||||
if(!filename.endsWith(".bin")) {
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
} else if (!SPIFFS.begin()) {
|
||||
if (!SPIFFS.begin()) {
|
||||
printE("An Error has occurred while mounting SPIFFS");
|
||||
String html = "<html><body><h1>Error uploading!</h1></form>";
|
||||
server.send(500, "text/html", html);
|
||||
} else {
|
||||
printD("handleFileUpload Name: %s", filename.c_str());
|
||||
firmwareFile = SPIFFS.open("/firmware.bin", "w");
|
||||
file = SPIFFS.open(path, "w");
|
||||
filename = String();
|
||||
}
|
||||
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
||||
if(firmwareFile)
|
||||
firmwareFile.write(upload.buf, upload.currentSize);
|
||||
if(file)
|
||||
file.write(upload.buf, upload.currentSize);
|
||||
} else if(upload.status == UPLOAD_FILE_END) {
|
||||
if(firmwareFile) {
|
||||
firmwareFile.close();
|
||||
if(file) {
|
||||
file.close();
|
||||
SPIFFS.end();
|
||||
printD("handleFileUpload Size: %d", upload.totalSize);
|
||||
performRestart = true;
|
||||
server.sendHeader("Location","/restart-wait");
|
||||
server.send(303);
|
||||
} else {
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::deleteFile(const char* path) {
|
||||
if(SPIFFS.begin()) {
|
||||
SPIFFS.remove(path);
|
||||
SPIFFS.end();
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::configSystemUpload() {
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_START) {
|
||||
String filename = upload.filename;
|
||||
if(!filename.endsWith(".bin")) {
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
}
|
||||
uploadFile(FILE_FIRMWARE);
|
||||
if(upload.status == UPLOAD_FILE_END) {
|
||||
performRestart = true;
|
||||
server.sendHeader("Location","/restart-wait");
|
||||
server.send(303);
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::restartWaitHtml() {
|
||||
printD("Serving /restart-wait.html over http...");
|
||||
|
||||
@@ -714,6 +771,169 @@ void AmsWebServer::isAliveCheck() {
|
||||
server.send(200);
|
||||
}
|
||||
|
||||
void AmsWebServer::uploadHtml(const char* label, const char* action, const char* menu) {
|
||||
String html = String((const __FlashStringHelper*) UPLOAD_HTML);
|
||||
html.replace("${form.action}", action);
|
||||
html.replace("${version}", VERSION);
|
||||
|
||||
if(WiFi.getMode() != WIFI_AP) {
|
||||
html.replace("boot.css", BOOTSTRAP_URL);
|
||||
}
|
||||
|
||||
html.replace("${menu." + String(menu) + ".class}", "active");
|
||||
html.replace("${menu.meter.class}", "");
|
||||
html.replace("${menu.wifi.class}", "");
|
||||
html.replace("${menu.mqtt.class}", "");
|
||||
html.replace("${menu.web.class}", "");
|
||||
html.replace("${menu.system.class}", "");
|
||||
html.replace("${file.label}", label);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
|
||||
server.setContentLength(html.length());
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::deleteHtml(const char* label, const char* action, const char* menu) {
|
||||
String html = String((const __FlashStringHelper*) DELETE_HTML);
|
||||
html.replace("${form.action}", action);
|
||||
html.replace("${version}", VERSION);
|
||||
|
||||
if(WiFi.getMode() != WIFI_AP) {
|
||||
html.replace("boot.css", BOOTSTRAP_URL);
|
||||
}
|
||||
|
||||
html.replace("${menu." + String(menu) + ".class}", "active");
|
||||
html.replace("${menu.meter.class}", "");
|
||||
html.replace("${menu.wifi.class}", "");
|
||||
html.replace("${menu.mqtt.class}", "");
|
||||
html.replace("${menu.web.class}", "");
|
||||
html.replace("${menu.system.class}", "");
|
||||
html.replace("${file.label}", label);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
|
||||
server.setContentLength(html.length());
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCa() {
|
||||
printD("Serving /mqtt-ca.html over http...");
|
||||
|
||||
String html;
|
||||
if(SPIFFS.begin()) {
|
||||
if(SPIFFS.exists(FILE_MQTT_CA)) {
|
||||
deleteHtml("CA file", "/mqtt-ca/delete", "mqtt");
|
||||
} else {
|
||||
uploadHtml("CA file", "/mqtt-ca", "mqtt");
|
||||
}
|
||||
SPIFFS.end();
|
||||
} else {
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCaUpload() {
|
||||
uploadFile(FILE_MQTT_CA);
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_END) {
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
if(config->isMqttSsl()) {
|
||||
config->setMqttChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCaDelete() {
|
||||
deleteFile(FILE_MQTT_CA);
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
if(config->isMqttSsl()) {
|
||||
config->setMqttChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCert() {
|
||||
printD("Serving /mqtt-cert.html over http...");
|
||||
|
||||
String html;
|
||||
if(SPIFFS.begin()) {
|
||||
if(SPIFFS.exists(FILE_MQTT_CERT)) {
|
||||
deleteHtml("Certificate", "/mqtt-cert/delete", "mqtt");
|
||||
} else {
|
||||
uploadHtml("Certificate", "/mqtt-cert", "mqtt");
|
||||
}
|
||||
SPIFFS.end();
|
||||
} else {
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCertUpload() {
|
||||
uploadFile(FILE_MQTT_CERT);
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_END) {
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
if(config->isMqttSsl()) {
|
||||
config->setMqttChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCertDelete() {
|
||||
deleteFile(FILE_MQTT_CERT);
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
if(config->isMqttSsl()) {
|
||||
config->setMqttChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttKey() {
|
||||
printD("Serving /mqtt-key.html over http...");
|
||||
|
||||
String html;
|
||||
if(SPIFFS.begin()) {
|
||||
if(SPIFFS.exists(FILE_MQTT_KEY)) {
|
||||
deleteHtml("Private key", "/mqtt-key/delete", "mqtt");
|
||||
} else {
|
||||
uploadHtml("Private key", "/mqtt-key", "mqtt");
|
||||
}
|
||||
SPIFFS.end();
|
||||
} else {
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttKeyUpload() {
|
||||
uploadFile(FILE_MQTT_KEY);
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_END) {
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
if(config->isMqttSsl()) {
|
||||
config->setMqttChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttKeyDelete() {
|
||||
deleteFile(FILE_MQTT_KEY);
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
if(config->isMqttSsl()) {
|
||||
config->setMqttChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AmsWebServer::printD(String fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
AmsConfiguration* config;
|
||||
AmsData data;
|
||||
MQTTClient* mqtt;
|
||||
File firmwareFile;
|
||||
File file;
|
||||
bool performRestart = false;
|
||||
|
||||
#if defined(ESP8266)
|
||||
@@ -56,6 +56,7 @@ private:
|
||||
bool checkSecurity(byte level);
|
||||
|
||||
void indexHtml();
|
||||
void indexJs();
|
||||
void configMeterHtml();
|
||||
void configWifiHtml();
|
||||
void configMqttHtml();
|
||||
@@ -68,11 +69,25 @@ private:
|
||||
void handleSave();
|
||||
|
||||
void configSystemHtml();
|
||||
void configSystemPost();
|
||||
void configSystemUpload();
|
||||
void restartWaitHtml();
|
||||
void isAliveCheck();
|
||||
|
||||
void uploadHtml(const char* label, const char* action, const char* menu);
|
||||
void deleteHtml(const char* label, const char* action, const char* menu);
|
||||
void uploadFile(const char* path);
|
||||
void deleteFile(const char* path);
|
||||
void uploadPost();
|
||||
void mqttCa();
|
||||
void mqttCaUpload();
|
||||
void mqttCaDelete();
|
||||
void mqttCert();
|
||||
void mqttCertUpload();
|
||||
void mqttCertDelete();
|
||||
void mqttKey();
|
||||
void mqttKeyUpload();
|
||||
void mqttKeyDelete();
|
||||
|
||||
void printD(String fmt, ...);
|
||||
void printI(String fmt, ...);
|
||||
void printW(String fmt, ...);
|
||||
|
||||
Reference in New Issue
Block a user