Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

JSON (WString format) accessing elements. Convert to STRUCT?

2021-11-15
2021-11-17
  • justthefacts77

    justthefacts77 - 2021-11-15

    Hey Folks,

    I am obtaining data from a Weather API site using the "WEB_CLIENT" block (HTTP Get). JSON data comes in and is stored off in a "WSTRING" as follows:

    "{"coord":{"lon":-82.4584,"lat":27.9475},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"base":"stations","main":{"temp":72.48,"feels_like":71.6,"temp_min":68.05,"temp_max":76.15,"pressure":1023,"humidity":43},....."

    Pretty format...

    {
    "coord": {
    "lon": -82.4584,
    "lat": 27.9475
    },
    "weather":
    {
    "id": 804,
    "main": "Clouds",
    "description": "overcast clouds",
    "icon": "04d"
    }
    ,
    "base": "stations",
    "main": {
    "temp": 66.96,
    "feels_like": 65.61,
    "temp_min": 63.95,
    "temp_max": 70.41,
    "pressure": 1023,
    "humidity": 48
    },....

    ?- What is the optimal way to access elements in the Array.

    Seems like It be converted into a STRUCT and elements pulled with the "dot . " convention i.e.
    MAIN.TEMP = 66.96

    Regards

     
  • tvm

    tvm - 2021-11-16

    Take a look at this library: https://forge.codesys.com/lib/pro-json/home/Home/
    I created it and did most of the testing with open weather map, which looks like what you're using as well.

     
  • justthefacts77

    justthefacts77 - 2021-11-16

    Thank you much TVM!

    My biggest challenge is to parse out an element from an Array, so i was thinking multiple steps:
    - Find Key for the Array location
    - Find item in Array via an Index lookup...etc.

    Anyway ill dig into it.

    I am looking at the JSON Utilies SL library right now but hampered by the fact my HTTP Client is outputting a WString (JSON) from the weather API and haven't figured out way to feed into the FBlks they offer.

    Thank you again!

     
  • tvm

    tvm - 2021-11-16

    well, for what it's worth, the JSON library uses STRING variables as well, but feel free to modify it.
    The main conversion function blocks uses a pointer to the string:

    JSONString:     POINTER TO ARRAY[1..GPL_JSON.MAX_JSON_STRING] OF BYTE;
    

    It might be as easy as changing the BYTE to a WORD, because after that it uses array indexes, not pointer math. But I haven't tested that.

     

    Last edit: tvm 2021-11-17
  • justthefacts77

    justthefacts77 - 2021-11-17

    Ok so looking at "ParseJSON"...feed it in a String, then how do I access members of an Element, then an object in an Array, i.e. how does it determine which Type?

    "coord" : {

    "lon" : -82.4584,
    "lat" : 27.9475
    

    },
    "weather" : [

    {
    "id" : 804,
    "main" : Clouds,
    "description" : overcast clouds,
    "icon" : 04d
    }

    ],

    ?- What would be the syntax to assign the element to a temp variable, for example
    temp := JSONVars.weather.main

    Appreciate any input, gonna have to do my due diligence on the coding aspects for sure.

     
  • tvm

    tvm - 2021-11-17

    Here's an example of one of the structures I was using with Open Weather Map:

    TYPE OWM_WEATHER :
    STRUCT
        id:             JSONVAR;
        main:           JSONVAR;
        description:    JSONVAR;
        icon:           JSONVAR;
    END_STRUCT
    END_TYPE
    
    Weather:    OWM_WEATHER;
    

    You'll have to create structures and arrays that match the expected result from whichever API you're using. Order doesn't matter, but the structure does. (But parsing will be faster if the order matches as closely as possible).

    So then, for example, if I want to get the description, I could access Weather.description.CharString
    or if I wanted the id, I'd use Weather.id.Integer, (or Weather.id.Number if I wanted it as a floating point value)

    take a look at the documentation in the JSONVAR function block, basically it guesses at the type when parsing from the string (because it uses the setter of the .AsString property), but you can then access it as whatever type you need (string, boolean, integer, number, or datetime)

     

Log in to post a comment.