Ver código fonte

Add support for Domoticz MQTT integration (#3359)

* initial changes to add domoticz support

* error correction

* further changes

* further changes

* Refactoring

* further refactoring

* further refactoring

* Update DomoticzTopicIn.md

* Update NUMBER.DomoticzIDX.md

* Update DomoticzTopicIn.md

* Update NUMBER.DomoticzIDX.md

* Update config.ini

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update DomoticzTopicIn.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>
gneluka 1 ano atrás
pai
commit
08baf1824c

+ 2 - 0
code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h

@@ -66,6 +66,8 @@ struct NumberPost {
     float AnalogToDigitTransitionStart; // AnalogToDigitTransitionStartValue; FIXME: need a better description; When is the digit > x.1, i.e. when does it start to tilt?
     float AnalogToDigitTransitionStart; // AnalogToDigitTransitionStartValue; FIXME: need a better description; When is the digit > x.1, i.e. when does it start to tilt?
     int Nachkomma;              // decimalPlaces; usually defined by the number of analog ROIs; affected by DecimalShift
     int Nachkomma;              // decimalPlaces; usually defined by the number of analog ROIs; affected by DecimalShift
 
 
+    string DomoticzIdx;             // Domoticz counter Idx
+    
     string FieldV1;             // influxdbFieldName_v1; Name of the Field in InfluxDBv1
     string FieldV1;             // influxdbFieldName_v1; Name of the Field in InfluxDBv1
     string MeasurementV1;       // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1
     string MeasurementV1;       // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1
 
 

+ 55 - 15
code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp

@@ -51,6 +51,7 @@ void ClassFlowMQTT::SetInitialParameter(void)
     ListFlowControll = NULL; 
     ListFlowControll = NULL; 
     disabled = false;
     disabled = false;
     keepAlive = 25*60;
     keepAlive = 25*60;
+    domoticzintopic = "";
 }       
 }       
 
 
 ClassFlowMQTT::ClassFlowMQTT()
 ClassFlowMQTT::ClassFlowMQTT()
@@ -105,43 +106,44 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
     while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
     while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
     {
     {
         splitted = ZerlegeZeile(aktparamgraph);
         splitted = ZerlegeZeile(aktparamgraph);
-        if ((toUpper(splitted[0]) == "CACERT") && (splitted.size() > 1))
+        std::string _param = GetParameterName(splitted[0]);
+        if ((toUpper(_param) == "CACERT") && (splitted.size() > 1))
         {
         {
             this->caCertFilename = splitted[1];
             this->caCertFilename = splitted[1];
         }  
         }  
-        if ((toUpper(splitted[0]) == "CLIENTCERT") && (splitted.size() > 1))
+        if ((toUpper(_param) == "CLIENTCERT") && (splitted.size() > 1))
         {
         {
             this->clientCertFilename = splitted[1];
             this->clientCertFilename = splitted[1];
         }  
         }  
-        if ((toUpper(splitted[0]) == "CLIENTKEY") && (splitted.size() > 1))
+        if ((toUpper(_param) == "CLIENTKEY") && (splitted.size() > 1))
         {
         {
             this->clientKeyFilename = splitted[1];
             this->clientKeyFilename = splitted[1];
         }  
         }  
-        if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1))
+        if ((toUpper(_param) == "USER") && (splitted.size() > 1))
         {
         {
             this->user = splitted[1];
             this->user = splitted[1];
         }  
         }  
-        if ((toUpper(splitted[0]) == "PASSWORD") && (splitted.size() > 1))
+        if ((toUpper(_param) == "PASSWORD") && (splitted.size() > 1))
         {
         {
             this->password = splitted[1];
             this->password = splitted[1];
         }               
         }               
-        if ((toUpper(splitted[0]) == "URI") && (splitted.size() > 1))
+        if ((toUpper(_param) == "URI") && (splitted.size() > 1))
         {
         {
             this->uri = splitted[1];
             this->uri = splitted[1];
         }
         }
-        if ((toUpper(splitted[0]) == "RETAINMESSAGES") && (splitted.size() > 1))
+        if ((toUpper(_param) == "RETAINMESSAGES") && (splitted.size() > 1))
         {
         {
             if (toUpper(splitted[1]) == "TRUE") {
             if (toUpper(splitted[1]) == "TRUE") {
                 SetRetainFlag = true;  
                 SetRetainFlag = true;  
                 setMqtt_Server_Retain(SetRetainFlag);
                 setMqtt_Server_Retain(SetRetainFlag);
             }
             }
         }
         }
