Merge branch 'pr801' into dev

This commit is contained in:
Thomas Basler 2023-04-12 19:35:58 +02:00
commit ebaccc9b3f
13 changed files with 103 additions and 28 deletions

View File

@ -19,7 +19,7 @@
#define MQTT_MAX_PASSWORD_STRLEN 64 #define MQTT_MAX_PASSWORD_STRLEN 64
#define MQTT_MAX_TOPIC_STRLEN 32 #define MQTT_MAX_TOPIC_STRLEN 32
#define MQTT_MAX_LWTVALUE_STRLEN 20 #define MQTT_MAX_LWTVALUE_STRLEN 20
#define MQTT_MAX_ROOT_CA_CERT_STRLEN 2560 #define MQTT_MAX_CERT_STRLEN 2560
#define INV_MAX_NAME_STRLEN 31 #define INV_MAX_NAME_STRLEN 31
#define INV_MAX_COUNT 10 #define INV_MAX_COUNT 10
@ -89,7 +89,10 @@ struct CONFIG_T {
char Mqtt_Hass_Topic[MQTT_MAX_TOPIC_STRLEN + 1]; char Mqtt_Hass_Topic[MQTT_MAX_TOPIC_STRLEN + 1];
bool Mqtt_Hass_IndividualPanels; bool Mqtt_Hass_IndividualPanels;
bool Mqtt_Tls; bool Mqtt_Tls;
char Mqtt_RootCaCert[MQTT_MAX_ROOT_CA_CERT_STRLEN + 1]; char Mqtt_RootCaCert[MQTT_MAX_CERT_STRLEN + 1];
bool Mqtt_TlsCertLogin;
char Mqtt_ClientCert[MQTT_MAX_CERT_STRLEN + 1];
char Mqtt_ClientKey[MQTT_MAX_CERT_STRLEN + 1];
char Mqtt_Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1]; char Mqtt_Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];

View File

@ -3,7 +3,7 @@
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#define MQTT_JSON_DOC_SIZE 3072 #define MQTT_JSON_DOC_SIZE 10240
class WebApiMqttClass { class WebApiMqttClass {
public: public:
@ -14,7 +14,7 @@ private:
void onMqttStatus(AsyncWebServerRequest* request); void onMqttStatus(AsyncWebServerRequest* request);
void onMqttAdminGet(AsyncWebServerRequest* request); void onMqttAdminGet(AsyncWebServerRequest* request);
void onMqttAdminPost(AsyncWebServerRequest* request); void onMqttAdminPost(AsyncWebServerRequest* request);
String getRootCaCertInfo(const char* cert); String getTlsCertInfo(const char* cert);
AsyncWebServer* _server; AsyncWebServer* _server;
}; };

View File

@ -66,6 +66,9 @@
"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n" \ "mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n" \
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n" \ "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n" \
"-----END CERTIFICATE-----\n" "-----END CERTIFICATE-----\n"
#define MQTT_TLSCERTLOGIN false
#define MQTT_TLSCLIENTCERT ""
#define MQTT_TLSCLIENTKEY ""
#define MQTT_LWT_TOPIC "dtu/status" #define MQTT_LWT_TOPIC "dtu/status"
#define MQTT_LWT_ONLINE "online" #define MQTT_LWT_ONLINE "online"
#define MQTT_LWT_OFFLINE "offline" #define MQTT_LWT_OFFLINE "offline"

View File

