Publish a JSON payload via MQTT Publish (using IIot Libraries)

2024-04-10
2024-06-18
  • joshskellig - 2024-04-10

    I am trying to figure out how to get a JSON payload to properly publish to my MQTT Broker. I am able to generate JSON using the examples from Codesys, but when I send that payload via MQTT there are characters that are extra or not recognized by my MQTT client. Any idea what could be causing it?

    PROGRAM PLC_PRG
    VAR
        hostname: STRING := 'localhost';
        port: UINT := 1883;
        topic: WSTRING(1024) := "testing/";
        payload: BYTE;
        factory : JSON.JSONDataFactory;
        eDataFactoryError : FBF.ERROR;
        pJsonData : POINTER TO JSON.JSONData := factory.Create(eError => eDataFactoryError);
        fb_JBuilder : JSON.JSONBuilder;
        wsValue : WSTRING := "Value1";
        diRootIndex, diObject1Index : DINT;
        iValue : INT := 1234;
        jsonArrayWriter : JSON.JSONByteArrayWriter;
        wsJsonData : WSTRING(1000);
        xFirst : BOOL := TRUE;
        mqttClient: MQTT.MQTTClient;
        mqttPublish: MQTT.MQTTPublish;
        mqttPublishProperties: MQTT.MQTTPublishProperties := (bPayloadFormatIndicator := 1, wsContentType := "application/json");
    END_VAR
    
    // Json Functionality
    IF xFirst THEN
      fb_JBuilder(pJsonData := pJsonData, diRootObj => diRootIndex);
      fb_JBuilder.SetKeyWithValue("Key1", wsValue, diParentIndex := diRootIndex);
      diObject1Index := fb_JBuilder.SetKeyWithObject("Key2", diParentIndex := diRootIndex);
      fb_JBuilder.SetKeyWithValue("Key3", iValue, diParentIndex := diObject1Index);
      xFirst := FALSE;
    END_IF
    
    jsonArrayWriter(pwData := ADR(wsJsonData), udiSize := SIZEOF(wsJsonData), jsonData := pJsonData^, xAsyncMode := FALSE);
    MSU.StrTrimW(pString:= ADR(wsJsonData));
    
    // MQTT Functionality
    mqttClient(
        sHostname:=hostname,
        uiPort:=port,
        eMQTTVersion:=MQTT.MQTT_VERSION.V5
    );
    mqttPublish(
        mqttClient:=mqttClient,
        pbPayload:=ADR(wsJsonData),
        udiPayloadSize:=SIZEOF(wsJsonData),
        wsTopicName:=topic,
        mQTTPublishProperties:=mqttPublishProperties
    );
    
     
  • i-campbell

    i-campbell - 2024-04-10
    1. your are sending as a WSTRING which is UTF16, but your receiver is interpriting as UTF8. Change the receiver to use UTF16, or better change your sender to convert to UTF8.
    2. You publish the entire storage space (SIZEOF) Instead of the number of bytes of actual text (StrLenA)

    try using

    utf8JsonData : STRING(2000);
    
    JSON.Stu.ConvertUTF16toUTF8(
        ADR(wsJsonData),
        ADR(utf8JsonData),
        SIZEOF(utf8JsonData)
    );
    

    and change your publish to

    mqttPublish(
        mqttClient:=mqttClient,
        pbPayload:=ADR(utf8JsonData),
        udiPayloadSize:=To_UDINT(JSON.Stu.StrLenA(ADR(utr8JsonData))),
        wsTopicName:=topic,
        mQTTPublishProperties:=mqttPublishProperties
    );
    
     
    πŸ‘
    1
    • joshskellig - 2024-04-10

      Thanks for the help! Everything now works as expected.

       
      • calviniscoding - 2024-06-18

        Are you able to dynamically change the JSON message? As in, if wsValue or iValue is linked to some real telemetry that varies over time, will the JSON message reflect these changes? I am only able to send the values that I initialize the JSON message to

         
    • joshskellig - 2024-04-10

      Thanks for the help! Everything now works as expected.

       
    • joshskellig - 2024-04-10

      Thanks for the help! Everything now works as expected.

       

Log in to post a comment.