OpenPLC中的库在代码中的定义

122 阅读2分钟
  • 在iec_std.csv文件中

image.png image.png

  • 在OpenPLC软件中

image.png

  • 在difinitions.py文件中 image.png

  • 在structures.py文件中

  1. csv_file_to_table函数:返回这个表示CSV文件内容的二维表格
  2. get_standard_funtions函数:最终生成一个符合程序要求的标准函数定义列表
def get_standard_funtions(table):
    """
    Returns this kind of declaration for all standard functions

            [{"name" : "Numerical", 'list': [   {
                'baseinputnumber': 1,
                'comment': 'Addition',
                'extensible': True,
                'inputs': [   ('IN1', 'ANY_NUM', 'none'),
                              ('IN2', 'ANY_NUM', 'none')],
                'name': 'ADD',
                'outputs': [('OUT', 'ANY_NUM', 'none')],
                'type': 'function'}, ...... ] },.....]
    """

    variables = get_standard_funtions_input_variables(table)

    fonctions = find_section("Standard_functions_type", table)

    Standard_Functions_Decl = []
    Current_section = None

    translate = {
        "extensible": lambda x: {"yes": True, "no": False}[x],
        "inputs": lambda x: csv_input_translate(x, variables, baseinputnumber),
        "outputs": lambda x: [("OUT", x, "none")]}

    for fields in table:
        if fields[1]:
            # If function section name given
            if fields[0]:
                words = fields[0].split('"')
                if len(words) > 1:
                    section_name = words[1]
                else:
                    section_name = fields[0]
                Current_section = {"name": section_name, "list": []}
                Standard_Functions_Decl.append(Current_section)
            if Current_section:
                Function_decl = dict([(champ, val) for champ, val in zip(fonctions, fields[1:]) if champ])
                baseinputnumber = int(Function_decl.get("baseinputnumber", 1))
                Function_decl["baseinputnumber"] = baseinputnumber
                for param, value in Function_decl.iteritems():
                    if param in translate:
                        Function_decl[param] = translate[param](value)
                Function_decl["type"] = "function"

                if Function_decl["name"].startswith('*') or Function_decl["name"].endswith('*'):
                    input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
                    output_types = GetSubTypes(Function_decl["outputs"][0][1])
                else:
                    input_ovrloading_types = [None]
                    output_types = [None]

                funcdeclname_orig = Function_decl["name"]
                funcdeclname = Function_decl["name"].strip('*_')
                fdc = Function_decl["inputs"][:]
                for intype in input_ovrloading_types:
                    if intype is not None:
                        Function_decl["inputs"] = []
                        for decl_tpl in fdc:
                            if IsOfType(intype, decl_tpl[1]):
                                Function_decl["inputs"] += [(decl_tpl[0], intype, decl_tpl[2])]
                            else:
                                Function_decl["inputs"] += [(decl_tpl)]

                            if funcdeclname_orig.startswith('*'):
                                funcdeclin = intype + '_' + funcdeclname
                            else:
                                funcdeclin = funcdeclname
                    else:
                        funcdeclin = funcdeclname

                    for outype in output_types:
                        if outype is not None:
                            decl_tpl = Function_decl["outputs"][0]
                            Function_decl["outputs"] = [(decl_tpl[0], outype,  decl_tpl[2])]
                            if funcdeclname_orig.endswith('*'):
                                funcdeclout = funcdeclin + '_' + outype
                            else:
                                funcdeclout = funcdeclin
                        else:
                            funcdeclout = funcdeclin
                        Function_decl["name"] = funcdeclout

                        # apply filter given in "filter" column
                        filter_name = Function_decl["filter"]
                        store = True
                        for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name, []):
                            outs = reduce(lambda a, b: a or b,
                                          map(lambda testtype: IsOfType(
                                              Function_decl["outputs"][0][1],
                                              testtype), OutTypes))
                            inps = reduce(lambda a, b: a or b,
                                          map(lambda testtype: IsOfType(
                                              Function_decl["inputs"][0][1],
                                              testtype), InTypes))
                            if inps and outs and Function_decl["outputs"][0][1] != Function_decl["inputs"][0][1]:
                                store = True
                                break
                            else:
                                store = False
                        if store:
                            # create the copy of decl dict to be appended to section
                            Function_decl_copy = Function_decl.copy()
                            Current_section["list"].append(Function_decl_copy)
            else:
                raise ValueError("First function must be in a category")

    return Standard_Functions_Decl
  • 其他库的xml文件

image.png

  1. xml文件孩子节点读取错误:去掉头结点的xmlns

image.png 2. 中文乱码:

image.png

OpenPLC已展示的库对应的文件
  1. iec_std.csv(函数)
  2. Standard_Function_Blocks.xml
  3. Additional_Function_Blocks.xml
  4. Arduino_Function_Blocks.xml
  5. Communication_Blocks.xml
  6. P1AM.xml
OpenPLC未展示的库对应的文件
  1. MQTT.xml
  2. SM_Cards.xml
  3. Jaguar.xml