@ -65,6 +65,9 @@ bool ConfigurationClass::write()
JsonObject mqtt_tls = mqtt.createNestedObject("tls"); JsonObject mqtt_tls = mqtt.createNestedObject("tls");
mqtt_tls["enabled"] = config.Mqtt_Tls; mqtt_tls["enabled"] = config.Mqtt_Tls;
mqtt_tls["root_ca_cert"] = config.Mqtt_RootCaCert; mqtt_tls["root_ca_cert"] = config.Mqtt_RootCaCert;
mqtt_tls["certlogin"] = config.Mqtt_TlsCertLogin;
mqtt_tls["client_cert"] = config.Mqtt_ClientCert;
mqtt_tls["client_key"] = config.Mqtt_ClientKey;
JsonObject mqtt_hass = mqtt.createNestedObject("hass"); JsonObject mqtt_hass = mqtt.createNestedObject("hass");
mqtt_hass["enabled"] = config.Mqtt_Hass_Enabled; mqtt_hass["enabled"] = config.Mqtt_Hass_Enabled;
@ -202,6 +205,9 @@ bool ConfigurationClass::read()
JsonObject mqtt_tls = mqtt["tls"]; JsonObject mqtt_tls = mqtt["tls"];
config.Mqtt_Tls = mqtt_tls["enabled"] | MQTT_TLS; config.Mqtt_Tls = mqtt_tls["enabled"] | MQTT_TLS;
strlcpy(config.Mqtt_RootCaCert, mqtt_tls["root_ca_cert"] | MQTT_ROOT_CA_CERT, sizeof(config.Mqtt_RootCaCert)); strlcpy(config.Mqtt_RootCaCert, mqtt_tls["root_ca_cert"] | MQTT_ROOT_CA_CERT, sizeof(config.Mqtt_RootCaCert));
config.Mqtt_TlsCertLogin = mqtt_tls["certlogin"] | MQTT_TLSCERTLOGIN;
strlcpy(config.Mqtt_ClientCert, mqtt_tls["client_cert"] | MQTT_TLSCLIENTCERT, sizeof(config.Mqtt_ClientCert));
strlcpy(config.Mqtt_ClientKey, mqtt_tls["client_key"] | MQTT_TLSCLIENTKEY, sizeof(config.Mqtt_ClientKey));
JsonObject mqtt_hass = mqtt["hass"]; JsonObject mqtt_hass = mqtt["hass"];
config.Mqtt_Hass_Enabled = mqtt_hass["enabled"] | MQTT_HASS_ENABLED; config.Mqtt_Hass_Enabled = mqtt_hass["enabled"] | MQTT_HASS_ENABLED;

View File

