diff --git a/newmodeljsonparse.py b/newmodeljsonparse.py index 533f08093231bdc654e0191c38d54c62bf739aa0..8aa643a71945e668e6df4c6b586d74088de3b205 100644 --- a/newmodeljsonparse.py +++ b/newmodeljsonparse.py @@ -4,25 +4,63 @@ import sys import writefile as wf from collections import namedtuple +""" +This File takes the json structure and parses it, to pass it to writefile.py + Functions: measurementJsonDecod, parameterJsonDecod, functionJsonDecod, dimensionchange, getdatatypes, changerange, + getunit, getobjnames, getMeasurements, getParameters, getFunctions, searchlists, getdefaultvalue, + iskeythere, getInterfaceParam, getVariables, getFunctionVariables, getEvents, getStreams, buildComponents, + instantiate, instantiateComponents, main + + Classes: Measurement, Parameter, Function +""" #creates the constructor for the measurement-object with corresponding parameters def measurementJsonDecod(measurementdict): + """ + Method that takes a measurementdict and pareses it into an object. + :param measurementdict: Measurement variable as Dictionary + :return: Tuple with all valuessorted according to an object hook + """ return namedtuple('Measurement', measurementdict.keys())(*measurementdict.values()) #creates the constructor for the parameter-object with corresponding parameters def parameterJsonDecod(parameterdict): + """ + Method that takes a parametertdict and pareses it into an object. + :param parameterdict: Parameter variable as Dictionary + :return: Tuple with all valuessorted according to an object hook + """ return namedtuple('Parameter', parameterdict.keys())(*parameterdict.values()) #creates the constructor for the function-object with corresponding parameters def functionJsonDecod(functiondict): + """ + Method that takes a functiondict and pareses it into an object. + :param functiondict: Function as Dictionary + :return: Tuple with all valuessorted according to an object hook + """ return namedtuple('Function', functiondict.keys())(*functiondict.values()) #Measurement class that can be instantiated using JsonDecod functions class Measurement: + """ + Class for measurement variables, is instantiated using MeasurementJsonDecod. + """ def __init__(self, name, description, datatype, value, uuid, dimension, unit=None, range=None): + """ + Initializes Measurement object. + :param name: name of the measurement in the component + :param description: description of the measurement + :param datatype: datatype of the measurement + :param value: the value of the measurement object which is generated in getdefaultvalue + :param uuid: the uuid of the measurement + :param dimension: the dimension of the measurement changed in dimensionchange + :param unit: the unit of the measurement + :param range: the range of the measurement changed in changerange + """ self.name = name self.description = description self.datatype = datatype @@ -30,22 +68,33 @@ class Measurement: self.uuid = uuid self.dimension = dimension self.unit = unit - array = [] if self.datatype == "float": self.value = float(value) else: self.value = value -#Parameter class that can be instantiated using JsonDecod functions class Parameter: + """ + Class for Parameter objects, is inatatntiated using parameterJsonDecod. + """ def __init__(self, name, description, datatype, dimension, value, uuid, rangevar=None, unit=None, default=None, constant=False): + """ + Initializes parameter object. + :param name: parameter name + :param description: parameter description + :param datatype: parameter datatype + :param dimension: parameter dimension changed in dimensionchange + :param value: parameter value generated in getdefaultvalue + :param uuid: parameter uuid + :param rangevar: parameter range (if not known before added in changerange) + :param unit: parameter unit (if not known before added in changerange) + :param default: parameter default value + :param constant: is the parameter constant or not + """ self.name = name self.description = description self.datatype = datatype - # if range == [None, None]: - # self.range = None - # else: self.range = rangevar self.uuid = uuid self.dimension = dimension @@ -53,22 +102,21 @@ class Parameter: self.default = default self.constant = constant self.value = value - # array = [] - # calculate a start value - # if self.default == False: - # if self.dimension != 0: - # for i in range(self.dimension): - # array.append(self.datatype((self.range[0] + self.range[1]) / 2)) - # self.value = array - # else: - # self.value = self.datatype(((self.range[0] + self.range[1]) / 2)) - # else: - # self.value = self.datatype(default) - - -#Function class that can be instantiated using JsonDecod functions + + class Function: + """ + Class for Function objects, is instantiated using JsonDecode functions + """ def __init__(self, name, description, uuid, inargsdatatypes = None, outargsdatatypes = None): + """ + Initializes function object. + :param name: function name + :param description: function description + :param uuid: function uuid + :param inargsdatatypes: List of Datatypes of all arguments + :param outargsdatatypes: List of dataytypes of all returns + """ self.name = name self.description = description self.uuid = uuid @@ -129,12 +177,16 @@ def getobjnames(argarray): #returns a list of all the parameters as objects -def getParameters(parametersDict): +def getParameters(parametersDict, variablelist): # extracts the measurements of a Json-Mode parameterobj = [] if len(parametersDict) > 0: for i in parametersDict: - obj = i + obj = i.copy() + for var in variablelist: + if obj["uuid"] == var["value"]: + obj["name"] = var["name"] + variablelist.remove(var) obj = dimensionchange(obj) obj["value"] = getdefaultvalue(obj) obj = changerange(obj) @@ -146,7 +198,7 @@ def getParameters(parametersDict): #returns a list of all the measurements as objects -def getMeasurements(measurementsDict): +def getMeasurements(measurementsDict, variablelist): measurementobj = [] if len(measurementsDict) > 0: for i in measurementsDict: @@ -184,7 +236,6 @@ def getFunctions(functionsDict, jsonmeasurements, jsonparameters): def searchlists(list1, list2): - #print("I am searching") objmeasurementlist = [] if len(list1) <= 0: return [] @@ -225,13 +276,6 @@ def iskeythere(list, key): return False -def iteratingInterface(obj, dict, componentslist): - if iskeythere(list(obj.keys()), "baseComponent"): - for searchobj in componentslist: - if searchobj["uuid"] == obj["baseComponent"]: - wf.writeinterface(componentslist[searchobj["name"]], searchobj["name"], 0) - - def getInterfaceparam(list1, interface, searched, jsoncomponents, searchinglist): for inputsearch in interface[searched]: for searchobj in searchinglist: @@ -244,47 +288,13 @@ def getInterfaceparam(list1, interface, searched, jsoncomponents, searchinglist) else: return list1 - -def getVariables(list1, interface, jsoncomponents): - variablelist = interface["parameters"] + interface["measurements"] +def getComponentVarList(searched, list1, component, jsoncomponents): + variablelist = component[searched] list1 = list1 + variablelist - if iskeythere(list(interface.keys()), "baseComponent"): - for component in jsoncomponents: - if component["uuid"] == interface["baseComponent"]: - return getVariables(list1, component, jsoncomponents) - else: - return list1 - - -def getFunctionVariables(list1, interface, jsoncomponents): - variablelist = interface["functions"] - list1 = list1 + variablelist - if iskeythere(list(interface.keys()), "baseComponent"): - for component in jsoncomponents: - if component["uuid"] == interface["baseComponent"]: - return getFunctionVariables(list1, component, jsoncomponents) - else: - return list1 - - -def getEvents(list1, component, jsoncomponents): - for event in component["events"]: - list1.append(event) - if iskeythere(list(component.keys()), "baseComponent"): - for search in jsoncomponents: - if search["uuid"] == component["baseComponent"]: - return getEvents(list1, search, jsoncomponents) - else: - return list1 - - -def getStreams(list1, component, jsoncomponents): - for stream in component["streams"]: - list1.append(stream) if iskeythere(list(component.keys()), "baseComponent"): for search in jsoncomponents: if search["uuid"] == component["baseComponent"]: - return getEvents(list1, search, jsoncomponents) + return getComponentVarList(searched, list1, search, jsoncomponents) else: return list1 @@ -302,60 +312,71 @@ def buildComponents(interfacesreturn, variabledict, jsoninterfaces, jsoncomponen continue objcomponentslist = getInterfaceparam([], rootobj, "components", jsoncomponents, jsoncomponents) if obj["name"] not in interfacesreturn.keys(): - interfacesreturn[str(obj["name"])] = wf.openobject(obj["name"], rootobj["description"]) + interfacesreturn[str(obj["uuid"])] = wf.openobject(obj["name"], rootobj["description"]) objmeasurementlist = getInterfaceparam([], rootobj, "measurements", jsoncomponents, jsonmeasurements) - #print(objmeasurementlist) - measurementsobjs = getMeasurements(objmeasurementlist) - wf.writemeasurement(measurementsobjs, interfacesreturn[str(obj["name"])], enumnodedict, enumvalues, enumnames) - variablelist = getVariables([], rootobj, jsoncomponents) - variabledict[obj["uuid"]] = variablelist + measurementlist = getComponentVarList("measurements", [], rootobj, jsoncomponents) + parameterlist = getComponentVarList("parameters", [], rootobj, jsoncomponents) + #variablelist = measurementlist + parameterlist + measurementsobjs = getMeasurements(objmeasurementlist, measurementlist.copy()) + wf.writemeasurement(measurementsobjs, interfacesreturn[str(obj["uuid"])], enumnodedict, enumvalues, enumnames, measurementlist.copy()) + #variabledict[obj["uuid"]] = variablelist objparameterlist = getInterfaceparam([], rootobj, "parameters", jsoncomponents, jsonparameters) - parameterobjs = getParameters(objparameterlist) - wf.writeparameter(parameterobjs, interfacesreturn[str(obj["name"])], enumnodedict, enumvalues, enumnames) + parameterobjs = getParameters(objparameterlist, parameterlist.copy()) + wf.writeparameter(parameterobjs, interfacesreturn[str(obj["uuid"])], enumnodedict, enumvalues, enumnames, parameterlist.copy()) objfunctionlist = getInterfaceparam([], rootobj, "functions", jsoncomponents, jsonfunctions) functionobj = getFunctions(objfunctionlist, jsonparameters, jsonmeasurements) - functionvars = getFunctionVariables([], rootobj, jsoncomponents) - wf.writefunction(functionobj, interfacesreturn[str(obj["name"])], functionvars) + functionvars = getComponentVarList("functions", [], rootobj, jsoncomponents) + wf.writefunction(functionobj, interfacesreturn[str(obj["uuid"])], functionvars.copy()) buildComponents(interfacesreturn, variabledict, objcomponentslist, jsoncomponents, jsonmeasurements, jsonparameters, jsonfunctions, objcomponentsclone, enumnodedict, enumvalues, enumnames) - return interfacesreturn, variabledict + return interfacesreturn #, variabledict -def instantiateComponents(typesdict, interfaces, jsoncomponents, headnode, instantiatedict, eventsdict, streamsdict): +def instantiateComponents(typesdict, interfaces, jsoncomponents, instantiatedict, eventsdict, streamsdict, componentlist, headnodeindex, variabledict): count = 0 countcomponent = 0 for interface in interfaces: root = interface - events = getEvents([], root, jsoncomponents) - streams = getStreams([], root, jsoncomponents) + interfacename = "" + newcomponentlist = getComponentVarList("components", [], root, jsoncomponents) + for cobj in componentlist: + if cobj["value"] == root["uuid"]: + interfacename = cobj["name"] + componentlist.remove(cobj) + break + events = getComponentVarList("events", [], root, jsoncomponents) + streams = getComponentVarList("streams", [], root, jsoncomponents) + variables = getComponentVarList("measurements", [], root, jsoncomponents) + getComponentVarList("parameters", [], root, jsoncomponents) + variabledict[interfacename] = variables components = getInterfaceparam([], root, "components", jsoncomponents, jsoncomponents) - if interface["name"] in list(instantiatedict.keys()): - count += 1 - instantiatedict[str(interface["uuid"])] = wf.writeobjects(typesdict[str(interface["name"])], interface["name"], instantiatedict[str(headnode["uuid"])], count) - eventsdict[str(interface["uuid"])] = events - streamsdict[str(interface["uuid"])] = streams + instantiatedict[str(interfacename)] = wf.writeobjects(typesdict[str(interface["uuid"])], interfacename, instantiatedict[str(headnodeindex)]) + eventsdict[str(interfacename)] = events + streamsdict[str(interfacename)] = streams if len(components) > 0: - instantiateComponents(typesdict, components, jsoncomponents, interface, instantiatedict, eventsdict, streamsdict) + instantiateComponents(typesdict, components, jsoncomponents, instantiatedict, eventsdict, streamsdict, newcomponentlist, interfacename, variabledict) - return instantiatedict, eventsdict, streamsdict + return instantiatedict, eventsdict, streamsdict, variabledict def instantiate(typesdict, interfaces, jsoncomponents): instantiatedict = {} eventsdict = {} streamsdict ={} + variabledict = {} for interface in interfaces: root = {} - count = 0 for component in jsoncomponents: if interface["rootComponent"] == component["uuid"]: root = component - events = getEvents([], root, jsoncomponents) - streams = getStreams([], root, jsoncomponents) + events = getComponentVarList("events", [], root, jsoncomponents) + streams = getComponentVarList("streams", [], root, jsoncomponents) + variables = getComponentVarList("measurements", [], root, jsoncomponents) + getComponentVarList("parameters", [], root, jsoncomponents) + variabledict[interface["uuid"]] = variables components = getInterfaceparam([], root, "components", jsoncomponents, jsoncomponents) - instantiatedict[str(interface["uuid"])] = wf.writeinterface(typesdict[str(interface["name"])], interface["name"]) + instantiatedict[str(interface["uuid"])] = wf.writeinterface(typesdict[str(interface["uuid"])], interface["name"]) eventsdict[str(interface["uuid"])] = events streamsdict[str(interface["uuid"])] = streams - return instantiateComponents(typesdict, components, jsoncomponents, interface, instantiatedict, eventsdict, streamsdict) + newcomponentlist = getComponentVarList("components", [], root, jsoncomponents) + return instantiateComponents(typesdict, components, jsoncomponents, instantiatedict, eventsdict, streamsdict, newcomponentlist, interface["uuid"], variabledict) def main(): @@ -398,13 +419,14 @@ def main(): enumnodedict = returnvalenums[0] enumvalues = returnvalenums[1] enumnames = returnvalenums[2] - returnComponents = buildComponents({}, {}, jsoninterfaces, jsoncomponents, jsonmeasurements, jsonparameters, jsonfunctions, [], enumnodedict, enumvalues, enumnames) - typesdict = returnComponents[0] - variabledict = returnComponents[1] + typesdict = buildComponents({}, {}, jsoninterfaces, jsoncomponents, jsonmeasurements, jsonparameters, jsonfunctions, [], enumnodedict, enumvalues, enumnames) + #typesdict = returnComponents[0] + #variabledict = returnComponents[1] returnval = instantiate(typesdict, jsoninterfaces, jsoncomponents) instantiatedict = returnval[0] eventsdict = returnval[1] streamsdict = returnval[2] + variabledict = returnval[3] generatordict = {} streamgendict = {} savestreamvaldict = {} diff --git a/writefile.py b/writefile.py index f38cdff50caaf9498c6caf519a064271a2dd450b..d33ab50bd5409554723a22a5733c668a66df796e 100644 --- a/writefile.py +++ b/writefile.py @@ -26,7 +26,7 @@ def defFunction(functionname, file, indent, inargs, function): file.write(writeindent + "async def " + functionname + "(parent") if inargs is not None: file.write(", ") - for i in range (len(inargs)): + for i in range(len(inargs)): if i < (len(inargs) - 1): file.write(inargs[i] + ", ") else: @@ -162,7 +162,7 @@ def openobject(objname, description): return objtypename -def writemeasurement(measurementobj, headnode, enumnodedict, enumvaldict, enumvariantdict): +def writemeasurement(measurementobj, headnode, enumnodedict, enumvaldict, enumvariantdict, varlist): #ToDo: Schauen ob man returns rausnehmen kann """ Creates the measurement variables with their properties @@ -179,10 +179,18 @@ def writemeasurement(measurementobj, headnode, enumnodedict, enumvaldict, enumva if len(measurementobj) > 0: server.write(writeindent + "# measurements for " + headnode + "\n") for i in measurementobj: - varname = ((i.name).lower()).replace(" ", "") + "var" + # varname = ((i.name).lower()).replace(" ", "") + "var" + varname = "" + measname = "" + for fobj in varlist: + if fobj["value"] == i.uuid: + measname = fobj["name"] + varname = (fobj["name"].lower()).replace(" ", "") + varlist.remove(fobj) + break if i.datatype == "enum": measurementdict[i.name] = varname - server.write(writeindent + varname + " = await " + headnode + ".add_variable(idx, \"" + i.name + "\", " + i.value + ", datatype=" + enumnodedict[i.uuid] + ".nodeid)\n") + server.write(writeindent + varname + " = await " + headnode + ".add_variable(idx, \"" + measname + "\", " + i.value + ", datatype=" + enumnodedict[i.uuid] + ".nodeid)\n") server.write(writeindent + "await " + varname + "." + "set_modelling_rule(True)\n") count = 0 for value in enumvaldict[i.uuid]: @@ -194,7 +202,7 @@ def writemeasurement(measurementobj, headnode, enumnodedict, enumvaldict, enumva varianttype = getVariantType(i.datatype) datatype = "measurementtype.nodeid" server.write(writeindent + varname + " = " + "await " + headnode + ".add_variable(idx, \"" + str( - i.name) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") + measname) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") server.write(writeindent + "await " + varname + "." + "set_modelling_rule(True)\n") if i.range is not None and i.range != [None, None]: rangename = "rangeprop" @@ -207,10 +215,10 @@ def writemeasurement(measurementobj, headnode, enumnodedict, enumvaldict, enumva server.write(writeindent + "await " + unitname + ".set_modelling_rule(True)\n") server.write( writeindent + varname + "description = await " + varname + ".add_property(idx, \"Description\", " + "\"" + i.description + "\")" + "\n") - server.write(writeindent + "await "+ varname + "description.set_modelling_rule(True)\n\n") + server.write(writeindent + "await " + varname + "description.set_modelling_rule(True)\n\n") -def writeparameter(parameterobj, headnode, enumnodedict, enumvaldict, enumvariantdict): +def writeparameter(parameterobj, headnode, enumnodedict, enumvaldict, enumvariantdict, parameterlist): """ Creates the parameter values. (Similar to writemeasurement) :param parameterobj: A list of the objparameters @@ -226,9 +234,17 @@ def writeparameter(parameterobj, headnode, enumnodedict, enumvaldict, enumvarian if len(parameterobj) > 0: server.write(writeindent + "# parameters for " + headnode + "\n") for i in parameterobj: + #varname = (i.name.lower()).replace(" ", "") + "var" + varname = "" + parname = "" + for fobj in parameterlist: + if fobj["value"] == i.uuid: + parname = fobj["name"] + varname = (fobj["name"].lower()).replace(" ", "") + parameterlist.remove(fobj) + break if i.datatype == "enum": - varname = (i.name.lower()).replace(" ", "") + "var" - server.write(writeindent + varname + " = await " + headnode + ".add_variable(idx, \"" + i.name + "\", " + i.value + ", datatype=" + enumnodedict[i.uuid] + ".nodeid)\n") + server.write(writeindent + varname + " = await " + headnode + ".add_variable(idx, \"" + parname + "\", " + i.value + ", datatype=" + enumnodedict[i.uuid] + ".nodeid)\n") server.write(writeindent + "await " + varname + "." + "set_modelling_rule(True)\n") count = 0 for value in enumvaldict[i.uuid]: @@ -239,10 +255,10 @@ def writeparameter(parameterobj, headnode, enumnodedict, enumvaldict, enumvarian else: varianttype = getVariantType(i.datatype) datatype = "parametertype.nodeid" - varname = ((i.name).lower()).replace(" ", "") + "var" + #varname = ((i.name).lower()).replace(" ", "") + "var" parameterdict[i.name] = varname server.write(writeindent + varname + " = " + "await " + headnode + ".add_variable(idx, \"" + str( - i.name) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") + parname) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") server.write(writeindent + "await " + varname + "." + "set_modelling_rule(True)\n") if i.range is not None and i.range != [None, None]: rangename = "rangeprop" @@ -271,11 +287,11 @@ def writefunction(functionobj, headnode, functionlist): server = open("opcua-server.py", "a") writeindent = " " functionname = "" + funcname = "" for i in functionobj: - print(i) for fobj in functionlist: if fobj["value"] == i.uuid: - print(fobj["name"]) + funcname = fobj["name"] functionname = (fobj["name"].lower()).replace(" ", "") functionlist.remove(fobj) break @@ -290,12 +306,11 @@ def writefunction(functionobj, headnode, functionlist): for j in i.outargsdataypes: inargslist.append(getVariantType(j)) methodvarname = functionname + "var" - server.write(writeindent + methodvarname + " = await " + headnode + ".add_method(idx, \"" + i.name +"\", " + functionname + ", " + str(inargslist) + ", "+ str(outargslist) + ")\n\n") + server.write(writeindent + methodvarname + " = await " + headnode + ".add_method(idx, \"" + funcname +"\", " + functionname + ", " + str(inargslist) + ", "+ str(outargslist) + ")\n\n") server.write(writeindent + "await " + methodvarname + ".set_modelling_rule(True)\n\n") -def writeobjects(objtype, objname, headnode, count): - #ToDo: Implement count or cut it out +def writeobjects(objtype, objname, headnode): """ Generates the objects of the components. :param objtype: The node of the node with the objecttype @@ -307,8 +322,9 @@ def writeobjects(objtype, objname, headnode, count): """ server = open("opcua-server.py", "a") writeindent = " " + server.write(writeindent + "# creating object \n") - objtypename = (objname.lower()).replace(" ", "") + "var" + str(count) + objtypename = (objname.lower()).replace(" ", "") + "var" server.write( writeindent + objtypename + "= await " + headnode + ".add_object(idx, \"" + objname + "\", " + objtype + ".nodeid)\n\n") return objtypename @@ -455,12 +471,13 @@ def triggerevents(generatordict, eventslist, component, variablelist, jsonmeasur else: for variable in variablelist: if variable["name"] == event["element"]: - for measurement in jsonmeasurements: - if variable["value"] == measurement["uuid"]: - eventsearchname = measurement["name"] - for parameter in jsonparameters: - if variable["value"] == parameter["uuid"]: - eventsearchname = parameter["name"] + eventsearchname = variable["name"] + # for measurement in jsonmeasurements: + # if variable["value"] == measurement["uuid"]: + # eventsearchname = measurement["name"] + # for parameter in jsonparameters: + # if variable["value"] == parameter["uuid"]: + # eventsearchname = parameter["name"] variablenamelist[str(event["element"])] = eventsearchname server.write(writeindent + valuename + "= await " + component + ".get_child([\"2:" + eventsearchname + "\"])\n") dictname = (event["element"].lower()).replace(" ", "") + component + event["severity"] @@ -498,17 +515,18 @@ def triggerstreams(generatordict, streamslist, component, variablelist, jsonmeas for stream in streamslist: writeindent = "" streamname = "" - valuename = "stream" + ((stream["measurement"]).lower()).replace(" ", "") + valuename = "stream" + ((stream["measurement"]).lower()).replace(" ", "") + component for i in range(indent): writeindent += " " for variable in variablelist: if variable["name"] == stream["measurement"]: - for measurement in jsonmeasurements: - if measurement["uuid"] == variable["value"]: - streamname = measurement["name"] - for parameter in jsonparameters: - if parameter["uuid"] == variable["value"]: - streamname = parameter["name"] + streamname = variable["name"] + # for measurement in jsonmeasurements: + # if measurement["uuid"] == variable["value"]: + # streamname = measurement["name"] + # for parameter in jsonparameters: + # if parameter["uuid"] == variable["value"]: + # streamname = parameter["name"] server.write(writeindent + valuename + " = await " + component + ".get_child([\"2:" + streamname + "\"])\n") generatorname = generatordict[(stream["measurement"].lower()).replace(" ", "") + component] if stream["streamType"] == "update": @@ -522,8 +540,8 @@ def triggerstreams(generatordict, streamslist, component, variablelist, jsonmeas writeindent += " " if stream["streamType"] == "fixed": - server.write(writeindent + stream["measurement"] + "time = count % " + str(stream["intervalValue"]) + "\n") - server.write(writeindent + "if "+ stream["measurement"] + "time == 0:\n") + server.write(writeindent + stream["measurement"] + component + "time = count % " + str(stream["intervalValue"]) + "\n") + server.write(writeindent + "if "+ stream["measurement"] + component + "time == 0:\n") writeindent += " " server.write(writeindent + "puffer = await " + valuename + ".get_value()\n") server.write(writeindent + "await " + generatorname + ".trigger(message=\"" + stream["measurement"] + " value: \" + str(puffer))\n\n")