-        if ((toUpper(splitted[0]) == "HOMEASSISTANTDISCOVERY") && (splitted.size() > 1))
+        if ((toUpper(_param) == "HOMEASSISTANTDISCOVERY") && (splitted.size() > 1))
         {
         {
             if (toUpper(splitted[1]) == "TRUE")
             if (toUpper(splitted[1]) == "TRUE")
                 SetHomeassistantDiscoveryEnabled(true);  
                 SetHomeassistantDiscoveryEnabled(true);  
         }
         }
-        if ((toUpper(splitted[0]) == "METERTYPE") && (splitted.size() > 1)) {
+        if ((toUpper(_param) == "METERTYPE") && (splitted.size() > 1)) {
         /* Use meter type for the device class 
         /* Use meter type for the device class 
            Make sure it is a listed one on https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes */
            Make sure it is a listed one on https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes */
             if (toUpper(splitted[1]) == "WATER_M3") {
             if (toUpper(splitted[1]) == "WATER_M3") {
@@ -176,15 +178,26 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
             }
             }
         }
         }
 
 
-        if ((toUpper(splitted[0]) == "CLIENTID") && (splitted.size() > 1))
+        if ((toUpper(_param) == "CLIENTID") && (splitted.size() > 1))
         {
         {
             this->clientname = splitted[1];
             this->clientname = splitted[1];
         }
         }
 
 
-        if (((toUpper(splitted[0]) == "TOPIC") || (toUpper(splitted[0]) == "MAINTOPIC")) && (splitted.size() > 1))
+        if (((toUpper(_param) == "TOPIC") || (toUpper(splitted[0]) == "MAINTOPIC")) && (splitted.size() > 1))
         {
         {
             maintopic = splitted[1];
             maintopic = splitted[1];
         }
         }
+
+        if (((toUpper(_param) == "DOMOTICZTOPICIN")) && (splitted.size() > 1))
+        {
+            this->domoticzintopic = splitted[1];
+        }
+
+        if (((toUpper(_param) == "DOMOTICZIDX")) && (splitted.size() > 1))
+        {
+            handleIdx(splitted[0], splitted[1]);
+        }
+        
     }
     }
 
 
     /* Note:
     /* Note:
@@ -193,6 +206,7 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
      * To work around this, we delay the start and trigger it from ClassFlowControll::ReadParameter() */
      * To work around this, we delay the start and trigger it from ClassFlowControll::ReadParameter() */
 
 
     mqttServer_setMainTopic(maintopic);
     mqttServer_setMainTopic(maintopic);
+    mqttServer_setDmoticzInTopic(domoticzintopic);
 
 
     return true;
     return true;
 }
 }
@@ -210,7 +224,7 @@ bool ClassFlowMQTT::Start(float AutoInterval)
 
 
     mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);
     mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);
 
 
-    bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED,
+    bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, domoticzintopic, LWT_TOPIC, LWT_CONNECTED,
                                      LWT_DISCONNECTED, caCertFilename, clientCertFilename, clientKeyFilename,
                                      LWT_DISCONNECTED, caCertFilename, clientCertFilename, clientKeyFilename,
                                      keepAlive, SetRetainFlag, (void *)&GotConnected);
                                      keepAlive, SetRetainFlag, (void *)&GotConnected);
 
 
@@ -235,6 +249,8 @@ bool ClassFlowMQTT::doFlow(string zwtime)
     std::string resultchangabs = "";
     std::string resultchangabs = "";
     string zw = "";
     string zw = "";
     string namenumber = "";
     string namenumber = "";
+    string domoticzpayload = "";
+    string DomoticzIdx = "";
     int qos = 1;
     int qos = 1;
 
 
     /* Send the the Homeassistant Discovery and the Static Topics in case they where scheduled */
     /* Send the the Homeassistant Discovery and the Static Topics in case they where scheduled */
@@ -258,16 +274,20 @@ bool ClassFlowMQTT::doFlow(string zwtime)
             resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
             resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
             resulttimestamp = (*NUMBERS)[i]->timeStamp;
             resulttimestamp = (*NUMBERS)[i]->timeStamp;
 
 
