Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Domoticz MQTT integration #3359

Merged
merged 17 commits into from
Dec 1, 2024
Merged
2 changes: 2 additions & 0 deletions code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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?
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 MeasurementV1; // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1

Expand Down
70 changes: 55 additions & 15 deletions code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void ClassFlowMQTT::SetInitialParameter(void)
ListFlowControll = NULL;
disabled = false;
keepAlive = 25*60;
domoticzintopic = "";
}

ClassFlowMQTT::ClassFlowMQTT()
Expand Down Expand Up @@ -105,43 +106,44 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(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];
}
if ((toUpper(splitted[0]) == "CLIENTCERT") && (splitted.size() > 1))
if ((toUpper(_param) == "CLIENTCERT") && (splitted.size() > 1))
{
this->clientCertFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "CLIENTKEY") && (splitted.size() > 1))
if ((toUpper(_param) == "CLIENTKEY") && (splitted.size() > 1))
{
this->clientKeyFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1))
if ((toUpper(_param) == "USER") && (splitted.size() > 1))
{
this->user = splitted[1];
}
if ((toUpper(splitted[0]) == "PASSWORD") && (splitted.size() > 1))
if ((toUpper(_param) == "PASSWORD") && (splitted.size() > 1))
{
this->password = splitted[1];
}
if ((toUpper(splitted[0]) == "URI") && (splitted.size() > 1))
if ((toUpper(_param) == "URI") && (splitted.size() > 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") {
SetRetainFlag = true;
setMqtt_Server_Retain(SetRetainFlag);
}
}
if ((toUpper(splitted[0]) == "HOMEASSISTANTDISCOVERY") && (splitted.size() > 1))
if ((toUpper(_param) == "HOMEASSISTANTDISCOVERY") && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "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
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") {
Expand Down Expand Up @@ -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];
}

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];
}

if (((toUpper(_param) == "DOMOTICZTOPICIN")) && (splitted.size() > 1))
{
this->domoticzintopic = splitted[1];
}

if (((toUpper(_param) == "DOMOTICZIDX")) && (splitted.size() > 1))
{
handleIdx(splitted[0], splitted[1]);
}

}

/* Note:
Expand All @@ -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() */

mqttServer_setMainTopic(maintopic);
mqttServer_setDmoticzInTopic(domoticzintopic);

return true;
}
Expand All @@ -210,7 +224,7 @@ bool ClassFlowMQTT::Start(float AutoInterval)

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,
keepAlive, SetRetainFlag, (void *)&GotConnected);

Expand All @@ -235,6 +249,8 @@ bool ClassFlowMQTT::doFlow(string zwtime)
std::string resultchangabs = "";
string zw = "";
string namenumber = "";
string domoticzpayload = "";
string DomoticzIdx = "";
int qos = 1;

/* Send the the Homeassistant Discovery and the Static Topics in case they where scheduled */
Expand All @@ -258,16 +274,20 @@ bool ClassFlowMQTT::doFlow(string zwtime)
resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
resulttimestamp = (*NUMBERS)[i]->timeStamp;

DomoticzIdx = (*NUMBERS)[i]->DomoticzIdx;
domoticzpayload = "{\"command\":\"udevice\",\"idx\":" + DomoticzIdx + ",\"svalue\":\""+ result + "\"}";

namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = maintopic + "/";
else
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);

if (resulterror.length() > 0)
success |= MQTTPublish(namenumber + "error", resulterror, qos, SetRetainFlag);

Expand Down Expand Up @@ -325,6 +345,26 @@ bool ClassFlowMQTT::doFlow(string zwtime)

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
4 changes: 2 additions & 2 deletions code/components/jomjol_flowcontroll/ClassFlowMQTT.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class ClassFlowMQTT :
bool SetRetainFlag;
int keepAlive; // Seconds
float roundInterval; // Minutes

std::string maintopic;
std::string maintopic, domoticzintopic;
void SetInitialParameter(void);
void handleIdx(string _decsep, string _value);

public:
ClassFlowMQTT();
Expand Down
5 changes: 3 additions & 2 deletions code/components/jomjol_mqtt/interface_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bool mqtt_initialized = false;
bool mqtt_connected = false;

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;
int keepalive;
bool SetRetainFlag;
Expand Down Expand Up @@ -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,
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,
int _keepalive, bool _SetRetainFlag, void *_callbackOnConnected) {
if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0))
Expand All @@ -222,6 +222,7 @@ bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us
keepalive = _keepalive;
SetRetainFlag = _SetRetainFlag;
maintopic = _maintopic;
domoticz_in_topic = _domoticz_in_topic;
callbackOnConnected = ( void (*)(std::string, bool) )(_callbackOnConnected);

if (_clientcertfilename.length() && _clientkeyfilename.length()){
Expand Down
2 changes: 1 addition & 1 deletion code/components/jomjol_mqtt/interface_mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <functional>

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,
int _keepalive, bool SetRetainFlag, void *callbackOnConnected);
int MQTT_Init();
Expand Down
8 changes: 7 additions & 1 deletion code/components/jomjol_mqtt/server_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ std::string rateUnit = "Unit/Minute";
float roundInterval; // Minutes
int keepAlive = 0; // Seconds
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



void mqttServer_setParameter(std::vector<NumberPost*>* _NUMBERS, int _keepAlive, float _roundInterval) {
NUMBERS = _NUMBERS;
keepAlive = _keepAlive;
Expand Down Expand Up @@ -355,4 +356,9 @@ std::string mqttServer_getMainTopic() {
return maintopic;
}

void mqttServer_setDmoticzInTopic( std::string _domoticzintopic) {
domoticzintopic = _domoticzintopic;
}


#endif //ENABLE_MQTT
3 changes: 3 additions & 0 deletions code/components/jomjol_mqtt/server_mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 setMqtt_Server_Retain(bool SetRetainFlag);
void mqttServer_setMainTopic( std::string maintopic);
void mqttServer_setDmoticzInTopic( std::string domoticzintopic);


std::string mqttServer_getMainTopic();

void register_server_mqtt_uri(httpd_handle_t server);
Expand Down
6 changes: 6 additions & 0 deletions param-docs/parameter-pages/MQTT/DomoticzTopicIn.md
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions param-docs/parameter-pages/MQTT/NUMBER.DomoticzIDX.md
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions sd-card/config/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ HomeassistantDiscovery = false
;CACert = /config/certs/RootCA.pem
;ClientCert = /config/certs/client.pem.crt
;ClientKey = /config/certs/client.pem.key
;DomoticzTopicIn = domoticz/in
;main.DomoticzIDX = 0

;[InfluxDB]
;Uri = undefined
Expand Down
Loading