Created
October 22, 2024 13:37
-
-
Save kulheimzb/cfe8c21214c80cdab579c7719bc56136 to your computer and use it in GitHub Desktop.
Connecting Tecomat Foxtrot to Home Assistant via MQTT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
VAR_GLOBAL CONSTANT | |
MAX_SENSORS : USINT := 17; | |
MAX_STRING : USINT := 20; | |
END_VAR | |
TYPE | |
T_SENSOR : STRUCT | |
name : string [30]; | |
val : STRING[MAX_STRING]; // aktualni STRING hodnota | |
preVal : STRING[MAX_STRING]; // predchozi STRING hodnota | |
END_STRUCT; | |
T_SENSORS : ARRAY [1..MAX_SENSORS] OF T_SENSOR; | |
END_TYPE | |
PROGRAM prgMqtt | |
VAR_INPUT | |
//sendcomPub : BOOL R_EDGE := 0; | |
//subRqSub : BOOL R_EDGE := 0; | |
END_VAR | |
VAR | |
connect : bool := true; | |
MQTTPub : fbMQTTPublisher; | |
MQTTSub : fbMQTTSubscriber; | |
sent : BOOL := false; // zda bylo odeslano | |
brokerIPaddr : STRING := 'x.x.x.x'; | |
remotePort : UINT := 1883; | |
localPortPub : UINT := 60000; | |
localPortSub : UINT := 50000; | |
loginName : string[32] := ''; | |
loginPass : string[32] := ''; | |
comparamPub : T_MQTT_COM_PARAM := (pRetain := true, qos := 1, dup := false, clean := false); | |
comparamSub : T_MQTT_COM_PARAM; | |
// na prvnim miste je zdroj dat | |
topicPub : string[80] := 'xxxxx'; | |
topicSub : string[80] := 'ha/xxxxx/#'; | |
dataPub : string[255] := ''; | |
dataSub : string[255] := ''; | |
// aktualni sensor | |
i : USINT := 1; | |
// predchozi hodnota pro temperature senzory | |
tempsensors : ARRAY [1..8] OF REAL := [-99,-99,-99,-99,-99,-99,-99,-99]; | |
// string hodnota senzoru | |
sensors : T_SENSORS := [// pocet teplomeru musi souhlasit s tempsensors | |
(name:= 'tempKotel', preVal:='-'), | |
(name:= 'tempObyvC', preVal:='-'), | |
(name:= 'tempP24', preVal:='-'), | |
(name:= 'tempP20', preVal:='-'), | |
(name:= 'tempP17', preVal:='-'), | |
(name:= 'tempHost', preVal:='-'), | |
(name:= 'tempGaraz', preVal:='-'), | |
(name:= 'tempKoupelna2', preVal:='-'), | |
// konec teplot | |
(name:= 'Cerpadlo1', preVal:='-'), | |
(name:= 'Cerpadlo2', preVal:='-'), | |
(name:= 'CerpadloTopna', preVal:='-'), | |
(name:= 'VztTopeni', preVal:='-'), | |
(name:= 'Kotel', preVal:='-'), | |
(name:= 'HDO', preVal:='-'), | |
(name:= 'HJ306_1stupen', preVal:='-'), | |
(name:= 'VztBypass', preVal:='-'), | |
(name:= 'VztMode', preVal:='-') | |
]; | |
END_VAR | |
VAR_TEMP | |
dateTimeRTC : DATE_AND_TIME; | |
processValue : BOOL; | |
bval : BOOL; // aktualni BOOL hodnota senzoru | |
rval : REAL; // aktualni REAL hodnota senzoru | |
sval : STRING[MAX_STRING]; // aktualni STRING hodnota senzoru | |
preRval : REAL; //predchozi REAL hodnota | |
END_VAR | |
// presunout do one time init | |
MQTTPub(chanCode := ETH1_UNI0, | |
brokerIP := STRING_TO_IPADR(brokerIPaddr), | |
brokerPort := remotePort, | |
localPort := localPortPub, | |
connect := connect, | |
//keepAlive := keepAlive, | |
//keepAliveInterval := keepAliveInterval, | |
//pingInterval := pingInterval, | |
//connTimeOut := connTimeOut, | |
comparam := comparamPub, | |
//loginName := loginName, | |
//loginPass := loginPass, | |
dataTxt := dataPub, | |
topicTxt := topicPub, | |
//sendCom := sendCom, | |
); | |
IF MQTTPub.connected_to_broker THEN | |
// zopakuj poslani minule hodnoty | |
IF MQTTPub.err AND sent THEN | |
MQTTPub.sendcom := true; | |
END_IF; | |
// posun na další hodnotu | |
IF MQTTPub.ok THEN | |
sensors[i].preVal:= sensors[i].val; | |
i := i+1; | |
IF i > MAX_SENSORS THEN i := 1; END_IF; | |
sent:= false; | |
END_IF; | |
// posli pripadnou dalsi hodnotu | |
IF not MQTTPub.busy THEN | |
// nacteni aktualnich hodnot | |
CASE i OF | |
// REAL_TO_STRINGF (nový doplnit níže do CASE i OF ...) | |
1 : rval := tempKotel; | |
2 : rval := tempObyvC; | |
3 : rval := tempP24; | |
4 : rval := tempP20; | |
5 : rval := tempP17; | |
6 : rval := tempHost; | |
7 : rval := tempGaraz; | |
8 : rval := tempKoupelna2; | |
// BOOL_TO_STRING | |
9 : bval := Cerpadlo1; | |
10 : bval := Cerpadlo2; | |
11 : bval := CerpadloTopna; | |
12 : bval := VztTopeni; | |
13 : bval := Kotel; | |
14 : bval := HDO; | |
15 : bval := HJ306_1stupen; | |
// STRING | |
16 : IF VztBypass>=100 THEN sval:='1'; ELSE sval:='0'; END_IF; | |
17 : sval := VztMode; | |
END_CASE; | |
// nastav REAL jako STRING do array sensors | |
processValue := true; | |
CASE i OF | |
1..8 : | |
// zamezeni neustále zmenì hodnot senzoru (I. radek), vysledek je II. radek | |
// -99->22.1->22.1->22.2->22.1->22.2->22.3->22.2->22.3->22.3 | |
// 22.1-> 22.15-> 22.25 | |
// pokud doilo ke zmene | |
IF tempsensors[i] <> rval AND abs(tempsensors[i]- rval)>0.05 THEN | |
IF tempsensors[i] = -99 THEN | |
tempsensors[i] := rval; | |
ELSE | |
preRval := tempsensors[i]; | |
tempsensors[i] := rval; // jako predchozi hodnotu pouzij neupravenou hodnotu | |
//namisto aktualni hodnoty dej prumer predchozi a nove hodnoty | |
rval := (rval + preRval)/2; | |
END_IF; | |
sensors[i].val := REAL_TO_STRINGF(rval,'%.1f'); | |
ELSE | |
// neni zmena | |
processValue := false; | |
END_IF; | |
9..15 : sensors[i].val := BOOL_TO_STRING(bval); | |
16..17 : sensors[i].val := sval; | |
END_CASE; | |
//dataPub := DT_TO_STRING(GetRTC()); | |
IF processValue and sensors[i].val<>sensors[i].preVal THEN | |
topicPub := sensors[i].name; | |
dataPub := sensors[i].val; | |
MQTTPub.sendcom := true; | |
sent:= true; | |
END_IF; | |
END_IF; // not busy | |
END_IF; // connected_to_broker | |
(* IF MQTTSub.connected_to_broker THEN | |
MQTTSub.subRq := 1; | |
END_IF; | |
MQTTSub(chanCode := ETH1_UNI2, | |
brokerIP := STRING_TO_IPADR(brokerIPaddr), | |
brokerPort := remotePort, | |
localPort := localPortSub, | |
connect := connect, | |
//keepAlive := keepAliveSubs, | |
//keepAliveInterval := keepAliveIntervalSubs, | |
//pingInterval := pingInterval, | |
//connTimeOut := connTimeOutSubs, | |
comparam := comparamSub, | |
//loginName := loginName, | |
//loginPass := loginPass, | |
topicTxt := topicSub, | |
//subRq := subRqSub | |
); | |
IF MQTTSub.connected_to_broker and MQTTSub.dataRec THEN | |
// doplnit co udelat po restartu ha - nic, broker posle klientovi ha znovu vsechny retain | |
// po restartu foxtrotu? | |
// Detekovat vypadek brokera: foxtrot by mel publikovat aktualni cas kazdou vterinu. | |
// https://community.home-assistant.io/t/alarm-if-mqtt-broker-goes-down/188826/5 | |
// nenu potreba, mosquitto lze nastavit pro zachovani retain pri startu | |
// autosave_interval 1, autosave_on_changes true, persistence true, persistence_location /temp/ | |
// TODO: zajistit, aby foxtrot opakoval poslani zpravy dokud neni potvrzeno prijeti | |
END_IF; | |
*) | |
END_PROGRAM |
Dobrý den, bude to fungovat i na TČ Acond?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CP1000 limitations:
Kvůli tomuto omezení rozjet pouze publisher. Aby fungoval zároveň publisher i subscriber v Foxtrot1, tak každý musí mít dedikovaný ETH_UNI, který nesmí být použitý jinde v programu. (Ve Foxtrot2 lze již komunikační kanál vytvořit programově).
Mqtt server Mosqitto:
listener 1883
autosave_interval 1
autosave_on_changes true
persistence true
persistence_location /temp/