I was implementing the JSON parsing and composing library, however I ran in a problem.
Since codesys does not support dynamic array allocation, I have to use a static array of objects.
Is it possible to extend the function of "VariableArraySize", currently only null values are ignored.
If a user uses an array of DUT and every value in the DUT is null that the whole object is ignored?
That would be a good feature, I'll have to think about the best way to implement that.
As a workaround for now, you could try manually setting the NumberOfVars input of STRUCT_TO_JSON. In all the example projects, I've always used SIZEOF(LocalJSONObj) / SIZEOF(JSONVAR), which will always result in the total number of JSONVARs in the local object. In your example, I think it would result in 22 variables. If you set it manually, or with some code, to 15, the composer should ignore your last 7 null values. It's a little bit messy, but I think it could work. I have not tested this though.
Last edit: tvm 2022-10-12
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Basically each JSONVAR has properties so the composer knows what kind of variable it is. The end of an array should also be, by definition, the end of an object, but that flag was not set, so it missed the last '}'
I've tested this a bit, but I wouldn't say extensively. I actually use the parser more than the composer myself. There's so many possible combinations of JSON strings that it's hard to test for every possibility. So previous versions are still available.
Tim
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am reading REAL values from a Json, however the conversion is not working quite properly.
Do I need to use a function on every variable or should it be done automatically?
I can see that the HMIVarAsString is correct '0.9454', however the Number is 0 and the AsString is also '0'.
I'm not exactly sure why, but your variable is of type Integer, but the value looks more like a Real. This is one of the places where JSON doesn't correspond to IEC61131 types. In JSON, a Number can be either floating point or integer. Of course, we have to strictly declare the types, so the library uses types like this:
TYPE JSONVALUETYPE :( json_string, //local var is type STRING json_number, //local var is REAL json_integer, //local var is DINT json_boolean, //local var is BOOL json_null, //local var is type null json_array, //object is an array json_object //object is another object (nested objects));END_TYPE
If the value is set through the 'AsString' property, it will guess at the type (see the STRING_TO_JSONVAR function to see how it does that). If the value is set explicitly through the 'Number', or 'Integer' property, it will set the type to REAL or DINT. You can also manually set the ValueType property.
I see the 'HMIVarAsString' shows a floating point type value. This variable is updated any time the set accessor of the 'AsString' property is called, so your number was probably a floating point type at some time.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I was implementing the JSON parsing and composing library, however I ran in a problem.
Since codesys does not support dynamic array allocation, I have to use a static array of objects.
Is it possible to extend the function of "VariableArraySize", currently only null values are ignored.
If a user uses an array of DUT and every value in the DUT is null that the whole object is ignored?
Best regards,
Sander
That would be a good feature, I'll have to think about the best way to implement that.
As a workaround for now, you could try manually setting the NumberOfVars input of STRUCT_TO_JSON. In all the example projects, I've always used SIZEOF(LocalJSONObj) / SIZEOF(JSONVAR), which will always result in the total number of JSONVARs in the local object. In your example, I think it would result in 22 variables. If you set it manually, or with some code, to 15, the composer should ignore your last 7 null values. It's a little bit messy, but I think it could work. I have not tested this though.
Last edit: tvm 2022-10-12
Hi,
Thanks for you response in first place, I haven't checked your quickfix (but I will).
However I found a bug which I cannot truly understand:
If the last object is an array then the json is incorrect, see wrongjson.png.
The expected json is shown in the other image (expectedresult.png)
Hope you can easily fix this issue?
Best regards,
Sander
Well that helped me track down a bug that's been around for a while.
Try the new version 1.0.0.14
https://forge.codesys.com/lib/pro-json/home/Home/
Basically each JSONVAR has properties so the composer knows what kind of variable it is. The end of an array should also be, by definition, the end of an object, but that flag was not set, so it missed the last '}'
I've tested this a bit, but I wouldn't say extensively. I actually use the parser more than the composer myself. There's so many possible combinations of JSON strings that it's hard to test for every possibility. So previous versions are still available.
Tim
Hi Tim,
Thanks for your fix, it is working very good currently!
Is there still a chance of implementing the initial question to ignore null objects?
Really appreciate your work!
Best regards,
Sander
It's on my list of things to do, but I'm in the middle of a big project right now so I probably won't get to it until the new year.
Hi Tim,
I am reading REAL values from a Json, however the conversion is not working quite properly.
Do I need to use a function on every variable or should it be done automatically?
I can see that the HMIVarAsString is correct '0.9454', however the Number is 0 and the AsString is also '0'.
Best regards,
Sander
I'm not exactly sure why, but your variable is of type Integer, but the value looks more like a Real. This is one of the places where JSON doesn't correspond to IEC61131 types. In JSON, a Number can be either floating point or integer. Of course, we have to strictly declare the types, so the library uses types like this:
If the value is set through the 'AsString' property, it will guess at the type (see the STRING_TO_JSONVAR function to see how it does that). If the value is set explicitly through the 'Number', or 'Integer' property, it will set the type to REAL or DINT. You can also manually set the ValueType property.
I see the 'HMIVarAsString' shows a floating point type value. This variable is updated any time the set accessor of the 'AsString' property is called, so your number was probably a floating point type at some time.