+            DomoticzIdx = (*NUMBERS)[i]->DomoticzIdx;
+            domoticzpayload = "{\"command\":\"udevice\",\"idx\":" + DomoticzIdx + ",\"svalue\":\""+ result + "\"}";
+
             namenumber = (*NUMBERS)[i]->name;
             namenumber = (*NUMBERS)[i]->name;
             if (namenumber == "default")
             if (namenumber == "default")
                 namenumber = maintopic + "/";
                 namenumber = maintopic + "/";
             else
             else
                 namenumber = maintopic + "/" + namenumber + "/";
                 namenumber = maintopic + "/" + namenumber + "/";
 
 
+            if ((domoticzintopic.length() > 0) && (result.length() > 0)) 
+                success |= MQTTPublish(domoticzintopic, domoticzpayload, qos, SetRetainFlag);
 
 
-            if (result.length() > 0)   
+            if (result.length() > 0)
                 success |= MQTTPublish(namenumber + "value", result, qos, SetRetainFlag);
                 success |= MQTTPublish(namenumber + "value", result, qos, SetRetainFlag);
-
             if (resulterror.length() > 0)  
             if (resulterror.length() > 0)  
                 success |= MQTTPublish(namenumber + "error", resulterror, qos, SetRetainFlag);
                 success |= MQTTPublish(namenumber + "error", resulterror, qos, SetRetainFlag);
 
 
@@ -325,6 +345,26 @@ bool ClassFlowMQTT::doFlow(string zwtime)
     
     
     return true;
     return true;
 }
 }
-
+void ClassFlowMQTT::handleIdx(string _decsep, string _value)
+{
+    string _digit, _decpos;
+    int _pospunkt = _decsep.find_first_of(".");
+//    ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
+    if (_pospunkt > -1)
+        _digit = _decsep.substr(0, _pospunkt);
+    else
+        _digit = "default";
+    for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
+    {
+        if (_digit == "default")                        //  Set to default first (if nothing else is set)
+        {
+            flowpostprocessing->NUMBERS[j]->DomoticzIdx = _value;
+        }
+        if (flowpostprocessing->NUMBERS[j]->name == _digit)
+        {
+            flowpostprocessing->NUMBERS[j]->DomoticzIdx = _value;
+        }
+    }
+}
 
 
 #endif //ENABLE_MQTT
 #endif //ENABLE_MQTT

+ 2 - 2
code/components/jomjol_flowcontroll/ClassFlowMQTT.h

@@ -23,9 +23,9 @@ protected:
     bool SetRetainFlag;
     bool SetRetainFlag;
     int keepAlive; // Seconds
     int keepAlive; // Seconds
     float roundInterval; // Minutes
     float roundInterval; // Minutes
-
-    std::string maintopic; 
+    std::string maintopic, domoticzintopic; 
 	void SetInitialParameter(void);        
 	void SetInitialParameter(void);        
+    void handleIdx(string _decsep, string _value);   
 
 
 public:
 public:
     ClassFlowMQTT();
     ClassFlowMQTT();

+ 3 - 2
code/components/jomjol_mqtt/interface_mqtt.cpp

@@ -34,7 +34,7 @@ bool mqtt_initialized = false;
 bool mqtt_connected = false;
 bool mqtt_connected = false;
 
 
 esp_mqtt_client_handle_t client = NULL;
 esp_mqtt_client_handle_t client = NULL;
-std::string uri, client_id, lwt_topic, lwt_connected, lwt_disconnected, user, password, maintopic;
+std::string uri, client_id, lwt_topic, lwt_connected, lwt_disconnected, user, password, maintopic, domoticz_in_topic;
 std::string caCert, clientCert, clientKey;
 std::string caCert, clientCert, clientKey;
 int keepalive;
 int keepalive;
 bool SetRetainFlag;
 bool SetRetainFlag;
@@ -205,7 +205,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
 
 
 
 
 bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
 bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
-        std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
+        std::string _maintopic, std::string _domoticz_in_topic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
         std::string _cacertfilename, std::string _clientcertfilename, std::string _clientkeyfilename, 
         std::string _cacertfilename, std::string _clientcertfilename, std::string _clientkeyfilename, 
                     int _keepalive, bool _SetRetainFlag, void *_callbackOnConnected) {
                     int _keepalive, bool _SetRetainFlag, void *_callbackOnConnected) {
     if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0)) 
     if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0)) 
