@@ -948,13 +948,14 @@ func (s *StaticModelGenerator) printDataObjectDefinitions(lnName string, dataObj
948
948
s .printDataObjectDefinitions (doName , dataObject .SubDataObjects , firstDataAttributeName , isDoTransient )
949
949
}
950
950
if len (dataObject .DataAttributes ) > 0 {
951
- s .printDataAttributeDefinitions (doName , dataObject .DataAttributes , isDoTransient )
951
+ s .printDataAttributeDefinitions (doName , dataObject .DataAttributes , isDoTransient , - 1 )
952
952
}
953
953
}
954
954
}
955
955
956
- func (s * StaticModelGenerator ) printDataAttributeDefinitions (doName string , dataAttributes []* DataAttribute , isTransient bool ) {
956
+ func (s * StaticModelGenerator ) printDataAttributeDefinitions (doName string , dataAttributes []* DataAttribute , isTransient bool , arrayIdx int ) {
957
957
for i , dataAttribute := range dataAttributes {
958
+ isArray := dataAttribute .Count > 0
958
959
daName := doName + "_" + dataAttribute .Name
959
960
960
961
// Handle FunctionalConstraint "SE"
@@ -972,7 +973,7 @@ func (s *StaticModelGenerator) printDataAttributeDefinitions(doName string, data
972
973
s .cOut .println (" \" %s\" ," , dataAttribute .Name )
973
974
s .cOut .println (" (ModelNode*) &%s," , doName )
974
975
975
- // Sibling node
976
+ // Print pointer to sibling node
976
977
if i < len (dataAttributes )- 1 {
977
978
sibling := dataAttributes [i + 1 ]
978
979
siblingDoName := doName
@@ -986,15 +987,23 @@ func (s *StaticModelGenerator) printDataAttributeDefinitions(doName string, data
986
987
s .cOut .println (" NULL," )
987
988
}
988
989
989
- // First sub-data attribute
990
- if len (dataAttribute .SubDataAttributes ) > 0 {
991
- s .cOut .println (" (ModelNode*) &%s_%s," , daName , dataAttribute .SubDataAttributes [0 ].Name )
990
+ if isArray {
991
+ // For arrays, the first child is array element 0
992
+ s .cOut .println (" (ModelNode*) &%s_0," , daName )
993
+ s .cOut .println (" %d," , dataAttribute .Count )
994
+ s .cOut .println (" -1," ) // arrayIdx
992
995
} else {
993
- s .cOut .println (" NULL," )
996
+ // For non-arrays, print pointer to the first sub-data attribute if exists
997
+ if len (dataAttribute .SubDataAttributes ) > 0 {
998
+ s .cOut .println (" (ModelNode*) &%s_%s," , daName , dataAttribute .SubDataAttributes [0 ].Name )
999
+ } else {
1000
+ s .cOut .println (" NULL," )
1001
+ }
1002
+ s .cOut .println (" %d," , dataAttribute .Count )
1003
+ s .cOut .println (" -1," ) // arrayIdx
994
1004
}
995
1005
996
- // Print Count, FunctionalConstraint, and Type
997
- s .cOut .println (" %d," , dataAttribute .Count )
1006
+ // Print FunctionalConstraint and Type
998
1007
s .cOut .println (" IEC61850_FC_%s," , dataAttribute .FC )
999
1008
s .cOut .println (" IEC61850_%s," , dataAttribute .AttributeType .ToString ())
1000
1009
@@ -1019,7 +1028,7 @@ func (s *StaticModelGenerator) printDataAttributeDefinitions(doName string, data
1019
1028
1020
1029
s .cOut .println (" NULL," )
1021
1030
1022
- // Short address
1031
+ // Print short address if valid
1023
1032
shortAddr := int64 (0 )
1024
1033
if addr , err := cast .ToInt64E (dataAttribute .ShortAddress ); err == nil {
1025
1034
shortAddr = addr
@@ -1029,12 +1038,74 @@ func (s *StaticModelGenerator) printDataAttributeDefinitions(doName string, data
1029
1038
s .cOut .println (" %d" , shortAddr )
1030
1039
s .cOut .println ("};\n " )
1031
1040
1032
- // Recursive call for sub-data attributes
1033
- if len (dataAttribute .SubDataAttributes ) > 0 {
1034
- s .printDataAttributeDefinitions (daName , dataAttribute .SubDataAttributes , isTransient )
1041
+ // If array, print each array element definition
1042
+ if isArray {
1043
+ for idx := 0 ; idx < dataAttribute .Count ; idx ++ {
1044
+ arrayElementdaName := fmt .Sprintf ("%s_%d" , daName , idx )
1045
+ s .variablesList = append (s .variablesList , arrayElementdaName )
1046
+
1047
+ s .cOut .println ("DataAttribute %s = {" , arrayElementdaName )
1048
+ s .cOut .println (" DataAttributeModelType," )
1049
+ s .cOut .println (" NULL," )
1050
+ s .cOut .println (" (ModelNode*) &%s," , daName )
1051
+
1052
+ // Print pointer to next array element or NULL if last
1053
+ if idx != dataAttribute .Count - 1 {
1054
+ nextArrayElementdaName := fmt .Sprintf ("%s_%d" , daName , idx + 1 )
1055
+ s .cOut .println (" (ModelNode*) &%s," , nextArrayElementdaName )
1056
+ } else {
1057
+ s .cOut .println (" NULL," )
1058
+ }
1059
+
1060
+ // Print pointer to first sub-data attribute if exists
1061
+ if len (dataAttribute .SubDataAttributes ) > 0 {
1062
+ s .cOut .println (" (ModelNode*) &%s_%s," , arrayElementdaName , dataAttribute .SubDataAttributes [0 ].Name )
1063
+ } else {
1064
+ s .cOut .println (" NULL," )
1065
+ }
1066
+
1067
+ s .cOut .println (" 0," ) // count for array element
1068
+ s .cOut .println (" %d," , idx ) // index of array element
1069
+
1070
+ s .cOut .println (" IEC61850_FC_%s," , dataAttribute .FC )
1071
+ s .cOut .println (" IEC61850_%s," , dataAttribute .AttributeType .ToString ())
1072
+
1073
+ // Print trigger options for array element
1074
+ s .cOut .print (" 0" )
1075
+ if trgOps != nil {
1076
+ if trgOps .Dchg {
1077
+ s .cOut .print (" + TRG_OPT_DATA_CHANGED" )
1078
+ }
1079
+ if trgOps .Dupd {
1080
+ s .cOut .print (" + TRG_OPT_DATA_UPDATE" )
1081
+ }
1082
+ if trgOps .Qchg {
1083
+ s .cOut .print (" + TRG_OPT_QUALITY_CHANGED" )
1084
+ }
1085
+ }
1086
+ if isTransient {
1087
+ s .cOut .print (" + TRG_OPT_TRANSIENT" )
1088
+ }
1089
+ s .cOut .println ("," )
1090
+
1091
+ s .cOut .println (" NULL," )
1092
+ // sAddr is always zero for array element
1093
+ s .cOut .print (" 0" )
1094
+ s .cOut .println ("};\n " )
1095
+
1096
+ // Recursively print sub-data attributes for each array element
1097
+ if len (dataAttribute .SubDataAttributes ) > 0 {
1098
+ s .printDataAttributeDefinitions (arrayElementdaName , dataAttribute .SubDataAttributes , isTransient , - 1 )
1099
+ }
1100
+ }
1101
+ } else {
1102
+ // Recursively print sub-data attributes for non-array attribute
1103
+ if len (dataAttribute .SubDataAttributes ) > 0 {
1104
+ s .printDataAttributeDefinitions (daName , dataAttribute .SubDataAttributes , isTransient , - 1 )
1105
+ }
1035
1106
}
1036
1107
1037
- // Process value
1108
+ // Process value if present or fetch default value from definition
1038
1109
value := dataAttribute .Value
1039
1110
if value == nil && dataAttribute .Definition != nil {
1040
1111
value = dataAttribute .Definition .Value
0 commit comments