1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | ========================================================================================================*) starttime:= TIME(); //store the time of the beginning of execution compose:= TRUE; Busy:= TRUE; Aborted:= FALSE; Done:= FALSE; Error:= FALSE; ErrorPosition:= 0; bufferposition:= 1; jsonvarindex:= 1; FOR i:= 1 TO GPL_JSON.MAX_LEVELS DO //clear names array names[i].Name:= ''; names[i].ArrayIndex:= 0; END_FOR //clear previous string SysMemSet( pDest:= JSONString, udiValue:= 0, udiCount:= JSONStringSize ); END_IF IF Abort_TRIG.Q THEN Busy:= FALSE; Aborted:= TRUE; compose:= FALSE; //characteristics of the first variable are not always set properly by FB_Init //every level of the first variable could be either a new object or a new array JSONVars^[jsonvarindex].VarNameArray[varlevelindex].NewArray:= TRUE; ELSIF (varlevelindex > 1) OR (NumberofVars = 1) THEN JSONVars^[jsonvarindex].VarNameArray[varlevelindex].NewObject:= TRUE; END_IF END_FOR END_IF IF (jsonvarindex = NumberOfVars) THEN //set characteristics of last variable IF (JSONVars^[jsonvarindex].VarNameArray[varlevelindex].ArrayIndex > 0) THEN //end array if an array index exists JSONVars^[jsonvarindex].VarNameArray[varlevelindex].EndObject:= TRUE; objectstr:= '{'; //new JSON string ELSE objectstr:= ''; //clear previous object string IF NOT (VariableArraySize AND (names[1].ArrayIndex > 0) AND (JSONVars^[jsonvarindex].ValueType = JSONVALUETYPE.json_null)) THEN objectstr:= CONCAT(objectstr, ','); //comma in between each value IF Format AND (names[1].ArrayIndex <= 1) THEN //new line after each comma, except in arrays objectstr:= CONCAT(objectstr, GPL_JSON.NEWLINE); END_IF IF (MaxLevel = 0) THEN //default, create all objects below the program level maxlevelindex:= JSONVars^[jsonvarindex].ApplicationLevel - 2; //manually defined with the MaxLevel input maxlevelindex:= MaxLevel; FOR namesindex:= maxlevelindex TO 1 BY -1 DO //loop through all levels of an object IF names[namesindex].NewArray AND (names[namesindex].ArrayIndex <= 1) THEN //new array at this level CreateName(Name:= names[namesindex].Name); CreateArray(); ELSIF names[namesindex].NewObject AND (namesindex <> 1) THEN //new object at this level CreateName(Name:= names[namesindex].Name); CreateObject(); IF (namesindex=1) THEN //only write a value at level 1 IF (names[namesindex].ArrayIndex > 0) THEN //array, create value only //don't write the value if the current variable is an array, and the value is null CreateValue(ValueType:= JSONVars^[jsonvarindex].ValueType, Value:= JSONVars^[jsonvarindex].AsString); END_IF FOR namesindex:= 1 TO maxlevelindex DO IF names[namesindex].EndArray THEN CloseArray(); IF names[namesindex].EndObject AND (namesindex <> 1) THEN CloseObject(); StrConcatA( pstTo:= ADR(JSONString^[bufferposition]), ); bufferposition:= bufferposition + DINT_TO_UDINT(LEN(objectstr)); //end of vars, close string Busy:= FALSE; ComposeTime:= TIME() - starttime; JSONString^[bufferposition]:= ASCII.CLOSE_BRACE;; //close JSON object with } RETURN; END_WHILE {a9ed5b7e-75c5-4651-af16-d2c27e98cb94} VAR_INPUT Execute: BOOL; //rising edge triggers compose of JSON string JSONStringSize: UDINT; //size of string JSONVars: POINTER TO ARRAY[1..GPL_JSON.MAX_VARS] OF JSONVAR; //pointer to local structure made up of type JSONVAR NumberOfVars: UINT; //number of variables in the local structure or array VariableArraySize: BOOL; //don't write array values which are null, resulting in variable array sizes Format: BOOL; //add white space and indenting to the resulting string MaxLevel examples: Device.Application.TestJSON_PRG.var1, default {"var1":"value"} Device.Application.TestJSON_PRG.var1, set MaxLevel=2 to get {TestJSON_PRG:{"var1":"value"}} Device: 5, Application: 4, Program: 3, Function Block: 2, Variable: 1 Device.Application.TestJSON_PRG.Test_FB.var1, set MaxLevel=1 to get {"var1":"value"} Device.Application.TestJSON_PRG.Test_FB.var1, set MaxLevel=2 to get {Test_FB:{"var1":"value"}} Device.Application.TestJSON_PRG.Test_FB.var1, set MaxLevel=3 to get {TestJSON_PRG:{Test_FB:{"var1":"value"}}} END_VAR Busy: BOOL; //busy composing a string Done: BOOL; //successfully composed the whole string with no errors ComposeTime: TIME; //time it took to compose the string bufferposition: UDINT; //current position in the string compose: BOOL; namesindex: INT; Execute_TRIG: R_TRIG; thisloopstarttime: TIME; //time the current loop started varlevelindex: INT; |