@@ -222,6 +222,7 @@ bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us
     keepalive = _keepalive;
     keepalive = _keepalive;
     SetRetainFlag = _SetRetainFlag;
     SetRetainFlag = _SetRetainFlag;
     maintopic = _maintopic;
     maintopic = _maintopic;
+    domoticz_in_topic = _domoticz_in_topic;
     callbackOnConnected = ( void (*)(std::string, bool) )(_callbackOnConnected);
     callbackOnConnected = ( void (*)(std::string, bool) )(_callbackOnConnected);
 
 
     if (_clientcertfilename.length() && _clientkeyfilename.length()){
     if (_clientcertfilename.length() && _clientkeyfilename.length()){

+ 1 - 1
code/components/jomjol_mqtt/interface_mqtt.h

@@ -10,7 +10,7 @@
 #include <functional>
 #include <functional>
 
 
 bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
 bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
-                    std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
+                    std::string _maintopic, std::string _domoticz_in_topic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
                     std::string _cacertfilename, std::string _clientcertfilename, std::string _clientkeyfilename, 
                     std::string _cacertfilename, std::string _clientcertfilename, std::string _clientkeyfilename, 
                     int _keepalive, bool SetRetainFlag, void *callbackOnConnected);
                     int _keepalive, bool SetRetainFlag, void *callbackOnConnected);
 int MQTT_Init();
 int MQTT_Init();

+ 7 - 1
code/components/jomjol_mqtt/server_mqtt.cpp

@@ -32,10 +32,11 @@ std::string rateUnit = "Unit/Minute";
 float roundInterval; // Minutes
 float roundInterval; // Minutes
 int keepAlive = 0; // Seconds
 int keepAlive = 0; // Seconds
 bool retainFlag;
 bool retainFlag;
-static std::string maintopic;
+static std::string maintopic, domoticzintopic;
 bool sendingOf_DiscoveryAndStaticTopics_scheduled = true; // Set it to true to make sure it gets sent at least once after startup
 bool sendingOf_DiscoveryAndStaticTopics_scheduled = true; // Set it to true to make sure it gets sent at least once after startup
 
 
 
 
