NTNU-IHB / PythonFMU

A lightweight framework that enables the packaging of Python3.x code as co-simulation FMUs
MIT License
130 stars 37 forks source link

Element 'ModelVariables': Missing child element(s). Expected is ( ScalarVariable ). #195

Closed till12mann closed 10 months ago

till12mann commented 10 months ago

I generated a FMU , but if i check it, i get the following error:

Validation failed. 1 problem was found: ERROR (line 22, column 0): Element 'ModelVariables': Missing child element(s). Expected is ( ScalarVariable ).

How do i fix this ? My code looks like this:

` import tkinter as tk from opcua import from opcua import ua from tkinter import from pythonfmu import Fmi2Causality,Fmi2Variability, Fmi2Slave, Boolean, Integer, Real, String, Fmi2Initial

class OpcUAFmu(Fmi2Slave):

def __init_(self, **kwargs):
    super().__init__(**kwargs)

    # configure the root window
    self.title('STÄUBLI Robotics - FMU Generator')
    self.geometry("500x500")

    self.Widgets()

def Widgets(self):
    tk.Label(master=self,text="OPC UA Server Address:").pack()

    #opcua_address=StringVar()
    address_entry = tk.Entry(self,textvariable=self.opcua_address,width=25)
    address_entry.focus_set()
    address_entry.pack()

    submit_btn = tk.Button(master=self, text="Generate FMU", command=self.on_submit())
    submit_btn.pack() 

    #Bind X
    self.protocol('WM_DELETE_WINDOW', self.on_closing)     

def create_fmu(opcua_address):
    slave=OpcUAFmu(guid='1234',instance_name="OpcUaFmu",opcua_address=opcua_address)

    opcua_client=Client(opcua_address)
    opcua_client.connect()
    print("Connected!")

    root=opcua_client.get_root_node()
    print("Root node is: {:s} ".format(str(root)))
    OpcUAFmu.browse_nodes(root,opcua_client)
    print("FMU should've been created!")

def browse_nodes(node,client):
    for childId in node.get_children():
        ch = client.get_node(childId)
        print(ch.get_node_class())

        if ch.get_node_class() == ua.NodeClass.Object:
            OpcUAFmu.browse_nodes(ch, client)
        elif ch.get_node_class() == ua.NodeClass.Variable:
            try:
                with open ("nodes1.txt", mode="a") as f:
                    if str(ch.get_browse_name()).find("FastIO") != -1:
                        f.write("\n {bn} is type {dt} and has value {val} ".format(
                        bn=ch.get_browse_name(),
                        dt=ch.get_data_type_as_variant_type(),
                        val=str(ch.get_value())))
                        f.write("\n")

                if ch.get_data_type_as_variant_type() == "VariantType.Boolean":
                    OpcUAFmu.register_variable(Boolean("{bn}".format(bn=ch.get_browse_name()),variability=Fmi2Variability.continuous,causality=Fmi2Causality.input, start=ch.get_value()))
                    print("Boolean added!")
                elif ch.get_data_type_as_variant_type() == "VariantType.Int32":
                    OpcUAFmu.register_variable(Integer("{bn}".format(bn=ch.get_browse_name()),variability=Fmi2Variability.continuous,causality=Fmi2Causality.input, start=ch.get_value()))
                    print("Int32 added!")
                elif ch.get_data_type_as_variant_type() == "VariantType.Float":
                    OpcUAFmu.register_variable(float("{bn}".format(bn=ch.get_browse_name()),variability=Fmi2Variability.continuous,causality=Fmi2Causality.input, start=ch.get_value()))
                    print("Float added!")
                elif ch.get_data_type_as_variant_type() == "VariantType.String":
                    OpcUAFmu.register_variable(String("{bn}".format(bn=ch.get_browse_name()),variability=Fmi2Variability.continuous,causality=Fmi2Causality.input, start=ch.get_value()))
                    print("String added!")
                elif ch.get_data_type_as_variant_type() == "VariantType.Double":
                    OpcUAFmu.register_variable(float("{bn}".format(bn=ch.get_browse_name()),variability=Fmi2Variability.continuous,causality=Fmi2Causality.input, start=ch.get_value()))
                    print("Double added!")
                elif ch.get_data_type_as_variant_type() == "VariantType.Float":
                    OpcUAFmu.register_variable(float("{bn}".format(bn=ch.get_browse_name()),variability=Fmi2Variability.continuous,causality=Fmi2Causality.input, start=ch.get_value()))
                    print("Float added!")

                print("{bn} is type {dt} and has value {val} ".format(
                        bn=ch.get_browse_name(),
                        dt=ch.get_data_type_as_variant_type(),
                        val=str(ch.get_value())))

            except ua.uaerrors.UaStatusCodeError as e:
                print(e)
                pass

def on_submit():
    opcua_address = "{ad}".format(
    ad=address_entry.get())
    print("Button pressed!")
    OpcUAFmu.create_fmu(opcua_address)
    #OpcUAFmu.root.quit()

def do_step(self, current_time, step_size):
    try:
        def browse_recursive(node,client):
            for childId in node.get_children():
                ch = self.opcua_client.get_node(childId)
                print(ch.get_node_class())

                if ch.get_node_class() == ua.NodeClass.Object:
                    browse_recursive(ch, )
                elif ch.get_node_class() == ua.NodeClass.Variable:
                    try:
                        with open ("nodes1.txt", mode="a") as f:
                            if str(ch.get_browse_name()).find("FastIO") != -1:
                                f.write("\n {bn} has value {val} ".format(
                                bn=ch.get_browse_name(),
                                val=str(ch.get_value())))
                                f.write("\n")
                    except ua.uaerrors.UaStatusCodeError as e:
                        print(e)
                        pass
    except Exception as e:
        print("Fehler beim Auslesen der OPC UA Nodes",e)
        pass
    return True

root = tk.Tk() root.title("OPC UA FMU Generator")

tk.Label(root,text="OPC UA Server Address:").pack()

opcua_address=StringVar() address_entry = tk.Entry(root,textvariable=opcua_address,width=25) opcua_address.set("opc.tcp://***") address_entry.focus_set() address_entry.pack()

submit_btn = tk.Button(root, text="Generate FMU", command=OpcUAFmu.on_submit()) submit_btn.pack()

root.mainloop()`

markaren commented 10 months ago

register_variable needs to be called as part of the constructor.