diff --git a/include/Configuration.h b/include/Configuration.h index 7c5ce1f6..e2ed0b3b 100644 --- a/include/Configuration.h +++ b/include/Configuration.h @@ -98,6 +98,7 @@ struct CONFIG_T { char Topic[MQTT_MAX_TOPIC_STRLEN + 1]; char Value_Online[MQTT_MAX_LWTVALUE_STRLEN + 1]; char Value_Offline[MQTT_MAX_LWTVALUE_STRLEN + 1]; + uint8_t Qos; } Lwt; struct { diff --git a/include/WebApi_errors.h b/include/WebApi_errors.h index ac91941e..31ddae03 100644 --- a/include/WebApi_errors.h +++ b/include/WebApi_errors.h @@ -56,6 +56,7 @@ enum WebApiError { MqttPublishInterval, MqttHassTopicLength, MqttHassTopicCharacter, + MqttLwtQos, NetworkBase = 8000, NetworkIpInvalid, diff --git a/include/defaults.h b/include/defaults.h index 2ee00630..264e6661 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -75,6 +75,7 @@ #define MQTT_LWT_TOPIC "dtu/status" #define MQTT_LWT_ONLINE "online" #define MQTT_LWT_OFFLINE "offline" +#define MQTT_LWT_QOS 2U #define MQTT_PUBLISH_INTERVAL 5U #define MQTT_CLEAN_SESSION true diff --git a/src/Configuration.cpp b/src/Configuration.cpp index e88bc399..ffb70f2d 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -67,6 +67,7 @@ bool ConfigurationClass::write() mqtt_lwt["topic"] = config.Mqtt.Lwt.Topic; mqtt_lwt["value_online"] = config.Mqtt.Lwt.Value_Online; mqtt_lwt["value_offline"] = config.Mqtt.Lwt.Value_Offline; + mqtt_lwt["qos"] = config.Mqtt.Lwt.Qos; JsonObject mqtt_tls = mqtt.createNestedObject("tls"); mqtt_tls["enabled"] = config.Mqtt.Tls.Enabled; @@ -220,6 +221,7 @@ bool ConfigurationClass::read() strlcpy(config.Mqtt.Lwt.Topic, mqtt_lwt["topic"] | MQTT_LWT_TOPIC, sizeof(config.Mqtt.Lwt.Topic)); strlcpy(config.Mqtt.Lwt.Value_Online, mqtt_lwt["value_online"] | MQTT_LWT_ONLINE, sizeof(config.Mqtt.Lwt.Value_Online)); strlcpy(config.Mqtt.Lwt.Value_Offline, mqtt_lwt["value_offline"] | MQTT_LWT_OFFLINE, sizeof(config.Mqtt.Lwt.Value_Offline)); + config.Mqtt.Lwt.Qos = mqtt_lwt["qos"] | MQTT_LWT_QOS; JsonObject mqtt_tls = mqtt["tls"]; config.Mqtt.Tls.Enabled = mqtt_tls["enabled"] | MQTT_TLS; diff --git a/src/MqttSettings.cpp b/src/MqttSettings.cpp index 2a4ba262..e864437d 100644 --- a/src/MqttSettings.cpp +++ b/src/MqttSettings.cpp @@ -134,7 +134,7 @@ void MqttSettingsClass::performConnect() } else { static_cast(mqttClient)->setServer(config.Mqtt.Hostname, config.Mqtt.Port); static_cast(mqttClient)->setCredentials(config.Mqtt.Username, config.Mqtt.Password); - static_cast(mqttClient)->setWill(willTopic.c_str(), 2, config.Mqtt.Retain, config.Mqtt.Lwt.Value_Offline); + static_cast(mqttClient)->setWill(willTopic.c_str(), config.Mqtt.Lwt.Qos, config.Mqtt.Retain, config.Mqtt.Lwt.Value_Offline); static_cast(mqttClient)->setClientId(clientId.c_str()); static_cast(mqttClient)->setCleanSession(config.Mqtt.CleanSession); static_cast(mqttClient)->onConnect(std::bind(&MqttSettingsClass::onMqttConnect, this, _1)); diff --git a/src/WebApi_mqtt.cpp b/src/WebApi_mqtt.cpp index d31b1e91..340642b9 100644 --- a/src/WebApi_mqtt.cpp +++ b/src/WebApi_mqtt.cpp @@ -85,6 +85,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request) root["mqtt_lwt_topic"] = config.Mqtt.Lwt.Topic; root["mqtt_lwt_online"] = config.Mqtt.CleanSession; root["mqtt_lwt_offline"] = config.Mqtt.Lwt.Value_Offline; + root["mqtt_lwt_qos"] = config.Mqtt.Lwt.Qos; root["mqtt_publish_interval"] = config.Mqtt.PublishInterval; root["mqtt_clean_session"] = config.Mqtt.CleanSession; root["mqtt_hass_enabled"] = config.Mqtt.Hass.Enabled; @@ -150,6 +151,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) && root.containsKey("mqtt_lwt_topic") && root.containsKey("mqtt_lwt_online") && root.containsKey("mqtt_lwt_offline") + && root.containsKey("mqtt_lwt_qos") && root.containsKey("mqtt_publish_interval") && root.containsKey("mqtt_clean_session") && root.containsKey("mqtt_hass_enabled") @@ -269,6 +271,15 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) return; } + if (root["mqtt_lwt_qos"].as() > 2) { + retMsg["message"] = "LWT QoS must not be greater than " STR(2) "!"; + retMsg["code"] = WebApiError::MqttLwtQos; + retMsg["param"]["max"] = 2; + response->setLength(); + request->send(response); + return; + } + if (root["mqtt_publish_interval"].as() < 5 || root["mqtt_publish_interval"].as() > 65535) { retMsg["message"] = "Publish interval must be a number between 5 and 65535!"; retMsg["code"] = WebApiError::MqttPublishInterval; @@ -315,6 +326,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) strlcpy(config.Mqtt.Lwt.Topic, root["mqtt_lwt_topic"].as().c_str(), sizeof(config.Mqtt.Lwt.Topic)); strlcpy(config.Mqtt.Lwt.Value_Online, root["mqtt_lwt_online"].as().c_str(), sizeof(config.Mqtt.Lwt.Value_Online)); strlcpy(config.Mqtt.Lwt.Value_Offline, root["mqtt_lwt_offline"].as().c_str(), sizeof(config.Mqtt.Lwt.Value_Offline)); + config.Mqtt.Lwt.Qos = root["mqtt_lwt_qos"].as(); config.Mqtt.PublishInterval = root["mqtt_publish_interval"].as(); config.Mqtt.CleanSession = root["mqtt_clean_session"].as(); config.Mqtt.Hass.Enabled = root["mqtt_hass_enabled"].as(); diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index 62e7548b..e14e281e 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -73,6 +73,7 @@ "7013": "Veröffentlichungsintervall muss zwischen {min} und {max} sein!", "7014": "Hass-Topic darf nicht länger als {max} Zeichen sein!", "7015": "Hass-Topic darf keine Leerzeichen enthalten!", + "7016": "LWT QOS darf icht größer als {max} sein!", "8001": "IP-Adresse ist ungültig!", "8002": "Netzmaske ist ungültig!", "8003": "Standardgateway ist ungültig!", @@ -437,6 +438,10 @@ "LwtOnlineHint": "Nachricht, die im LWT-Topic veröffentlicht wird, wenn OpenDTU online ist", "LwtOffline": "LWT-Offline-Nachricht:", "LwtOfflineHint": "Nachricht, die im LWT-Topic veröffentlicht wird, wenn OpenDTU offline ist", + "LwtQos": "QoS (Quality of Service):", + "QOS0": "0 (Höchstens einmal)", + "QOS1": "1 (Mindestens einmal)", + "QOS2": "2 (Exakt einmal)", "HassParameters": "Home Assistant MQTT-Auto-Discovery-Parameter", "HassPrefixTopic": "Präfix Topic:", "HassPrefixTopicHint": "The prefix for the discovery topic", diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 40458b17..4a76935d 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -73,6 +73,7 @@ "7013": "Publish interval must be a number between {min} and {max}!", "7014": "Hass topic must not longer then {max} characters!", "7015": "Hass topic must not contain space characters!", + "7016": "LWT QOS must not greater then {max}!", "8001": "IP address is invalid!", "8002": "Netmask is invalid!", "8003": "Gateway is invalid!", @@ -437,6 +438,10 @@ "LwtOnlineHint": "Message that will be published to LWT topic when online", "LwtOffline": "LWT Offline message:", "LwtOfflineHint": "Message that will be published to LWT topic when offline", + "LwtQos": "QoS (Quality of Service):", + "QOS0": "0 (At most once)", + "QOS1": "1 (At least once)", + "QOS2": "2 (Exactly once)", "HassParameters": "Home Assistant MQTT Auto Discovery Parameters", "HassPrefixTopic": "Prefix Topic:", "HassPrefixTopicHint": "The prefix for the discovery topic", diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index e5a48eb1..e3afc29f 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -73,6 +73,7 @@ "7013": "L'intervalle de publication doit être un nombre compris entre {min} et {max} !", "7014": "Le sujet Hass ne doit pas dépasser {max} caractères !", "7015": "Le sujet Hass ne doit pas contenir d'espace !", + "7016": "LWT QOS ne doit pas être supérieur à {max}!", "8001": "L'adresse IP n'est pas valide !", "8002": "Le masque de réseau n'est pas valide !", "8003": "La passerelle n'est pas valide !", @@ -437,6 +438,10 @@ "LwtOnlineHint": "Message qui sera publié sur le sujet LWT lorsqu'il sera en ligne", "LwtOffline": "Message hors ligne de LWT", "LwtOfflineHint": "Message qui sera publié sur le sujet LWT lorsqu'il sera hors ligne", + "LwtQos": "QoS (Quality of Service):", + "QOS0": "0 (Au maximum une fois)", + "QOS1": "1 (Au moins une fois)", + "QOS2": "2 (Exactement une fois)", "HassParameters": "Paramètres de découverte automatique MQTT de Home Assistant", "HassPrefixTopic": "Préfixe du sujet", "HassPrefixTopicHint": "Le préfixe de découverte du sujet", diff --git a/webapp/src/types/MqttConfig.ts b/webapp/src/types/MqttConfig.ts index f2d847b8..c61b770a 100644 --- a/webapp/src/types/MqttConfig.ts +++ b/webapp/src/types/MqttConfig.ts @@ -16,6 +16,7 @@ export interface MqttConfig { mqtt_lwt_topic: string; mqtt_lwt_online: string; mqtt_lwt_offline: string; + mqtt_lwt_qos: number; mqtt_hass_enabled: boolean; mqtt_hass_expire: boolean; mqtt_hass_retain: boolean; diff --git a/webapp/src/views/MqttAdminView.vue b/webapp/src/views/MqttAdminView.vue index d8c03b7f..fadc8d2a 100644 --- a/webapp/src/views/MqttAdminView.vue +++ b/webapp/src/views/MqttAdminView.vue @@ -98,6 +98,19 @@ v-model="mqttConfigList.mqtt_lwt_offline" type="text" maxlength="20" :placeholder="$t('mqttadmin.LwtOfflineHint')"/> + +
+ +
+ +
+