+
 void mqttServer_setParameter(std::vector<NumberPost*>* _NUMBERS, int _keepAlive, float _roundInterval) {
 void mqttServer_setParameter(std::vector<NumberPost*>* _NUMBERS, int _keepAlive, float _roundInterval) {
     NUMBERS = _NUMBERS;
     NUMBERS = _NUMBERS;
     keepAlive = _keepAlive;
     keepAlive = _keepAlive;
@@ -367,4 +368,9 @@ std::string mqttServer_getMainTopic() {
     return maintopic;
     return maintopic;
 }
 }
 
 
+void mqttServer_setDmoticzInTopic( std::string _domoticzintopic) {
+    domoticzintopic = _domoticzintopic;
+}
+
+
 #endif //ENABLE_MQTT
 #endif //ENABLE_MQTT

+ 3 - 0
code/components/jomjol_mqtt/server_mqtt.h

@@ -12,6 +12,9 @@ void mqttServer_setParameter(std::vector<NumberPost*>* _NUMBERS, int interval, f
 void mqttServer_setMeterType(std::string meterType, std::string valueUnit, std::string timeUnit,std::string rateUnit);
 void mqttServer_setMeterType(std::string meterType, std::string valueUnit, std::string timeUnit,std::string rateUnit);
 void setMqtt_Server_Retain(bool SetRetainFlag);
 void setMqtt_Server_Retain(bool SetRetainFlag);
 void mqttServer_setMainTopic( std::string maintopic);
 void mqttServer_setMainTopic( std::string maintopic);
+void mqttServer_setDmoticzInTopic( std::string domoticzintopic);
+
+
 std::string mqttServer_getMainTopic();
 std::string mqttServer_getMainTopic();
 
 
 void register_server_mqtt_uri(httpd_handle_t server);
 void register_server_mqtt_uri(httpd_handle_t server);

+ 6 - 0
param-docs/parameter-pages/MQTT/DomoticzTopicIn.md

@@ -0,0 +1,6 @@
+# Parameter `DomoticzTopicIn`
+Default Value: `domoticz/in`
+
+Domoticz "in" topic as configured on the "MQTT Client Gateway" setup page on the Domoticz system. Used to publish counter/s value/s.
+
+Parameter &lt;NUMBER&gt;.DomoticzIDX is required (see below).

+ 4 - 0
param-docs/parameter-pages/MQTT/NUMBER.DomoticzIDX.md

@@ -0,0 +1,4 @@
+# Parameter `<NUMBER>.DomoticzIDX`
+Default Value: `0`
+
+The Idx number for the counter device. Can be obtained from the devices setup page on the Domoticz system.

+ 2 - 0
sd-card/config/config.ini

@@ -87,6 +87,8 @@ HomeassistantDiscovery = false
 ;CACert = /config/certs/RootCA.pem
 ;CACert = /config/certs/RootCA.pem
 ;ClientCert = /config/certs/client.pem.crt
 ;ClientCert = /config/certs/client.pem.crt
 ;ClientKey = /config/certs/client.pem.key
 ;ClientKey = /config/certs/client.pem.key
+;DomoticzTopicIn = domoticz/in
+;main.DomoticzIDX = 0
 
 
 ;[InfluxDB]
 ;[InfluxDB]
 ;Uri = undefined
 ;Uri = undefined

+ 90 - 1
sd-card/html/edit_config_template.html

@@ -1178,6 +1178,36 @@
 			<td>$TOOLTIP_MQTT_MeterType</td>
 			<td>$TOOLTIP_MQTT_MeterType</td>
 		</tr>
 		</tr>
 
 
+		<tr class="MQTTItem">
+			<td class="indent1">
+				<input type="checkbox" id="MQTT_DomoticzTopicIn_enabled" value="1"  onclick = 'InvertEnableItem("MQTT", "DomoticzTopicIn")' unchecked >
+				<label for=MQTT_DomoticzTopicIn_enabled><class id="MQTT_DomoticzTopicIn_text" style="color:black;">Domoticz "in" topic</class></label>
+			</td>
+			<td>
+				<input type="text" id="MQTT_DomoticzTopicIn_value1">
+			</td>
+			<td>$TOOLTIP_MQTT_DomoticzTopicIn</td>
+		</tr>
+		
+		<tr class="MQTTItem" style="margin-top:12px">
+			<td class="indent1" style="padding-top:25px" colspan="3">
+				<b>Parameter per number sequence:</b>
+                <select
+					style="font-weight: bold; margin-left:17px" id="NumbersMQTTIdx_value1" onchange="numberMQTTIdxChanged()">
+                </select>
+			</td>
+		</tr>
+		<tr class="MQTTItem">
+			<td class="indent2">
+				<input type="checkbox" id="MQTT_DomoticzIDX_enabled" value="1"  onclick = 'InvertEnableItem("MQTT", "DomoticzIDX")' unchecked >
+				<label for=MQTT_DomoticzIDX_enabled><class id="MQTT_DomoticzIDX_text" style="color:black;">Domoticz Counter Idx:</class></label>
+			</td>
+			<td>
+				<input type="text" id="MQTT_DomoticzIDX_value1">
+			</td>
+			<td>$TOOLTIP_MQTT_NUMBER.DomoticzIDX</td>
+		</tr>
+
 		
 		
 		<!------------- INFLUXDB v1 ------------------>
 		<!------------- INFLUXDB v1 ------------------>
 		<tr style="border-bottom: 2px solid lightgray;">
 		<tr style="border-bottom: 2px solid lightgray;">
@@ -2120,6 +2150,7 @@ function LoadConfigNeu() {
     UpdateInput();
     UpdateInput();
     var sel = document.getElementById("Numbers_value1");
     var sel = document.getElementById("Numbers_value1");
     UpdateInputIndividual(sel);
     UpdateInputIndividual(sel);
+	
     UpdateExpertModus();
     UpdateExpertModus();
     UpdateTooltipModus();	
     UpdateTooltipModus();	
     document.getElementById("divall").style.display = ''; 
     document.getElementById("divall").style.display = ''; 
@@ -2162,6 +2193,11 @@ function InitIndivParameter() {
         _indexInfluxv1.remove(0);
         _indexInfluxv1.remove(0);
     }
     }
 
 
+    var _indexMQTTIdx = document.getElementById("NumbersMQTTIdx_value1");
+    while (_indexMQTTIdx.length) {
+        _indexMQTTIdx.remove(0);
+    }	
+
     for (var i = 0; i < NUMBERS.length; ++i) {
     for (var i = 0; i < NUMBERS.length; ++i) {
         var option = document.createElement("option");
         var option = document.createElement("option");
         option.text = NUMBERS[i]["name"];
         option.text = NUMBERS[i]["name"];
@@ -2177,11 +2213,17 @@ function InitIndivParameter() {
         optionInfluxv1.text = NUMBERS[i]["name"];
         optionInfluxv1.text = NUMBERS[i]["name"];
         optionInfluxv1.value = i;
         optionInfluxv1.value = i;
         _indexInfluxv1.add(optionInfluxv1);
         _indexInfluxv1.add(optionInfluxv1);
+
+		var optionMQTTIdx = document.createElement("option");
+        optionMQTTIdx.text = NUMBERS[i]["name"];
+        optionMQTTIdx.value = i;
+        _indexMQTTIdx.add(optionMQTTIdx);
     }
     }
 	
 	
     _index.selectedIndex = 0; 
     _index.selectedIndex = 0; 
     _indexInflux.selectedIndex = 0;
     _indexInflux.selectedIndex = 0;
     _indexInfluxv1.selectedIndex = 0;
     _indexInfluxv1.selectedIndex = 0;
+	_indexMQTTIdx.selectedIndex = 0;
 }
 }
 
 
 function UpdateInputIndividual(sel) {
 function UpdateInputIndividual(sel) {
@@ -2200,6 +2242,7 @@ function UpdateInputIndividual(sel) {
         ReadParameter(param, "InfluxDBv2", "Field", true, NUNBERSAkt);
         ReadParameter(param, "InfluxDBv2", "Field", true, NUNBERSAkt);
         ReadParameter(param, "InfluxDB", "Measurement", true, NUNBERSAkt);
         ReadParameter(param, "InfluxDB", "Measurement", true, NUNBERSAkt);
         ReadParameter(param, "InfluxDBv2", "Measurement", true, NUNBERSAkt);
         ReadParameter(param, "InfluxDBv2", "Measurement", true, NUNBERSAkt);
+        ReadParameter(param, "MQTT", "DomoticzIDX", true, NUNBERSAkt);
     }
     }
 
 
     // var sel = document.getElementById("Numbers_value1");
     // var sel = document.getElementById("Numbers_value1");
@@ -2218,6 +2261,8 @@ function UpdateInputIndividual(sel) {
     WriteParameter(param, category, "InfluxDBv2", "Field", true, NUNBERSAkt);
     WriteParameter(param, category, "InfluxDBv2", "Field", true, NUNBERSAkt);
     WriteParameter(param, category, "InfluxDB", "Measurement", true, NUNBERSAkt);
     WriteParameter(param, category, "InfluxDB", "Measurement", true, NUNBERSAkt);
     WriteParameter(param, category, "InfluxDBv2", "Measurement", true, NUNBERSAkt);
     WriteParameter(param, category, "InfluxDBv2", "Measurement", true, NUNBERSAkt);
+    WriteParameter(param, category, "MQTT", "DomoticzIDX", true, NUNBERSAkt);
+	
 }
 }
 
 
 function UpdateInput() {
 function UpdateInput() {
@@ -2306,6 +2351,7 @@ function UpdateInput() {
     WriteParameter(param, category, "MQTT", "CACert", true);
     WriteParameter(param, category, "MQTT", "CACert", true);
     WriteParameter(param, category, "MQTT", "ClientCert", true);
     WriteParameter(param, category, "MQTT", "ClientCert", true);
     WriteParameter(param, category, "MQTT", "ClientKey", true);
     WriteParameter(param, category, "MQTT", "ClientKey", true);
+    WriteParameter(param, category, "MQTT", "DomoticzTopicIn", true);
     
     
     WriteParameter(param, category, "InfluxDB", "Uri", true);	
     WriteParameter(param, category, "InfluxDB", "Uri", true);	
     WriteParameter(param, category, "InfluxDB", "Database", true);	
     WriteParameter(param, category, "InfluxDB", "Database", true);	
@@ -2473,6 +2519,7 @@ function ReadParameterAll() {
     ReadParameter(param, "MQTT", "CACert", true);
     ReadParameter(param, "MQTT", "CACert", true);
     ReadParameter(param, "MQTT", "ClientCert", true);
     ReadParameter(param, "MQTT", "ClientCert", true);
     ReadParameter(param, "MQTT", "ClientKey", true);
     ReadParameter(param, "MQTT", "ClientKey", true);
+    ReadParameter(param, "MQTT", "DomoticzTopicIn", true);
 
 
     ReadParameter(param, "InfluxDB", "Uri", true);
     ReadParameter(param, "InfluxDB", "Uri", true);
     ReadParameter(param, "InfluxDB", "Database", true);
     ReadParameter(param, "InfluxDB", "Database", true);
@@ -2527,7 +2574,7 @@ function ReadParameterAll() {
 
 
     var sel = document.getElementById("Numbers_value1");
     var sel = document.getElementById("Numbers_value1");
     UpdateInputIndividual(sel);
     UpdateInputIndividual(sel);
-    
+
     // FormatDecimalValue(param, "PostProcessing", "MaxRateValue");
     // FormatDecimalValue(param, "PostProcessing", "MaxRateValue");
 }
 }
 
 
@@ -2871,6 +2918,38 @@ function numberChanged() {
     if (_selInflux.selectedIndex != _neu) {
     if (_selInflux.selectedIndex != _neu) {
         _selInflux.selectedIndex = _neu
         _selInflux.selectedIndex = _neu
     }
     }
+
+    var _sel3 = document.getElementById("NumbersInfluxDB_value1");
+    if (_sel3.selectedIndex != _neu) {
+        _sel3.selectedIndex = _neu
+    }
+
+	var _sel4 = document.getElementById("NumbersMQTTIdx_value1");
+    if (_sel4.selectedIndex != _neu) {
+        _sel4.selectedIndex = _neu
+    }
+
+}
+
+function numberMQTTIdxChanged() {
+    var sel = document.getElementById("NumbersMQTTIdx_value1");
+    _neu = sel.selectedIndex;
+    UpdateInputIndividual(sel);
+
+	var _sel2 = document.getElementById("Numbers_value1");
+    if (_sel2.selectedIndex != _neu) {
+        _sel2.selectedIndex = _neu
+    }
+
+    var _sel3 = document.getElementById("NumbersInfluxDB_value1");
+    if (_sel3.selectedIndex != _neu) {
+        _sel3.selectedIndex = _neu
+    }
+
+    var _sel4 = document.getElementById("NumbersInfluxDBv2_value1");
+    if (_sel4.selectedIndex != _neu) {
+        _sel4.selectedIndex = _neu
+    }
 }
 }
     
     
 function numberInfluxDBv2Changed() {
 function numberInfluxDBv2Changed() {
@@ -2887,6 +2966,11 @@ function numberInfluxDBv2Changed() {
     if (_sel3.selectedIndex != _neu) {
     if (_sel3.selectedIndex != _neu) {
         _sel3.selectedIndex = _neu
         _sel3.selectedIndex = _neu
     }
     }
+
+    var _sel4 = document.getElementById("NumbersMQTTIdx_value1");
+    if (_sel4.selectedIndex != _neu) {
+        _sel4.selectedIndex = _neu
+    }
 }
 }
 
 
 function numberInfluxDBChanged() {
 function numberInfluxDBChanged() {
@@ -2903,6 +2987,11 @@ function numberInfluxDBChanged() {
     if (_sel3.selectedIndex != _neu) {
     if (_sel3.selectedIndex != _neu) {
         _sel3.selectedIndex = _neu
         _sel3.selectedIndex = _neu
     }
     }
+
+	var _sel4 = document.getElementById("NumbersMQTTIdx_value1");
+    if (_sel4.selectedIndex != _neu) {
+        _sel4.selectedIndex = _neu
+    }
 }
 }
 
 
 function getParameterByName(name, url = window.location.href) {
 function getParameterByName(name, url = window.location.href) {

+ 2 - 0
sd-card/html/readconfigparam.js

@@ -198,6 +198,8 @@ function ParseConfig() {
     ParamAddValue(param, catname, "user");
     ParamAddValue(param, catname, "user");
     ParamAddValue(param, catname, "password");
     ParamAddValue(param, catname, "password");
     ParamAddValue(param, catname, "RetainMessages");
     ParamAddValue(param, catname, "RetainMessages");
+    ParamAddValue(param, catname, "DomoticzTopicIn");
+    ParamAddValue(param, catname, "DomoticzIDX", 1, true);
     ParamAddValue(param, catname, "HomeassistantDiscovery");
     ParamAddValue(param, catname, "HomeassistantDiscovery");
     ParamAddValue(param, catname, "MeterType");
     ParamAddValue(param, catname, "MeterType");
     ParamAddValue(param, catname, "CACert");
     ParamAddValue(param, catname, "CACert");