mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-13 15:37:03 +00:00
Implemented upload of certificates for MQTT SSL
This commit is contained in:
parent
ab175ec9ec
commit
cc032fdf29
@ -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);
|
||||
@ -278,6 +287,7 @@ bool AmsConfiguration::hasConfig() {
|
||||
case 75:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
return true;
|
||||
default:
|
||||
configVersion = 0;
|
||||
@ -310,6 +320,9 @@ bool AmsConfiguration::load() {
|
||||
case 81:
|
||||
success = loadConfig81(address);
|
||||
break;
|
||||
case 82:
|
||||
success = loadConfig82(address);
|
||||
break;
|
||||
}
|
||||
EEPROM.end();
|
||||
return success;
|
||||
@ -608,6 +621,101 @@ bool AmsConfiguration::loadConfig81(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;
|
||||
|
||||
@ -643,6 +751,7 @@ bool AmsConfiguration::save() {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
address += saveInt(address, mqttPayloadFormat);
|
||||
address += saveBool(address, mqttSsl);
|
||||
} else {
|
||||
address += saveBool(address, false);
|
||||
}
|
||||
|
||||
@ -48,6 +48,8 @@ public:
|
||||
void setMqttPassword(String mqttPassword);
|
||||
int getMqttPayloadFormat();
|
||||
void setMqttPayloadFormat(int mqttPayloadFormat);
|
||||
bool isMqttSsl();
|
||||
void setMqttSsl(bool mqttSsl);
|
||||
void clearMqtt();
|
||||
|
||||
bool isMqttChanged();
|
||||
@ -102,6 +104,7 @@ private:
|
||||
String mqttUser;
|
||||
String mqttPassword;
|
||||
int mqttPayloadFormat = 0;
|
||||
bool mqttSsl;
|
||||
bool mqttChanged = false;
|
||||
|
||||
byte authSecurity;
|
||||
@ -114,13 +117,14 @@ private:
|
||||
int debugLevel = 3;
|
||||
|
||||
const int EEPROM_SIZE = 512;
|
||||
const int EEPROM_CHECK_SUM = 81; // 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 loadConfig82(int address);
|
||||
|
||||
int saveString(int pAddress, const char* pString);
|
||||
int readString(int pAddress, char* pString[]);
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -52,7 +52,6 @@ RemoteDebug Debug;
|
||||
|
||||
AmsWebServer ws(&Debug);
|
||||
|
||||
WiFiClient *client;
|
||||
MQTTClient mqtt(512);
|
||||
|
||||
HanReader hanReader;
|
||||
@ -188,7 +187,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");
|
||||
@ -635,6 +633,85 @@ void MQTT_connect() {
|
||||
mqtt.disconnect();
|
||||
yield();
|
||||
|
||||
Client *client;
|
||||
if(config.isMqttSsl()) {
|
||||
debugI("MQTT SSL is configured");
|
||||
WiFiClientSecure *secureClient = new WiFiClientSecure();
|
||||
|
||||
bool spiffs = false;
|
||||
#if defined(ESP32)
|
||||
debugD("ESP32 SPIFFS");
|
||||
spiffs = SPIFFS.begin(true);
|
||||
#else
|
||||
debugD("ESP8266 SPIFFS");
|
||||
spiffs = SPIFFS.begin();
|
||||
#endif
|
||||
|
||||
bool caExists = false;
|
||||
if(spiffs) {
|
||||
char *ca = NULL;
|
||||
char *cert = NULL;
|
||||
char *key = NULL;
|
||||
if(SPIFFS.exists("/mqtt-ca.cer")) {
|
||||
debugI("Found MQTT CA file");
|
||||
File file = SPIFFS.open("/mqtt-ca.cer", "r");
|
||||
ca = new char[file.size()];
|
||||
if (file.size() != file.readBytes(ca, file.size())) {
|
||||
delete ca;
|
||||
ca = NULL;
|
||||
}
|
||||
}
|
||||
if(SPIFFS.exists("/mqtt-cert.cer")) {
|
||||
debugI("Found MQTT certificate file");
|
||||
File file = SPIFFS.open("/mqtt-cert.cer", "r");
|
||||
cert = new char[file.size()];
|
||||
if (file.size() != file.readBytes(cert, file.size())) {
|
||||
delete cert;
|
||||
cert = NULL;
|
||||
}
|
||||
}
|
||||
if(SPIFFS.exists("/mqtt-key.cer")) {
|
||||
debugI("Found MQTT key file");
|
||||
File file = SPIFFS.open("/mqtt-key.cer", "r");
|
||||
key = new char[file.size()];
|
||||
if (file.size() != file.readBytes(key, file.size())) {
|
||||
delete key;
|
||||
key = NULL;
|
||||
}
|
||||
}
|
||||
SPIFFS.end();
|
||||
|
||||
if(ca) {
|
||||
#ifdef ESP32
|
||||
secureClient->setCACert(ca);
|
||||
#else
|
||||
secureClient->setTrustAnchors(new X509List(ca));
|
||||
secureClient->allowSelfSignedCerts();
|
||||
#endif
|
||||
caExists = true;
|
||||
}
|
||||
if(cert && key) {
|
||||
#ifdef ESP32
|
||||
secureClient->setCertificate(cert);
|
||||
secureClient->setPrivateKey(key);
|
||||
#else
|
||||
secureClient->setClientRSACert(new X509List(cert), new PrivateKey(key));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(!caExists) {
|
||||
debugW("No CA found, using insecure");
|
||||
#ifdef ESP32
|
||||
// TODO
|
||||
#else
|
||||
secureClient->setInsecure();
|
||||
#endif
|
||||
}
|
||||
client = secureClient;
|
||||
} else {
|
||||
client = new WiFiClient();
|
||||
}
|
||||
|
||||
mqtt.begin(config.getMqttHost().c_str(), config.getMqttPort(), *client);
|
||||
|
||||
// Connect to a unsecure or secure MQTT server
|
||||
@ -655,6 +732,7 @@ void MQTT_connect() {
|
||||
sendSystemStatusToMqtt();
|
||||
}
|
||||
} else {
|
||||
lastMqttRetry = millis() + 30000;
|
||||
if (Debug.isActive(RemoteDebug::ERROR)) {
|
||||
debugI("Failed to connect to MQTT");
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "root/restartwait_html.h"
|
||||
#include "root/boot_css.h"
|
||||
#include "root/gaugemeter_js.h"
|
||||
#include "root/upload_html.h"
|
||||
|
||||
#include "Base64.h"
|
||||
|
||||
@ -30,13 +31,20 @@ 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-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-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.begin(); // Web server start
|
||||
}
|
||||
|
||||
@ -252,6 +260,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("/mqtt-ca.pem") ? "none" : "");
|
||||
html.replace("${display.ca.file}", SPIFFS.exists("/mqtt-ca.pem") ? "" : "none");
|
||||
html.replace("${display.cert.upload}", SPIFFS.exists("/mqtt-cert.pem") ? "none" : "");
|
||||
html.replace("${display.cert.file}", SPIFFS.exists("/mqtt-cert.pem") ? "" : "none");
|
||||
html.replace("${display.key.upload}", SPIFFS.exists("/mqtt-key.pem") ? "none" : "");
|
||||
html.replace("${display.key.file}", SPIFFS.exists("/mqtt-key.pem") ? "" : "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);
|
||||
}
|
||||
@ -489,6 +517,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();
|
||||
}
|
||||
@ -571,7 +600,7 @@ void AmsWebServer::configSystemHtml() {
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::configSystemPost() {
|
||||
void AmsWebServer::uploadPost() {
|
||||
server.send(200);
|
||||
}
|
||||
|
||||
@ -651,6 +680,157 @@ void AmsWebServer::isAliveCheck() {
|
||||
server.send(200);
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCa() {
|
||||
printD("Serving /mqtt-ca.html over http...");
|
||||
|
||||
String html = String((const __FlashStringHelper*) UPLOAD_HTML);
|
||||
html.replace("${menu.meter.class}", "");
|
||||
html.replace("${menu.wifi.class}", "");
|
||||
html.replace("${menu.mqtt.class}", "active");
|
||||
html.replace("${menu.web.class}", "");
|
||||
html.replace("${menu.system.class}", "");
|
||||
html.replace("${file.label}", "CA file");
|
||||
|
||||
server.sendHeader("Cache-Control", "public, max-age=3600");
|
||||
|
||||
server.setContentLength(html.length());
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCaUpload() {
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_START){
|
||||
String filename = upload.filename;
|
||||
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());
|
||||
mqttCaFile = SPIFFS.open("/mqtt-ca.pem", "w");
|
||||
filename = String();
|
||||
}
|
||||
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
||||
if(mqttCaFile)
|
||||
mqttCaFile.write(upload.buf, upload.currentSize);
|
||||
} else if(upload.status == UPLOAD_FILE_END) {
|
||||
if(mqttCaFile) {
|
||||
mqttCaFile.close();
|
||||
SPIFFS.end();
|
||||
printD("handleFileUpload Size: %d", upload.totalSize);
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
} else {
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCaDelete() {
|
||||
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCert() {
|
||||
printD("Serving /mqtt-cert.html over http...");
|
||||
|
||||
String html = String((const __FlashStringHelper*) UPLOAD_HTML);
|
||||
html.replace("${menu.meter.class}", "");
|
||||
html.replace("${menu.wifi.class}", "");
|
||||
html.replace("${menu.mqtt.class}", "active");
|
||||
html.replace("${menu.web.class}", "");
|
||||
html.replace("${menu.system.class}", "");
|
||||
html.replace("${file.label}", "Certificate");
|
||||
|
||||
server.sendHeader("Cache-Control", "public, max-age=3600");
|
||||
|
||||
server.setContentLength(html.length());
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCertUpload() {
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_START){
|
||||
String filename = upload.filename;
|
||||
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());
|
||||
mqttCertFile = SPIFFS.open("/mqtt-cert.pem", "w");
|
||||
filename = String();
|
||||
}
|
||||
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
||||
if(mqttCertFile)
|
||||
mqttCertFile.write(upload.buf, upload.currentSize);
|
||||
} else if(upload.status == UPLOAD_FILE_END) {
|
||||
if(mqttCertFile) {
|
||||
mqttCertFile.close();
|
||||
SPIFFS.end();
|
||||
printD("handleFileUpload Size: %d", upload.totalSize);
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
} else {
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttCertDelete() {
|
||||
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttKey() {
|
||||
printD("Serving /mqtt-key.html over http...");
|
||||
|
||||
String html = String((const __FlashStringHelper*) UPLOAD_HTML);
|
||||
html.replace("${menu.meter.class}", "");
|
||||
html.replace("${menu.wifi.class}", "");
|
||||
html.replace("${menu.mqtt.class}", "active");
|
||||
html.replace("${menu.web.class}", "");
|
||||
html.replace("${menu.system.class}", "");
|
||||
html.replace("${file.label}", "Private key");
|
||||
|
||||
server.sendHeader("Cache-Control", "public, max-age=3600");
|
||||
|
||||
server.setContentLength(html.length());
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttKeyUpload() {
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_START){
|
||||
String filename = upload.filename;
|
||||
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());
|
||||
mqttKeyFile = SPIFFS.open("/mqtt-key.pem", "w");
|
||||
filename = String();
|
||||
}
|
||||
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
||||
if(mqttKeyFile)
|
||||
mqttKeyFile.write(upload.buf, upload.currentSize);
|
||||
} else if(upload.status == UPLOAD_FILE_END) {
|
||||
if(mqttKeyFile) {
|
||||
mqttKeyFile.close();
|
||||
SPIFFS.end();
|
||||
printD("handleFileUpload Size: %d", upload.totalSize);
|
||||
server.sendHeader("Location","/config-mqtt");
|
||||
server.send(303);
|
||||
} else {
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsWebServer::mqttKeyDelete() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void AmsWebServer::printD(String fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
@ -45,6 +45,9 @@ private:
|
||||
AmsData data;
|
||||
MQTTClient* mqtt;
|
||||
File firmwareFile;
|
||||
File mqttCaFile;
|
||||
File mqttCertFile;
|
||||
File mqttKeyFile;
|
||||
bool performRestart = false;
|
||||
|
||||
#if defined(ESP8266)
|
||||
@ -67,11 +70,21 @@ private:
|
||||
void handleSave();
|
||||
|
||||
void configSystemHtml();
|
||||
void configSystemPost();
|
||||
void configSystemUpload();
|
||||
void restartWaitHtml();
|
||||
void isAliveCheck();
|
||||
|
||||
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, ...);
|
||||
|
||||
@ -102,6 +102,49 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">SSL</label>
|
||||
<div class="col-8">
|
||||
<input id="mqttSsl" type="checkbox" name="mqttSsl" value="true" ${config.mqttSsl}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mqtt-ssl-config">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">CA</label>
|
||||
<div class="col-8">
|
||||
<span style="display: ${display.ca.upload};"><a href="/mqtt-ca">Upload</a></span>
|
||||
<span style="display: ${display.ca.file};">
|
||||
<a href="#">Delete</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mqtt-ssl-config">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">Certificate</label>
|
||||
<div class="col-8">
|
||||
<span style="display: ${display.cert.upload};"><a href="/mqtt-ca">Upload</a></span>
|
||||
<span style="display: ${display.cert.file};">
|
||||
<a href="#">Delete</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mqtt-ssl-config">
|
||||
<div class="row form-group">
|
||||
<label class="col-6">Private key</label>
|
||||
<div class="col-6">
|
||||
<span style="display: ${display.key.upload};"><a href="/mqtt-ca">Upload</a></span>
|
||||
<span style="display: ${display.key.file};">
|
||||
<a href="#">Delete</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
|
||||
66
web/upload.html
Normal file
66
web/upload.html
Normal file
@ -0,0 +1,66 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>AMS reader - Meter configuration</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" type="text/css" href="boot.css"/>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<main role="main" class="container">
|
||||
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bg-purple rounded mt-2 mb-4" style="background-color: var(--purple);">
|
||||
<a href="/" class=""><h6 class="navbar-brand">AMS reader <small>${version}</small></h6></a>
|
||||
<div class="navbar-nav-scroll">
|
||||
<ul class="navbar-nav bd-navbar-nav flex-row">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link ${menu.meter.class}" href="/config-meter">Meter</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link ${menu.wifi.class}" href="/config-wifi">WiFi</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link ${menu.mqtt.class}" href="/config-mqtt">MQTT</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link ${menu.web.class}" href="/config-web">Web</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link ${menu.system.class}" href="/config-system">System</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/gskjold/AmsToMqttBridge" target="_blank" rel="noopener" aria-label="GitHub">
|
||||
<svg class="d-inline-block align-text-top" style="width: 2rem; height: 2rem;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="row form-group">
|
||||
<label class="col-4">${file.label}</label>
|
||||
<div class="col-8">
|
||||
<input type="file" name="file"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="javascript:history.back();" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user