@ -104,7 +104,12 @@ void MqttSettingsClass::performConnect()
if (config.Mqtt_Tls) { if (config.Mqtt_Tls) {
static_cast<espMqttClientSecure*>(mqttClient)->setCACert(config.Mqtt_RootCaCert); static_cast<espMqttClientSecure*>(mqttClient)->setCACert(config.Mqtt_RootCaCert);
static_cast<espMqttClientSecure*>(mqttClient)->setServer(config.Mqtt_Hostname, config.Mqtt_Port); static_cast<espMqttClientSecure*>(mqttClient)->setServer(config.Mqtt_Hostname, config.Mqtt_Port);
if (config.Mqtt_TlsCertLogin) {
static_cast<espMqttClientSecure*>(mqttClient)->setCertificate(config.Mqtt_ClientCert);
static_cast<espMqttClientSecure*>(mqttClient)->setPrivateKey(config.Mqtt_ClientKey);
} else {
static_cast<espMqttClientSecure*>(mqttClient)->setCredentials(config.Mqtt_Username, config.Mqtt_Password); static_cast<espMqttClientSecure*>(mqttClient)->setCredentials(config.Mqtt_Username, config.Mqtt_Password);
}
static_cast<espMqttClientSecure*>(mqttClient)->setWill(willTopic.c_str(), 2, config.Mqtt_Retain, config.Mqtt_LwtValue_Offline); static_cast<espMqttClientSecure*>(mqttClient)->setWill(willTopic.c_str(), 2, config.Mqtt_Retain, config.Mqtt_LwtValue_Offline);
static_cast<espMqttClientSecure*>(mqttClient)->setClientId(clientId.c_str()); static_cast<espMqttClientSecure*>(mqttClient)->setClientId(clientId.c_str());
static_cast<espMqttClientSecure*>(mqttClient)->onConnect(std::bind(&MqttSettingsClass::onMqttConnect, this, _1)); static_cast<espMqttClientSecure*>(mqttClient)->onConnect(std::bind(&MqttSettingsClass::onMqttConnect, this, _1));

View File

@ -44,7 +44,9 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
root["mqtt_connected"] = MqttSettings.getConnected(); root["mqtt_connected"] = MqttSettings.getConnected();
root["mqtt_retain"] = config.Mqtt_Retain; root["mqtt_retain"] = config.Mqtt_Retain;
root["mqtt_tls"] = config.Mqtt_Tls; root["mqtt_tls"] = config.Mqtt_Tls;
root["mqtt_root_ca_cert_info"] = getRootCaCertInfo(config.Mqtt_RootCaCert); root["mqtt_root_ca_cert_info"] = getTlsCertInfo(config.Mqtt_RootCaCert);
root["mqtt_tls_cert_login"] = config.Mqtt_TlsCertLogin;
root["mqtt_client_cert_info"] = getTlsCertInfo(config.Mqtt_ClientCert);
root["mqtt_lwt_topic"] = String(config.Mqtt_Topic) + config.Mqtt_LwtTopic; root["mqtt_lwt_topic"] = String(config.Mqtt_Topic) + config.Mqtt_LwtTopic;
root["mqtt_publish_interval"] = config.Mqtt_PublishInterval; root["mqtt_publish_interval"] = config.Mqtt_PublishInterval;
root["mqtt_hass_enabled"] = config.Mqtt_Hass_Enabled; root["mqtt_hass_enabled"] = config.Mqtt_Hass_Enabled;
@ -76,6 +78,9 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request)
root["mqtt_retain"] = config.Mqtt_Retain; root["mqtt_retain"] = config.Mqtt_Retain;
root["mqtt_tls"] = config.Mqtt_Tls; root["mqtt_tls"] = config.Mqtt_Tls;
root["mqtt_root_ca_cert"] = config.Mqtt_RootCaCert; root["mqtt_root_ca_cert"] = config.Mqtt_RootCaCert;
root["mqtt_tls_cert_login"] = config.Mqtt_TlsCertLogin;
root["mqtt_client_cert"] = config.Mqtt_ClientCert;
root["mqtt_client_key"] = config.Mqtt_ClientKey;
root["mqtt_lwt_topic"] = config.Mqtt_LwtTopic; root["mqtt_lwt_topic"] = config.Mqtt_LwtTopic;
root["mqtt_lwt_online"] = config.Mqtt_LwtValue_Online; root["mqtt_lwt_online"] = config.Mqtt_LwtValue_Online;
root["mqtt_lwt_offline"] = config.Mqtt_LwtValue_Offline; root["mqtt_lwt_offline"] = config.Mqtt_LwtValue_Offline;
@ -137,6 +142,9 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
&& root.containsKey("mqtt_topic") && root.containsKey("mqtt_topic")
&& root.containsKey("mqtt_retain") && root.containsKey("mqtt_retain")
&& root.containsKey("mqtt_tls") && root.containsKey("mqtt_tls")
&& root.containsKey("mqtt_tls_cert_login")
&& root.containsKey("mqtt_client_cert")
&& root.containsKey("mqtt_client_key")
&& root.containsKey("mqtt_lwt_topic") && root.containsKey("mqtt_lwt_topic")
&& root.containsKey("mqtt_lwt_online") && root.containsKey("mqtt_lwt_online")
&& root.containsKey("mqtt_lwt_offline") && root.containsKey("mqtt_lwt_offline")
@ -164,7 +172,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
} }
if (root["mqtt_username"].as<String>().length() > MQTT_MAX_USERNAME_STRLEN) { if (root["mqtt_username"].as<String>().length() > MQTT_MAX_USERNAME_STRLEN) {
retMsg["message"] = "Username must not longer then " STR(MQTT_MAX_USERNAME_STRLEN) " characters!"; retMsg["message"] = "Username must not be longer than " STR(MQTT_MAX_USERNAME_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttUsernameLength; retMsg["code"] = WebApiError::MqttUsernameLength;
retMsg["param"]["max"] = MQTT_MAX_USERNAME_STRLEN; retMsg["param"]["max"] = MQTT_MAX_USERNAME_STRLEN;
response->setLength(); response->setLength();
@ -172,7 +180,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
return; return;
} }
if (root["mqtt_password"].as<String>().length() > MQTT_MAX_PASSWORD_STRLEN) { if (root["mqtt_password"].as<String>().length() > MQTT_MAX_PASSWORD_STRLEN) {
retMsg["message"] = "Password must not longer then " STR(MQTT_MAX_PASSWORD_STRLEN) " characters!"; retMsg["message"] = "Password must not be longer than " STR(MQTT_MAX_PASSWORD_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttPasswordLength; retMsg["code"] = WebApiError::MqttPasswordLength;
retMsg["param"]["max"] = MQTT_MAX_PASSWORD_STRLEN; retMsg["param"]["max"] = MQTT_MAX_PASSWORD_STRLEN;
response->setLength(); response->setLength();
@ -180,7 +188,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
return; return;
} }
if (root["mqtt_topic"].as<String>().length() > MQTT_MAX_TOPIC_STRLEN) { if (root["mqtt_topic"].as<String>().length() > MQTT_MAX_TOPIC_STRLEN) {
retMsg["message"] = "Topic must not longer then " STR(MQTT_MAX_TOPIC_STRLEN) " characters!"; retMsg["message"] = "Topic must not be longer than " STR(MQTT_MAX_TOPIC_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttTopicLength; retMsg["code"] = WebApiError::MqttTopicLength;
retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN; retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN;
response->setLength(); response->setLength();
@ -197,7 +205,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
} }
if (!root["mqtt_topic"].as<String>().endsWith("/")) { if (!root["mqtt_topic"].as<String>().endsWith("/")) {
retMsg["message"] = "Topic must end with slash (/)!"; retMsg["message"] = "Topic must end with a slash (/)!";
retMsg["code"] = WebApiError::MqttTopicTrailingSlash; retMsg["code"] = WebApiError::MqttTopicTrailingSlash;
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -212,17 +220,19 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
return; return;
} }
if (root["mqtt_root_ca_cert"].as<String>().length() > MQTT_MAX_ROOT_CA_CERT_STRLEN) { if (root["mqtt_root_ca_cert"].as<String>().length() > MQTT_MAX_CERT_STRLEN
retMsg["message"] = "Certificate must not longer then " STR(MQTT_MAX_ROOT_CA_CERT_STRLEN) " characters!"; || root["mqtt_client_cert"].as<String>().length() > MQTT_MAX_CERT_STRLEN
|| root["mqtt_client_key"].as<String>().length() > MQTT_MAX_CERT_STRLEN) {
retMsg["message"] = "Certificates must not be longer than " STR(MQTT_MAX_CERT_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttCertificateLength; retMsg["code"] = WebApiError::MqttCertificateLength;
retMsg["param"]["max"] = MQTT_MAX_ROOT_CA_CERT_STRLEN; retMsg["param"]["max"] = MQTT_MAX_CERT_STRLEN;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
if (root["mqtt_lwt_topic"].as<String>().length() > MQTT_MAX_TOPIC_STRLEN) { if (root["mqtt_lwt_topic"].as<String>().length() > MQTT_MAX_TOPIC_STRLEN) {
retMsg["message"] = "LWT topic must not longer then " STR(MQTT_MAX_TOPIC_STRLEN) " characters!"; retMsg["message"] = "LWT topic must not be longer than " STR(MQTT_MAX_TOPIC_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttLwtTopicLength; retMsg["code"] = WebApiError::MqttLwtTopicLength;
retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN; retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN;
response->setLength(); response->setLength();
@ -239,7 +249,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
} }
if (root["mqtt_lwt_online"].as<String>().length() > MQTT_MAX_LWTVALUE_STRLEN) { if (root["mqtt_lwt_online"].as<String>().length() > MQTT_MAX_LWTVALUE_STRLEN) {
retMsg["message"] = "LWT online value must not longer then " STR(MQTT_MAX_LWTVALUE_STRLEN) " characters!"; retMsg["message"] = "LWT online value must not be longer than " STR(MQTT_MAX_LWTVALUE_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttLwtOnlineLength; retMsg["code"] = WebApiError::MqttLwtOnlineLength;
retMsg["param"]["max"] = MQTT_MAX_LWTVALUE_STRLEN; retMsg["param"]["max"] = MQTT_MAX_LWTVALUE_STRLEN;
response->setLength(); response->setLength();
@ -248,7 +258,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
} }
if (root["mqtt_lwt_offline"].as<String>().length() > MQTT_MAX_LWTVALUE_STRLEN) { if (root["mqtt_lwt_offline"].as<String>().length() > MQTT_MAX_LWTVALUE_STRLEN) {
retMsg["message"] = "LWT offline value must not longer then " STR(MQTT_MAX_LWTVALUE_STRLEN) " characters!"; retMsg["message"] = "LWT offline value must not be longer than " STR(MQTT_MAX_LWTVALUE_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttLwtOfflineLength; retMsg["code"] = WebApiError::MqttLwtOfflineLength;
retMsg["param"]["max"] = MQTT_MAX_LWTVALUE_STRLEN; retMsg["param"]["max"] = MQTT_MAX_LWTVALUE_STRLEN;
response->setLength(); response->setLength();
@ -268,7 +278,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
if (root["mqtt_hass_enabled"].as<bool>()) { if (root["mqtt_hass_enabled"].as<bool>()) {
if (root["mqtt_hass_topic"].as<String>().length() > MQTT_MAX_TOPIC_STRLEN) { if (root["mqtt_hass_topic"].as<String>().length() > MQTT_MAX_TOPIC_STRLEN) {
retMsg["message"] = "Hass topic must not longer then " STR(MQTT_MAX_TOPIC_STRLEN) " characters!"; retMsg["message"] = "Hass topic must not be longer than " STR(MQTT_MAX_TOPIC_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttHassTopicLength; retMsg["code"] = WebApiError::MqttHassTopicLength;
retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN; retMsg["param"]["max"] = MQTT_MAX_TOPIC_STRLEN;
response->setLength(); response->setLength();
@ -291,6 +301,9 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
config.Mqtt_Retain = root["mqtt_retain"].as<bool>(); config.Mqtt_Retain = root["mqtt_retain"].as<bool>();
config.Mqtt_Tls = root["mqtt_tls"].as<bool>(); config.Mqtt_Tls = root["mqtt_tls"].as<bool>();
strlcpy(config.Mqtt_RootCaCert, root["mqtt_root_ca_cert"].as<String>().c_str(), sizeof(config.Mqtt_RootCaCert)); strlcpy(config.Mqtt_RootCaCert, root["mqtt_root_ca_cert"].as<String>().c_str(), sizeof(config.Mqtt_RootCaCert));
config.Mqtt_TlsCertLogin = root["mqtt_tls_cert_login"].as<bool>();
strlcpy(config.Mqtt_ClientCert, root["mqtt_client_cert"].as<String>().c_str(), sizeof(config.Mqtt_ClientCert));
strlcpy(config.Mqtt_ClientKey, root["mqtt_client_key"].as<String>().c_str(), sizeof(config.Mqtt_ClientKey));
config.Mqtt_Port = root["mqtt_port"].as<uint>(); config.Mqtt_Port = root["mqtt_port"].as<uint>();
strlcpy(config.Mqtt_Hostname, root["mqtt_hostname"].as<String>().c_str(), sizeof(config.Mqtt_Hostname)); strlcpy(config.Mqtt_Hostname, root["mqtt_hostname"].as<String>().c_str(), sizeof(config.Mqtt_Hostname));
strlcpy(config.Mqtt_Username, root["mqtt_username"].as<String>().c_str(), sizeof(config.Mqtt_Username)); strlcpy(config.Mqtt_Username, root["mqtt_username"].as<String>().c_str(), sizeof(config.Mqtt_Username));
@ -318,23 +331,23 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
MqttHandleHass.forceUpdate(); MqttHandleHass.forceUpdate();
} }
String WebApiMqttClass::getRootCaCertInfo(const char* cert) String WebApiMqttClass::getTlsCertInfo(const char* cert)
{ {
char rootCaCertInfo[1024] = ""; char tlsCertInfo[1024] = "";
mbedtls_x509_crt global_cacert; mbedtls_x509_crt tlsCert;
strlcpy(rootCaCertInfo, "Can't parse root ca", sizeof(rootCaCertInfo)); strlcpy(tlsCertInfo, "Can't parse TLS certificate", sizeof(tlsCertInfo));
mbedtls_x509_crt_init(&global_cacert); mbedtls_x509_crt_init(&tlsCert);
int ret = mbedtls_x509_crt_parse(&global_cacert, const_cast<unsigned char*>((unsigned char*)cert), 1 + strlen(cert)); int ret = mbedtls_x509_crt_parse(&tlsCert, const_cast<unsigned char*>((unsigned char*)cert), 1 + strlen(cert));
if (ret < 0) { if (ret < 0) {
snprintf(rootCaCertInfo, sizeof(rootCaCertInfo), "Can't parse root ca: mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); snprintf(tlsCertInfo, sizeof(tlsCertInfo), "Can't parse TLS certificate: mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
mbedtls_x509_crt_free(&global_cacert); mbedtls_x509_crt_free(&tlsCert);
return ""; return "";
} }
mbedtls_x509_crt_info(rootCaCertInfo, sizeof(rootCaCertInfo) - 1, "", &global_cacert); mbedtls_x509_crt_info(tlsCertInfo, sizeof(tlsCertInfo) - 1, "", &tlsCert);
mbedtls_x509_crt_free(&global_cacert); mbedtls_x509_crt_free(&tlsCert);
return rootCaCertInfo; return tlsCertInfo;
} }

View File

@ -259,6 +259,8 @@
"Retain": "Retain", "Retain": "Retain",
"Tls": "TLS", "Tls": "TLS",
"RootCertifcateInfo": "Root CA-Zertifikat-Informationen", "RootCertifcateInfo": "Root CA-Zertifikat-Informationen",
"TlsCertLogin": "Anmeldung mit TLS Zertifikat",
"ClientCertifcateInfo": "Client Zertifikat-Informationen",
"HassSummary": "Home Assistant MQTT-Auto-Discovery Konfigurationszusammenfassung", "HassSummary": "Home Assistant MQTT-Auto-Discovery Konfigurationszusammenfassung",
"Expire": "Ablaufen", "Expire": "Ablaufen",
"IndividualPanels": "Einzelne Paneele", "IndividualPanels": "Einzelne Paneele",
@ -387,6 +389,9 @@
"EnableRetain": "Retain Flag aktivieren", "EnableRetain": "Retain Flag aktivieren",
"EnableTls": "TLS aktivieren", "EnableTls": "TLS aktivieren",
"RootCa": "CA-Root-Zertifikat (Standard Letsencrypt):", "RootCa": "CA-Root-Zertifikat (Standard Letsencrypt):",
"TlsCertLoginEnable": "TLS Zertifikat Login",
"ClientCert": "TLS Client-Zertifikat:",
"ClientKey": "TLS Client-Key:",
"LwtParameters": "LWT-Parameter", "LwtParameters": "LWT-Parameter",
"LwtTopic": "LWT-Topic:", "LwtTopic": "LWT-Topic:",
"LwtTopicHint": "LWT-Topic, wird der Basis Topic angehängt", "LwtTopicHint": "LWT-Topic, wird der Basis Topic angehängt",

View File

@ -259,6 +259,8 @@
"Retain": "Retain", "Retain": "Retain",
"Tls": "TLS", "Tls": "TLS",
"RootCertifcateInfo": "Root CA Certifcate Info", "RootCertifcateInfo": "Root CA Certifcate Info",
"TlsCertLogin": "Login with TLS Certificate",
"ClientCertifcateInfo": "Client Certifcate Info",
"HassSummary": "Home Assistant MQTT Auto Discovery Configuration Summary", "HassSummary": "Home Assistant MQTT Auto Discovery Configuration Summary",
"Expire": "Expire", "Expire": "Expire",
"IndividualPanels": "Individual Panels", "IndividualPanels": "Individual Panels",
@ -387,6 +389,9 @@
"EnableRetain": "Enable Retain Flag", "EnableRetain": "Enable Retain Flag",
"EnableTls": "Enable TLS", "EnableTls": "Enable TLS",
"RootCa": "CA-Root-Certificate (default Letsencrypt):", "RootCa": "CA-Root-Certificate (default Letsencrypt):",
"TlsCertLoginEnable": "Enable TLS Certificate Login",
"ClientCert": "TLS Client-Certificate:",
"ClientKey": "TLS Client-Key:",
"LwtParameters": "LWT Parameters", "LwtParameters": "LWT Parameters",
"LwtTopic": "LWT Topic:", "LwtTopic": "LWT Topic:",
"LwtTopicHint": "LWT topic, will be append base topic", "LwtTopicHint": "LWT topic, will be append base topic",

View File

@ -259,6 +259,8 @@
"Retain": "Conserver", "Retain": "Conserver",
"Tls": "TLS", "Tls": "TLS",
"RootCertifcateInfo": "Informations sur le certificat de l'autorité de certification racine", "RootCertifcateInfo": "Informations sur le certificat de l'autorité de certification racine",
"TlsCertLogin": "Connexion avec un certificat TLS",
"ClientCertifcateInfo": "Informations sur le certificat du client",
"HassSummary": "Résumé de la configuration de la découverte automatique du MQTT de Home Assistant", "HassSummary": "Résumé de la configuration de la découverte automatique du MQTT de Home Assistant",
"Expire": "Expiration", "Expire": "Expiration",
"IndividualPanels": "Panneaux individuels", "IndividualPanels": "Panneaux individuels",
@ -387,6 +389,9 @@
"EnableRetain": "Activation du maintien", "EnableRetain": "Activation du maintien",
"EnableTls": "Activer le TLS", "EnableTls": "Activer le TLS",
"RootCa": "Certificat CA-Root (par défaut Letsencrypt)", "RootCa": "Certificat CA-Root (par défaut Letsencrypt)",
"TlsCertLoginEnable": "Activer la connexion par certificat TLS",
"ClientCert": "Certificat client TLS:",
"ClientKey": "Clé client TLS:",
"LwtParameters": "Paramètres LWT", "LwtParameters": "Paramètres LWT",
"LwtTopic": "Sujet LWT", "LwtTopic": "Sujet LWT",
"LwtTopicHint": "Sujet LWT, sera ajouté comme sujet de base", "LwtTopicHint": "Sujet LWT, sera ajouté comme sujet de base",

View File

@ -9,6 +9,9 @@ export interface MqttConfig {
mqtt_retain: boolean; mqtt_retain: boolean;
mqtt_tls: boolean; mqtt_tls: boolean;
mqtt_root_ca_cert: string; mqtt_root_ca_cert: string;
mqtt_tls_cert_login: boolean;
mqtt_client_cert: string;
mqtt_client_key: string;
mqtt_lwt_topic: string; mqtt_lwt_topic: string;
mqtt_lwt_online: string; mqtt_lwt_online: string;
mqtt_lwt_offline: string; mqtt_lwt_offline: string;

View File

@ -8,6 +8,8 @@ export interface MqttStatus {
mqtt_retain: boolean; mqtt_retain: boolean;
mqtt_tls: boolean; mqtt_tls: boolean;
mqtt_root_ca_cert_info: string; mqtt_root_ca_cert_info: string;
mqtt_tls_cert_login: boolean;
mqtt_client_cert_info: string;
mqtt_connected: boolean; mqtt_connected: boolean;
mqtt_hass_enabled: boolean; mqtt_hass_enabled: boolean;
mqtt_hass_expire: boolean; mqtt_hass_expire: boolean;

View File

@ -60,6 +60,21 @@
:label="$t('mqttadmin.RootCa')" :label="$t('mqttadmin.RootCa')"
v-model="mqttConfigList.mqtt_root_ca_cert" v-model="mqttConfigList.mqtt_root_ca_cert"
type="textarea" maxlength="2560" rows="10"/> type="textarea" maxlength="2560" rows="10"/>
<InputElement v-show="mqttConfigList.mqtt_tls"
:label="$t('mqttadmin.TlsCertLoginEnable')"
v-model="mqttConfigList.mqtt_tls_cert_login"
type="checkbox"/>
<InputElement v-show="mqttConfigList.mqtt_tls_cert_login"
:label="$t('mqttadmin.ClientCert')"
v-model="mqttConfigList.mqtt_client_cert"
type="textarea" maxlength="2560" rows="10"/>
<InputElement v-show="mqttConfigList.mqtt_tls_cert_login"
:label="$t('mqttadmin.ClientKey')"
v-model="mqttConfigList.mqtt_client_key"
type="textarea" maxlength="2560" rows="10"/>
</CardElement> </CardElement>
<CardElement :text="$t('mqttadmin.LwtParameters')" textVariant="text-bg-primary" add-space <CardElement :text="$t('mqttadmin.LwtParameters')" textVariant="text-bg-primary" add-space

View File

@ -46,6 +46,16 @@
<th>{{ $t('mqttinfo.RootCertifcateInfo') }}</th> <th>{{ $t('mqttinfo.RootCertifcateInfo') }}</th>
<td>{{ mqttDataList.mqtt_root_ca_cert_info }}</td> <td>{{ mqttDataList.mqtt_root_ca_cert_info }}</td>
</tr> </tr>
<tr>
<th>{{ $t('mqttinfo.TlsCertLogin') }}</th>
<td>
<StatusBadge :status="mqttDataList.mqtt_tls_cert_login" true_text="mqttinfo.Enabled" false_text="mqttinfo.Disabled" />
</td>
</tr>
<tr v-show="mqttDataList.mqtt_tls_cert_login">
<th>{{ $t('mqttinfo.ClientCertifcateInfo') }}</th>
<td>{{ mqttDataList.mqtt_client_cert_info }}</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>