diff --git a/docs/FAQ/Howto_adding_a_new_MQTT_subscription.md b/docs/FAQ/Howto_adding_a_new_MQTT_subscription.md index 59112ec..b1d4d15 100644 --- a/docs/FAQ/Howto_adding_a_new_MQTT_subscription.md +++ b/docs/FAQ/Howto_adding_a_new_MQTT_subscription.md @@ -65,6 +65,6 @@ A more in depth implementation can be found in the *InitMqtt* method of every MQ Data : SD_MQTT.CALLBACK_DATA; END_VAR ``` - - Add logic to process the received MQTT message: in this reference project a check is executed if the subscription that triggered the callback method matches the subscription configured in the *MqttInit* method. In that method the subscription topic is automatically concatinated with the function block name. For more in depth details study the *PublishReceived* and *MqttInit* methods of every MQTT function block in the reference project. + - Add logic to process the received MQTT message: in this reference project a check is executed if the subscription that triggered the callback method matches the subscription configured in the *MqttInit* method. In that method the subscription topic is automatically concatenated with the function block name. For more in depth details study the *PublishReceived* and *MqttInit* methods of every MQTT function block in the reference project. diff --git a/docs/FunctionBlocks/FB_OUTPUT_BINARY_MQTT.md b/docs/FunctionBlocks/FB_OUTPUT_BINARY_MQTT.md index a50f6f7..85f9a2b 100644 --- a/docs/FunctionBlocks/FB_OUTPUT_BINARY_MQTT.md +++ b/docs/FunctionBlocks/FB_OUTPUT_BINARY_MQTT.md @@ -32,7 +32,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **Output changes: OUT** | A change is detected on output `OUT`. | `TRUE/FALSE` | 2 | `TRUE` | yes -MQTT publish topic is a concatination of the publish prefix and the function block name. +MQTT publish topic is a concatenation of the publish prefix and the function block name. ### **MQTT subscribe behavior** Requires method call `InitMQTT` to enable MQTT capabilities. diff --git a/docs/FunctionBlocks/FB_OUTPUT_COVER_MQTT.md b/docs/FunctionBlocks/FB_OUTPUT_COVER_MQTT.md index 8920009..a2841e3 100644 --- a/docs/FunctionBlocks/FB_OUTPUT_COVER_MQTT.md +++ b/docs/FunctionBlocks/FB_OUTPUT_COVER_MQTT.md @@ -49,8 +49,12 @@ Requires method call `InitMQTT` to enable MQTT capabilities. | Event | Description | MQTT payload | QoS | Retain flag | Published on startup | | :---------------------- | :------------------------------------ | :----------- | :----------------------------------- | :---------- | :------------------- | | **Cover reaches position** | Cover reaches a open or closed position | `OPEN` or `CLOSED` | 2 | `TRUE` | no | +| Event | Description | MQTT payload | QoS | Retain flag | Published on startup | +| :---------------------- | :------------------------------------ | :----------- | :----------------------------------- | :---------- | :------------------- | +| **Cover moves** | Cover moves | `OPENING` or `CLOSING` | 2 | `TRUE` | no | +| **Cover stops** | Cover stopped moving without reaching fully open or closed position | `STOPPED` | 2 | `TRUE` | no | -MQTT publish topic is a concatination of the publish prefix and the function block name. +MQTT publish topic is a concatenation of the publish prefix and the function block name. ### **MQTT subscribe behavior** diff --git a/docs/FunctionBlocks/FB_RS485_DUCO_DUCOBOX_MQTT.md b/docs/FunctionBlocks/FB_RS485_DUCO_DUCOBOX_MQTT.md index 31b605e..16902c6 100644 --- a/docs/FunctionBlocks/FB_RS485_DUCO_DUCOBOX_MQTT.md +++ b/docs/FunctionBlocks/FB_RS485_DUCO_DUCOBOX_MQTT.md @@ -34,7 +34,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **register is polled** | a modbus register is polled | int value | 2 | `FALSE` | no -MQTT publish topic is a concatination of the publish prefix and the function block name, the node numer and a register number. For example: +MQTT publish topic is a concatenation of the publish prefix and the function block name, the node numer and a register number. For example: `Devices/PLC/House/Out/RS485/FB_RS485_DUCO_DUCOBOX_MQTT/1/read/0` @@ -50,7 +50,7 @@ Commands are executed by the FB if the topic `MQTTSubscribeTopic` matches the MQ MQTT subscription topic is a concatenation of the subscribe prefix variable, function block name, node number and register number. For example, topic `Devices/PLC/House/In/RS485/FB_RS485_DUCO_DUCOBOX_MQTT/1/write/0` with payload `30` will set the 'Target value (%)' parameter for node 1 (which in this case represents the entire system). Go through the DUCO modbus register documentation linked above for a deeper understanding. -Upon a succesfull write operation the received payload will be published on the 'Out' topic. Continuing with the example above this will result in a payload `30` to be published on topic `Devices/PLC/House/Out/RS485/FB_RS485_DUCO_DUCOBOX_MQTT/1/write/0`. +Upon a successful write operation the received payload will be published on the 'Out' topic. Continuing with the example above this will result in a payload `30` to be published on topic `Devices/PLC/House/Out/RS485/FB_RS485_DUCO_DUCOBOX_MQTT/1/write/0`. ### **Code example** diff --git a/docs/FunctionBlocks/FB_RS485_EASTRON_SDM220_MQTT.md b/docs/FunctionBlocks/FB_RS485_EASTRON_SDM220_MQTT.md index 9d99da2..52fa4c6 100644 --- a/docs/FunctionBlocks/FB_RS485_EASTRON_SDM220_MQTT.md +++ b/docs/FunctionBlocks/FB_RS485_EASTRON_SDM220_MQTT.md @@ -59,7 +59,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **output is updated** | the output is updated. | real value | 2 | `FALSE` | no -MQTT publish topic is a concatination of the publish prefix and the function block name and a unique value: +MQTT publish topic is a concatenation of the publish prefix and the function block name and a unique value: | output | MQTT topc suffic | Unit | |:-------------|:------------------|:------------------| | VOLTAGE | `/VOLT` | Volts diff --git a/docs/FunctionBlocks/FB_RS485_EASTRON_SDM_POWER_MQTT.md b/docs/FunctionBlocks/FB_RS485_EASTRON_SDM_POWER_MQTT.md index f5a37b2..5439a78 100644 --- a/docs/FunctionBlocks/FB_RS485_EASTRON_SDM_POWER_MQTT.md +++ b/docs/FunctionBlocks/FB_RS485_EASTRON_SDM_POWER_MQTT.md @@ -41,7 +41,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **output is updated** | the output is updated. | real value | 2 | `FALSE` | no -MQTT publish topic is a concatination of the publish prefix and the function block name and a unique value: +MQTT publish topic is a concatenation of the publish prefix and the function block name and a unique value: | output | MQTT topc suffic | Unit | |:-------------|:------------------|:------------------| | ACTIVEPOWER | `/ACTP` | Watts diff --git a/docs/FunctionBlocks/FB_RS485_ESERA_OWD_MQTT.md b/docs/FunctionBlocks/FB_RS485_ESERA_OWD_MQTT.md index 9177770..a839eb9 100644 --- a/docs/FunctionBlocks/FB_RS485_ESERA_OWD_MQTT.md +++ b/docs/FunctionBlocks/FB_RS485_ESERA_OWD_MQTT.md @@ -30,11 +30,11 @@ Requires method call `InitMQTT` to enable MQTT capabilities. |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **sensor data is received** | temperature, humidity, etc readings received. | real value | 2 | `FALSE` | no -MQTT publish topic is a concatination of the publish prefix and the function block name, the OWD numer and a unique sensor value. For example: +MQTT publish topic is a concatenation of the publish prefix and the function block name, the OWD number and a unique sensor value. For example: `Devices/PLC/House/Out/RS485/FB_RS485_ESERA_1WIRE_GATEWAY_MQTT_HOME/OWD/1/TEMP` -Naturally `/TEMP` will only be ommited by the OWD if the physical sensor exposes it. +Naturally `/TEMP` will only be omitted by the OWD if the physical sensor exposes it. | output | MQTT topc suffic | Unit | |:-------------|:------------------|:------------------| diff --git a/docs/FunctionBlocks/FB_VIRTUAL_BOOL_MQTT.md b/docs/FunctionBlocks/FB_VIRTUAL_BOOL_MQTT.md index 97323cc..3c34543 100644 --- a/docs/FunctionBlocks/FB_VIRTUAL_BOOL_MQTT.md +++ b/docs/FunctionBlocks/FB_VIRTUAL_BOOL_MQTT.md @@ -46,7 +46,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable if |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **input changes: IN** | A change is detected on input `IN`. | `TRUE/FALSE` | configured in method call `InitMQTT` | configured in method call `InitMQTT` | configured in method call `InitMQTT` -MQTT publish topic is a concatination of the publish prefix and the function block name. +MQTT publish topic is a concatenation of the publish prefix and the function block name. ### **MQTT subscribe behavior** Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable is the function block is configured in input mode which will allow the input of a value to the PLC through MQTT which will be exposed on the function block `OUT` output. diff --git a/docs/FunctionBlocks/FB_VIRTUAL_INT_MQTT.md b/docs/FunctionBlocks/FB_VIRTUAL_INT_MQTT.md index d100f80..f14efc3 100644 --- a/docs/FunctionBlocks/FB_VIRTUAL_INT_MQTT.md +++ b/docs/FunctionBlocks/FB_VIRTUAL_INT_MQTT.md @@ -46,7 +46,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable if |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **input changes: IN** | A change is detected on input `IN`. | `TRUE/FALSE` | configured in method call `InitMQTT` | configured in method call `InitMQTT` | configured in method call `InitMQTT` -MQTT publish topic is a concatination of the publish prefix and the function block name. +MQTT publish topic is a concatenation of the publish prefix and the function block name. ### **MQTT subscribe behavior** Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable is the function block is configured in input mode which will allow the input of a value to the PLC through MQTT which will be exposed on the function block `OUT` output. diff --git a/docs/FunctionBlocks/FB_VIRTUAL_REAL_MQTT.md b/docs/FunctionBlocks/FB_VIRTUAL_REAL_MQTT.md index 074796c..657cbbe 100644 --- a/docs/FunctionBlocks/FB_VIRTUAL_REAL_MQTT.md +++ b/docs/FunctionBlocks/FB_VIRTUAL_REAL_MQTT.md @@ -46,7 +46,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable if |:-------------|:------------------|:------------------|:------------------|:--------------------------|:--------------------------| | **input changes: IN** | A change is detected on input `IN`. | `TRUE/FALSE` | configured in method call `InitMQTT` | configured in method call `InitMQTT` | configured in method call `InitMQTT` -MQTT publish topic is a concatination of the publish prefix and the function block name. +MQTT publish topic is a concatenation of the publish prefix and the function block name. ### **MQTT subscribe behavior** Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable is the function block is configured in input mode which will allow the input of a value to the PLC through MQTT which will be exposed on the function block `OUT` output. diff --git a/docs/FunctionBlocks/FB_VIRTUAL_STRING_MQTT.md b/docs/FunctionBlocks/FB_VIRTUAL_STRING_MQTT.md index ad91d08..03a1f63 100644 --- a/docs/FunctionBlocks/FB_VIRTUAL_STRING_MQTT.md +++ b/docs/FunctionBlocks/FB_VIRTUAL_STRING_MQTT.md @@ -52,7 +52,7 @@ Requires method call `InitMQTT` to enable MQTT capabilities. Only applicable if | :-------------------- | :---------------------------------- | :----------- | :----------------------------------- | :----------------------------------- | :----------------------------------- | | **input changes: IN** | A change is detected on input `IN`. | `TRUE/FALSE` | configured in method call `InitMQTT` | configured in method call `InitMQTT` | configured in method call `InitMQTT` | -MQTT publish topic is a concatination of the publish prefix and the function block name. +MQTT publish topic is a concatenation of the publish prefix and the function block name. ### **MQTT subscribe behavior** diff --git a/src/Exports/CodesysV3.export b/src/Exports/CodesysV3.export index 9babb56..baaac1f 100644 --- a/src/Exports/CodesysV3.export +++ b/src/Exports/CodesysV3.export @@ -3055,7 +3055,7 @@ a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc - 638271220549486723 + 638646772895366879 None @@ -3063,372 +3063,532 @@ - 3 + 111 (* Run the timer to not power the motors for to long *) - 4 + 112 Cover_State_Timer(PT:=T_UD); - 5 + 113 Cover_State_Timer.IN:=FALSE; - 6 + 114 + + MU_RTrigger(CLK:=MU); + + + 115 + + MD_RTrigger(CLK:=MD); + + + 116 + + MU_FTrigger(CLK:=MU); + + + 117 + + MD_FTrigger(CLK:=MD); + + + 118 - 7 + 119 - IF NOT(Cover_State_Timer.Q) AND internalUp THEN + IF MU_RTrigger.Q AND InitMqttDone THEN - 8 + 120 pMqttPublishQueue^.AddMessage( - 9 + 121 + + Payload := 'OPENING', + + + 122 + + Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), + + + 123 + + Qos := MQTT.QoS.ExactlyOnce, + + + 124 + + MqttRetain := TRUE + + + 125 + + ); + + + 126 + + END_IF + + + 127 + + + + + 128 + + IF MD_RTrigger.Q AND InitMqttDone THEN + + + 129 + + pMqttPublishQueue^.AddMessage( + + + 130 + + Payload := 'CLOSING', + + + 131 + + Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), + + + 132 + + Qos := MQTT.QoS.ExactlyOnce, + + + 133 + + MqttRetain := TRUE + + + 134 + + ); + + + 135 + + END_IF + + + 136 + + + + + 137 + + IF (MD_FTrigger.Q OR MU_FTrigger.Q) AND Cover_State_Timer.Q AND InitMqttDone THEN + + + 138 + + pMqttPublishQueue^.AddMessage( + + + 139 + + Payload := 'STOPPED', + + + 140 + + Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), + + + 141 + + Qos := MQTT.QoS.ExactlyOnce, + + + 142 + + MqttRetain := TRUE + + + 143 + + ); + + + 144 + + END_IF + + + 145 + + + + + 146 + + + + + 147 + + IF (NOT(Cover_State_Timer.Q) AND internalUp) AND InitMqttDone THEN + + + 148 + + pMqttPublishQueue^.AddMessage( + + + 149 Payload := 'OPEN', - 10 + 150 Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), - 11 + 151 Qos := MQTT.QoS.ExactlyOnce, - 12 + 152 MqttRetain := TRUE - 13 + 153 ); - 14 + 154 END_IF - 15 + 155 - 16 + 156 - IF NOT(Cover_State_Timer.Q) AND internalDown THEN + IF (NOT(Cover_State_Timer.Q) AND internalDown) AND InitMqttDone THEN - 17 + 157 pMqttPublishQueue^.AddMessage( - 18 + 158 Payload := 'CLOSED', - 19 + 159 Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), - 20 + 160 Qos := MQTT.QoS.ExactlyOnce, - 21 + 161 MqttRetain := TRUE - 22 + 162 ); - 23 + 163 END_IF - 24 + 164 - 25 + 165 - 26 + 166 (* Check what to do *) - 27 + 167 IF NOT(Cover_State_Timer.Q) AND internalUp THEN // don't run the motors for to long, assume we've reached end and toggle dir - 28 + 168 internalUp := FALSE; - 29 + 169 internalDown := FALSE; - 30 + 170 internalDir := FALSE; - 31 + 171 ELSIF NOT(Cover_State_Timer.Q) AND internalDown THEN // don't run the motors for to long, assume we've reached end and toggle dir - 32 + 172 internalUp := FALSE; - 33 + 173 internalDown := FALSE; - 34 + 174 internalDir := TRUE; - 35 + 175 ELSIF PRIO_LOCK THEN - 36 + 176 internalUp := FALSE; - 37 + 177 internalDown := FALSE; - 38 + 178 ELSIF PRIO_UP THEN - 39 + 179 internalUp := TRUE; - 40 + 180 internalDown := FALSE; - 41 + 181 Cover_State_Timer.IN:=TRUE; - 42 + 182 ELSIF PRIO_DN THEN - 43 + 183 internalUp := FALSE; - 44 + 184 internalDown := TRUE; - 45 + 185 Cover_State_Timer.IN:=TRUE; - 46 + 186 ELSIF TOGGLE AND (internalUp OR internalDown) THEN // stop and toggle dir - 47 + 187 internalUp := FALSE; - 48 + 188 internalDown := FALSE; - 49 + 189 internalDir := NOT(internalDir); - 50 + 190 ELSIF TOGGLE AND NOT(internalDir) THEN //move down - 51 + 191 internalUp := FALSE; - 52 + 192 internalDown := TRUE; - 53 + 193 Cover_State_Timer.IN:=TRUE; - 54 + 194 ELSIF TOGGLE AND internalDir THEN //move upwards - 55 + 195 internalUp := TRUE; - 56 + 196 internalDown := FALSE; - 57 + 197 Cover_State_Timer.IN:=TRUE; - 58 + 198 ELSIF MqttRequestStop THEN - 59 + 199 internalUp := FALSE; - 60 + 200 internalDown := FALSE; - 61 + 201 MqttRequestStop := FALSE; - 62 + 202 ELSIF MqttRequestOpen THEN - 63 + 203 internalUp := TRUE; - 64 + 204 internalDown := FALSE; - 65 + 205 MqttRequestOpen := FALSE; - 66 + 206 Cover_State_Timer.IN:=TRUE;; - 67 + 207 ELSIF MqttRequestClose THEN - 68 + 208 internalUp := FALSE; - 69 + 209 internalDown := TRUE; - 70 + 210 MqttRequestClose := FALSE; - 71 + 211 Cover_State_Timer.IN:=TRUE; - 72 + 212 END_IF - 73 + 213 - 74 + 214 (* make sure only one motor is active at a given time *) - 75 + 215 lock(i1 := internalUp, I2 := InternalDown, TL := T_lockout); - 76 + 216 MU := lock.Q1; @@ -3444,167 +3604,187 @@ - 77 + 217 {attribute 'reflection' := ''} - 78 + 218 FUNCTION_BLOCK FB_OUTPUT_COVER_MQTT EXTENDS FB_MQTT_BASE IMPLEMENTS MQTT.MQTT_SUBSCRIBE_CALLBACK - 79 + 219 VAR_INPUT - 80 + 220 TOGGLE: BOOL; - 81 + 221 PRIO_LOCK: BOOL; - 82 + 222 PRIO_UP: BOOL; - 83 + 223 PRIO_DN: BOOL; - 84 + 224 {attribute 'input_constant' := ''} - 85 + 225 T_LOCKOUT: TIME := TIME#1s0ms; - 86 + 226 {attribute 'input_constant' := ''} - 87 + 227 T_UD: TIME := TIME#10s0ms; - 88 + 228 END_VAR - 89 + 229 VAR_OUTPUT - 90 + 230 MU: BOOL; - 91 + 231 MD: BOOL; - 92 + 232 END_VAR - 93 + 233 VAR - 94 + 234 /// object's full instance name - 95 + 235 {attribute 'instance-path' := ''} - 96 + 236 {attribute 'noinit'} - 97 + 237 InstancePath: STRING; - 98 + 238 lock: OSCAT_BASIC.INTERLOCK; - 99 + 239 Cover_State_Timer: TOF; - 100 + 240 internalUp: BOOL; - 101 + 241 internalDown: BOOL; - 102 + 242 MqttRequestStop: BOOL; - 103 + 243 MqttRequestOpen: BOOL; - 104 + 244 MqttRequestClose: BOOL; - 106 + 245 + + MU_RTrigger:Standard.R_TRIG; + + + 246 + + MD_RTrigger:Standard.R_TRIG; + + + 247 + + MU_FTrigger:Standard.F_TRIG; + + + 248 + + MD_FTrigger:Standard.F_TRIG; + + + 249 END_VAR - 107 + 250 VAR PERSISTENT - 108 + 251 ///down = false, up = true - 109 + 252 internalDir: BOOL; - 110 + 253 END_VAR @@ -3616,7 +3796,7 @@ - 110 + 253 Standard False @@ -15093,124 +15273,139 @@ a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc - 638115483685217844 + 638646772445588685 - 3 + 37 IF InitMqttDone AND NOT initMqttDiscoveryDone THEN - 4 + 38 - 5 + 39 IF CommonTypesAndFunctions.StrEquals(str1:= ADR(overruleId), str2:= ADR('')) THEN - 6 + 40 id := CONCAT(CONCAT(THIS^.DeviceName,'_'), THIS^.InstanceNamePt^); // 'FB_DI_PB_003' - 7 + 41 ELSE - 8 + 42 id := overruleId; // 'MY_PH_GND_HALL_01' - 9 + 43 END_IF - 10 + 44 - 11 + 45 Device^.CreateCoverEntity( - 12 + 46 Name := name, - 13 + 47 Id := id, - 14 + 48 Meta := meta, - 15 + 49 CommandTopic := THIS^.MQTTSubscribeTopic, - 16 + 50 PayloadOpen := 'OPEN', - 17 + 51 PayloadClose := 'CLOSE', - 18 + 52 PayloadStop := 'STOP', - 19 + 53 StateTopic := THIS^.MQTTPublishTopic, - 20 + 54 StateOpen := 'OPEN', - 21 + 55 + + StateOpening := 'OPENING', + + + 56 StateClosed := 'CLOSED', - 22 + 57 + + StateClosing := 'CLOSING', + + + 58 + + StateStopped := 'STOPPED', + + + 59 DeviceClass := DeviceClass - 23 + 60 ); - 24 + 61 - 25 + 62 initMqttDiscoveryDone := TRUE; @@ -26472,119 +26667,149 @@ a9ed5b7e-75c5-4651-af16-d2c27e98cb94 - 638119892249377283 + 638646771605761444 - 2 + 24 TYPE MQTT_DISCOVERY_COVER EXTENDS MQTT_DISCOVERY_BASE : - 3 + 25 STRUCT - 4 + 26 ///command_topic - 5 + 27 cmd_t: JSONVAR; - 6 + 28 /// payload open - 7 + 29 pl_open: JSONVAR; - 8 + 30 /// payload_close - 9 + 31 pl_cls: JSONVAR; - 10 + 32 /// payload_stop - 11 + 33 pl_stop: JSONVAR; - 12 + 34 /// state topic - 13 + 35 stat_t: JSONVAR; - 14 + 36 /// state open - 15 + 37 stat_open: JSONVAR; - 16 + 38 + + /// state opening + + + 39 + + stat_opening: JSONVAR; + + + 40 /// state closed - 17 + 41 stat_clsd: JSONVAR; - 18 + 42 + + /// state closing + + + 43 + + stat_closing: JSONVAR; + + + 44 + + /// state stopped + + + 45 + + stat_stopped: JSONVAR; + + + 46 /// optimistic - 19 + 47 opt: JSONVAR; - 20 + 48 /// device class - 21 + 49 dev_cla: JSONVAR; - 22 + 50 END_STRUCT - 23 + 51 END_TYPE @@ -26596,7 +26821,7 @@ - 23 + 51 8a03c49a-4a2c-4182-a32d-4447ec4dd7c0 @@ -29030,314 +29255,329 @@ a9ed5b7e-75c5-4651-af16-d2c27e98cb94 3b83b776-fb25-43b8-99f2-3c507c9143fc - 638271218545266890 + 638646772095156558 - 3 + 111 MqttTopic := CONCAT(CONCAT(CONCAT(CONCAT(THIS^.MqttDiscoveryPrefix, EntityId),'/'), Id),'/config' ); - 4 + 112 - 5 + 113 // Entity related: Basis - 6 + 114 MqttDiscMsgCover.name.CharString := name; // friendly name - 7 + 115 MqttDiscMsgCover.obj_id.CharString := Id; - 8 + 116 MqttDiscMsgCover.uniq_id.CharString := Id; - 9 + 117 - 10 + 118 // Entity related: Specific - 11 + 119 MqttDiscMsgCover.cmd_t.CharString := CommandTopic; - 12 + 120 MqttDiscMsgCover.pl_open.CharString := PayloadOpen; - 13 + 121 MqttDiscMsgCover.pl_cls.CharString := PayloadClose; - 14 + 122 MqttDiscMsgCover.pl_stop.CharString := PayloadStop; - 15 + 123 MqttDiscMsgCover.stat_t.CharString := StateTopic; - 16 + 124 MqttDiscMsgCover.stat_open.CharString := StateOpen; - 17 + 125 + + MqttDiscMsgCover.stat_opening.CharString := StateOpening; + + + 126 MqttDiscMsgCover.stat_clsd.CharString := StateClosed; - 18 + 127 + + MqttDiscMsgCover.stat_closing.CharString := StateClosing; + + + 128 + + MqttDiscMsgCover.stat_stopped.CharString := StateStopped; + + + 129 MqttDiscMsgCover.opt.Boolean := FALSE; - 19 + 130 MqttDiscMsgCover.dev_cla.CharString := Deviceclass; - 20 + 131 - 21 + 132 // Availabilty related - 22 + 133 MqttDiscMsgCover.avty[1].topic.CharString := THIS^.availabilityTopic1; - 23 + 134 MqttDiscMsgCover.avty[2].topic.CharString := THIS^.availabilityTopic2; - 24 + 135 MqttDiscMsgCover.avty_mode.CharString := 'all'; - 25 + 136 MqttDiscMsgCover.pl_avail.CharString := THIS^.availabilityOnline; - 26 + 137 MqttDiscMsgCover.pl_not_avail.CharString := THIS^.availabilityOffline; - 27 + 138 MqttDiscMsgCover.qos.Integer := 2; - 28 + 139 - 29 + 140 // Device related - 30 + 141 MqttDiscMsgCover.dev.cu.CharString := THIS^.cu; - 31 + 142 MqttDiscMsgCover.dev.name.CharString := THIS^.name; - 32 + 143 MqttDiscMsgCover.dev.hw.CharString := THIS^.hw; - 33 + 144 MqttDiscMsgCover.dev.ids.CharString := THIS^.ids; - 34 + 145 MqttDiscMsgCover.dev.sw.CharString := THIS^.sw; - 35 + 146 MqttDiscMsgCover.dev.mdl.CharString := THIS^.mdl; - 36 + 147 MqttDiscMsgCover.dev.mf.CharString := THIS^.mf; - 37 + 148 - 38 + 149 // Extra meta-data - 39 + 150 IF NOT CommonTypesAndFunctions.StrEquals(str1:= ADR(meta), str2:= ADR('')) THEN - 40 + 151 MqttDiscMsgCover.meta.CharString := meta; - 41 + 152 END_IF - 42 + 153 - 43 + 154 ComposeJSON( - 44 + 155 JSONString:= ADR(MqttJSON), - 45 + 156 JSONStringSize:= SIZEOF(MqttJSON), - 46 + 157 JSONVars:= ADR(MqttDiscMsgCover), - 47 + 158 NumberOfVars:= SIZEOF(MqttDiscMsgCover) / SIZEOF(JSONVAR), - 48 + 159 MaxLevel := 1, - 49 + 160 ); - 50 + 161 ComposeJSON.Execute := TRUE; - 51 + 162 ComposeJSON(); - 52 + 163 - 53 + 164 IF MqttJSON = '' THEN - 54 + 165 SendLogMessage(str:=CONCAT(CONCAT('ERROR ',Id), ' had empty MqttJSON'), instance := InstanceName); - 55 + 166 ELSIF NOT (MqttJSON = '') THEN - 56 + 167 pMqttPublishQueue^.AddMessage( - 57 + 168 Payload:= MqttJSON, - 58 + 169 Topic := MqttTopic, - 59 + 170 Qos := MQTT.QoS.ExactlyOnce, - 60 + 171 MqttRetain := TRUE, - 61 + 172 ); - 62 + 173 SendLogMessage(str:=CONCAT(CONCAT('Added ',Id), ' as MQTT dicovery'), instance := InstanceName); - 63 + 174 END_IF @@ -29353,112 +29593,127 @@ - 64 + 86 METHOD CreateCoverEntity - 65 + 87 VAR_INPUT - 66 + 88 /// default - 67 + 89 Name: STRING; - 68 + 90 Id: STRING; - 69 + 91 - Meta: STRING; + Meta: STRING := ''; - 70 + 92 /// entity specific - 71 + 93 CommandTopic: STRING; - 72 + 94 PayloadOpen: STRING; - 73 + 95 PayloadClose: STRING; - 74 + 96 PayloadStop: STRING; - 75 + 97 StateTopic: STRING; - 76 + 98 StateOpen: STRING; - 77 + 99 - StateClosed: STRING; + StateOpening: STRING; - 78 + 100 + + StateClosed: STRING; + + + 101 + + StateClosing: STRING; + + + 102 + + StateStopped: STRING; + + + 103 Deviceclass: STRING; - 79 + 104 END_VAR - 80 + 105 VAR - 81 + 106 EntityId: STRING(25) := 'cover'; - 82 + 107 ComposeJSON: STRUCT_TO_JSON; - 83 + 108 MqttJSON: STRING(1500); - 84 + 109 MqttTopic: STRING(100); - 85 + 110 END_VAR diff --git a/src/Exports/PLCopen.xml b/src/Exports/PLCopen.xml index 6c5a624..0e88d51 100644 --- a/src/Exports/PLCopen.xml +++ b/src/Exports/PLCopen.xml @@ -1,7 +1,7 @@  - - + + @@ -276,6 +276,14 @@ state open + + + + + + state opening + + @@ -284,6 +292,22 @@ state closed + + + + + + state closing + + + + + + + + state stopped + + @@ -2370,6 +2394,9 @@ END_IF + + + @@ -2404,11 +2431,26 @@ END_IF + + + + + + + + + + + + + + + @@ -2457,7 +2499,10 @@ MqttDiscMsgCover.pl_cls.CharString := PayloadClose; MqttDiscMsgCover.pl_stop.CharString := PayloadStop; MqttDiscMsgCover.stat_t.CharString := StateTopic; MqttDiscMsgCover.stat_open.CharString := StateOpen; +MqttDiscMsgCover.stat_opening.CharString := StateOpening; MqttDiscMsgCover.stat_clsd.CharString := StateClosed; +MqttDiscMsgCover.stat_closing.CharString := StateClosing; +MqttDiscMsgCover.stat_stopped.CharString := StateStopped; MqttDiscMsgCover.opt.Boolean := FALSE; MqttDiscMsgCover.dev_cla.CharString := Deviceclass; @@ -6359,6 +6404,26 @@ END_IF + + + + + + + + + + + + + + + + + + + + @@ -6389,8 +6454,40 @@ END_IF (* Run the timer to not power the motors for to long *) Cover_State_Timer(PT:=T_UD); Cover_State_Timer.IN:=FALSE; +MU_RTrigger(CLK:=MU); +MD_RTrigger(CLK:=MD); +MU_FTrigger(CLK:=MU); +MD_FTrigger(CLK:=MD); + +IF MU_RTrigger.Q AND InitMqttDone THEN + pMqttPublishQueue^.AddMessage( + Payload := 'OPENING', + Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), + Qos := MQTT.QoS.ExactlyOnce, + MqttRetain := TRUE + ); +END_IF + +IF MD_RTrigger.Q AND InitMqttDone THEN + pMqttPublishQueue^.AddMessage( + Payload := 'CLOSING', + Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), + Qos := MQTT.QoS.ExactlyOnce, + MqttRetain := TRUE + ); +END_IF + +IF (MD_FTrigger.Q OR MU_FTrigger.Q) AND Cover_State_Timer.Q AND InitMqttDone THEN + pMqttPublishQueue^.AddMessage( + Payload := 'STOPPED', + Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), + Qos := MQTT.QoS.ExactlyOnce, + MqttRetain := TRUE + ); +END_IF + -IF NOT(Cover_State_Timer.Q) AND internalUp THEN +IF (NOT(Cover_State_Timer.Q) AND internalUp) AND InitMqttDone THEN pMqttPublishQueue^.AddMessage( Payload := 'OPEN', Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), @@ -6399,7 +6496,7 @@ IF NOT(Cover_State_Timer.Q) AND internalUp THEN ); END_IF -IF NOT(Cover_State_Timer.Q) AND internalDown THEN +IF (NOT(Cover_State_Timer.Q) AND internalDown) AND InitMqttDone THEN pMqttPublishQueue^.AddMessage( Payload := 'CLOSED', Topic := CONCAT(MqttPublishTopicPrefix^, MqttPublishTopicSuffix), @@ -6535,7 +6632,10 @@ MD := lock.Q2; PayloadStop := 'STOP', StateTopic := THIS^.MQTTPublishTopic, StateOpen := 'OPEN', + StateOpening := 'OPENING', StateClosed := 'CLOSED', + StateClosing := 'CLOSING', + StateStopped := 'STOPPED', DeviceClass := DeviceClass ); diff --git a/src/HomeAutomation.ecp b/src/HomeAutomation.ecp index 6f89f27..b55e47a 100644 Binary files a/src/HomeAutomation.ecp and b/src/HomeAutomation.ecp differ