br-automation-com / paho.mqtt.c-ar

MQTT Client for Automation Runtime based on eclipse/paho.mqtt.c
21 stars 7 forks source link

Publish is not triggered on value-change with PublishMode = IOTMQTT_PUB_MODE_VALUE #19

Closed jesperhosen closed 2 years ago

jesperhosen commented 2 years ago

Hello! I am using your IotMqtt library and is having some issue when using the IotMqttRegParPublish.PublishMode:=IOTMQTT_PUB_MODE_VALUE.

I am sending a self defined struct : consisting of BOOLEAN values, USINT, REALs, some self defined directly derived datatypes (REAL) and self defined ENUM. When bool values are updated, a send is triggered, but when an enum value is updated, a send is not triggered. Any idea if this is a known problem? Maybe operator <> is not defined for enumerations?

Moreover, attributes with directly derived datatypes does not seem to be sent on MQTT.. Guess a work around would be to create a new struct with only basic types.

priesf commented 2 years ago

Hi @jesperhosen, I checked your description and I'm able to reproduce the issue with the directly derived datatypes not beeing sent via MQTT. Still, changes on the directly derived datatypes will trigger a send of the MQTT package. For the enumerations, I get the changes and the corresponding updates. Maybe as a hint, enums will be represented as DINT datatypes and therefore will be a number in the MQTT package. Can you provide your structure so I can check against my simple test?

Directly derived datatypes are currently not supported within the library using the JSON format. This has something to do with the internally used serializer function. Using the binary format, the directly derived datatypes are working.

For now, you can use basic datatypes as a workaround, as highlighted in the screenshot. image I will check if we can implement the directly derived datatypes into the serializer and get back to you.

BR Fabian

jesperhosen commented 2 years ago

Hi Fabian, Thanks for getting back to me. Here's the structure. In particullar, when attribute state is updated, a send is not triggered, while when a bool value is update a send is triggered.

TYPE
    EmsSts :    STRUCT 
        state : EmsState;
        powerAvailableDrive : WATT;
        powerAvailableAux : WATT;
        powerAvailableCooling : WATT;
        batteryContactorsClosed : BOOL := FALSE;
        hvDcLinkVoltage : VOLT;
        stopDriveRequested : BOOL;
        motorEnableKey : BOOL;
        ignitionKey : BOOL;
    END_STRUCT;

    EmsState : 
        (
        EMS_STATE_INIT := 0,
        EMS_STATE_IDLE := 1,
        EMS_STATE_DRIVE := 4,
        EMS_STATE_CHARGE := 5,
        EMS_STATE_EMERGENCY := 10
        );

    WATT : REAL;
    VOLT : REAL;

END_TYPE
priesf commented 2 years ago

Hi @jesperhosen, thanks for the update. I tried your struct definition an it is working for me, except the directly derived types.

https://user-images.githubusercontent.com/74359410/160339567-ce4168ae-26f6-4e02-af8d-1c73890c936a.mp4

Can you provide more information on how to reproduce the issue? BR Fabian

jesperhosen commented 2 years ago

Can you try to toggle state value between two values (e.g. EMERGENCY and IDLE) multiple times? In my EmsState-enum I am also using "EMS_STATE_DELAYED_SHUTDOWN := 7" which was not included in the previous code snip i sent to you. Some times when toggling between two states, the values are not updated. I'm using mosquitto as a broker, and mosquitto_sub to receive samples. All is running on LAN. My MQTT-publish-application runs at 100ms cycle. Under normal operation the values are set in an other PRG running at 100ms, but now to reproduce this I am setting values manually using the watch. The following screenshot shows a mismatch between the watch-window and the mosquitto_sub terminal.

image

priesf commented 2 years ago

Hello @jesperhosen, I'm still not able to reproduce your issue, even if I toggle the state each cycle. I'm not missing information and also I'm not seeing a difference between the actual state and the MQTT message.

One thing I noticed in your screenshot is, that the watch is showing a global structure variable "g_ems" with element "sts" The message shows that the variable which is registered at the functionblock is a local variable "ems" with the element "sts" inside the task "Gateway". Could it be that there is difference in your program or maybe a missing update link between these two variables?

patricthysell commented 2 years ago

@jesperhosen Which quality of service are you using for publishing the structure? QoS0 would mean a fire-and-forget which means that under certain circumstances you might not receive it on the subscriber side, meaning the network / IT infrastructure can be an influencing factor. From a Library-point of view - if a change occurs faster (or even in another taskclass with the same cycle-time) than the task that IotMqttPublish runs in, a "toggle" might be missed, as the publish function block checks the difference of the structure to its last scan. So its important to make sure values are changed and published in the same task-class. Otherwise please check the QoS option and see if that helps