mqtt/mqtt_client_gen.py
changeset 4020 205d5379b35e
parent 4019 ad2b84071881
child 4021 07504d4c40ee
equal deleted inserted replaced
4019:ad2b84071881 4020:205d5379b35e
   428             formatdict["init_pubsub"] += """
   428             formatdict["init_pubsub"] += """
   429     INIT_SUBSCRIPTION({Topic}, {QoS})""".format(**locals())
   429     INIT_SUBSCRIPTION({Topic}, {QoS})""".format(**locals())
   430             formatdict["retrieve"] += """
   430             formatdict["retrieve"] += """
   431         READ_VALUE({c_loc_name}, {C_type})""".format(**locals())
   431         READ_VALUE({c_loc_name}, {C_type})""".format(**locals())
   432 
   432 
   433         def recurseJsonTypes(datatype, basetypes):
   433         # collect all used type with their dependencies
       
   434         basetypes=[]
       
   435         arrays=set()
       
   436         structures=set()
       
   437         already_generated_types = set()
       
   438 
       
   439         def recurseJsonTypes(datatype):
       
   440             # append derivated type first so we can expect the list
       
   441             # to be sorted with base types in last position
   434             basetypes.append(datatype)
   442             basetypes.append(datatype)
   435             # add derivated type first fo we can expect the list to be sorted
       
   436             # with base types in last position
       
   437             infos = datatype_info_getter(datatype)
   443             infos = datatype_info_getter(datatype)
   438             for element in infos["elements"]:
   444             print(infos)
   439                 field_datatype = element["Type"]
   445             element_type = infos["type"]
   440                 if field_datatype not in MQTT_IEC_types:
   446             if element_type == "Structure":
   441                     recurseJsonTypes(field_datatype, basetypes)
   447                 structures.add(datatype)
   442 
   448                 for element in infos["elements"]:
   443         print(json_types)
   449                     field_datatype = element["Type"]
   444 
   450                     if field_datatype not in MQTT_IEC_types:
   445         # collect all type dependencies
   451                         recurseJsonTypes(field_datatype)
   446         basetypes=[]  # use a list to keep them ordered
   452             elif element_type == "Array":
       
   453                 arrays.add(datatype)
       
   454                 item_datatype = infos["base_type"]
       
   455                 if item_datatype not in MQTT_IEC_types:
       
   456                     recurseJsonTypes(item_datatype)
       
   457         def typeCategory(iec_type):
       
   458             if field_iec_type in arrays:
       
   459                 return "ARRAY"
       
   460             elif field_iec_type in structures:
       
   461                 return "OBJECT"
       
   462             return "SIMPLE"
       
   463 
   447         for iec_type,_instances in json_types.items():
   464         for iec_type,_instances in json_types.items():
   448             recurseJsonTypes(iec_type, basetypes)
   465             recurseJsonTypes(iec_type)
   449 
   466 
   450         done_types = set()
       
   451         # go backard to get most derivated type definition last
   467         # go backard to get most derivated type definition last
   452         # so that CPP can always find base type deinition before
   468         # so that CPP can always find base type deinition before
   453         for iec_type in reversed(basetypes):
   469         for iec_type in reversed(basetypes):
   454             # avoid repeating type definition
   470             # avoid repeating type definition
   455             if iec_type in done_types:
   471             if iec_type in already_generated_types:
   456                 continue
   472                 continue
   457             done_types.add(iec_type)
   473             already_generated_types.add(iec_type)
   458 
   474 
   459             C_type = iec_type.upper()
   475             C_type = iec_type.upper()
   460             json_decl = "#define TYPE_" + C_type + "(_P, _A) \\\n"
   476             json_decl = "#define TYPE_" + C_type + "(_P, _A) \\\n"
   461 
   477 
   462             infos = datatype_info_getter(iec_type)
   478             infos = datatype_info_getter(iec_type)
   463 
   479 
   464             elements = infos["elements"]
   480             element_type = infos["type"]
   465             last = len(elements) - 1
   481             if element_type == "Structure":
   466             for idx, element in enumerate(elements):
   482                 elements = infos["elements"]
   467                 field_iec_type = element["Type"]
   483                 last = len(elements) - 1
       
   484                 for idx, element in enumerate(elements):
       
   485                     field_iec_type = element["Type"]
       
   486                     if type(field_iec_type) == tuple and field_iec_type[0] == "array":
       
   487                         raise Exception("Inline arrays in structure are not supported. Please use a separate data type for array.")
       
   488 
       
   489                     field_C_type = field_iec_type.upper()
       
   490                     field_name = element["Name"]
       
   491                     field_C_name = field_name.upper()
       
   492                     decl_type = typeCategory(field_iec_type)
       
   493 
       
   494                     json_decl += ("    _P##_" + decl_type + "(" + 
       
   495                                   field_C_type + ", " + field_C_name + ", " + field_name + ", _A)" +
       
   496                                   ("\n\n" if idx == last else " _P##_separator \\\n"))
       
   497 
       
   498             elif element_type == "Array":
       
   499                 dimensions = infos["dimensions"]
       
   500                 if len(dimensions) > 1:
       
   501                     raise Exception("Only 1 dimension arrays are supported")
       
   502                 count = int(dimensions[0][1]) - int(dimensions[0][0]) + 1
       
   503                 field_iec_type = infos["base_type"]
       
   504                 decl_type = typeCategory(field_iec_type)
   468                 field_C_type = field_iec_type.upper()
   505                 field_C_type = field_iec_type.upper()
   469                 field_name = element["Name"]
   506                 last = count - 1
   470                 field_C_name = field_name.upper()
   507                 for idx in range(count):
   471                 if field_iec_type in MQTT_IEC_types:
   508                     json_decl += ("    _P##_ARRAY_" + decl_type + "(" +
   472                     decl_type = "SIMPLE"
   509                                   field_C_type + ", " + repr(idx) + " , _A)" +
   473                 else:
   510                                   ("\n\n" if idx == last else " _P##_separator \\\n"))
   474                     decl_type = "OBJECT"
       
   475 
       
   476                 json_decl += "    _P##_"+decl_type+"(" + field_C_type + ", " + field_C_name + ", " + field_name + ", _A)"
       
   477                 if idx != last:
       
   478                     json_decl += " _P##_separator \\"
       
   479                 else:
       
   480                     json_decl += "\n"
       
   481                 json_decl += "\n"
       
   482 
       
   483 
   511 
   484             formatdict["json_decl"] += json_decl
   512             formatdict["json_decl"] += json_decl
   485 
   513 
   486         for iec_type, instances in json_types.items():
   514         for iec_type, instances in json_types.items():
   487             C_type = iec_type.upper()
   515             C_type = iec_type.upper()