diff --git a/jsonparse.py b/jsonparse.py index bb7e5a36b024b6c2811990a8953c09d5d935a4fb..685d7cb3a3d765ccfb7c0fbb5091ecedc298be64 100644 --- a/jsonparse.py +++ b/jsonparse.py @@ -168,11 +168,63 @@ def createcomponent(jsonobj, iscomponent): obj = json.dumps(obj) functionobji = json.loads(obj, object_hook=functionJsonDecod) functionobj.append(functionobji) + print(functionobj) + print(parameterobj) + # exec(open("writefile.py").read()) + wf.writeinserver(jsonobj["name"], jsonobj["description"], measurementobj, parameterobj, functionobj, iscomponent) + + +def getParameters(parametersDict): + # extracts the measurements of a Json-Model + parameterobj = [] + if len(parametersDict) > 0: + for i in parametersDict: + obj = i + # del obj["value"] + del obj["uuid"] + dimensionchange(obj) + if i["range"]: + changerange(obj) + obj = json.dumps(i) + parameterobji = json.loads(obj, object_hook=parameterJsonDecod) + parameterobj.append(parameterobji) + return parameterobj + +def getMeasurements(measurementsDict): + #extracts the measurements of a Json-Model + measurementobj = [] + if len(measurementsDict) > 0: + for i in measurementsDict: + obj = i + #del obj["value"] + del obj["uuid"] + dimensionchange(obj) + #if i["range"]: + changerange(obj) + obj = json.dumps(i) + measurementobji = json.loads(obj, object_hook=measurementJsonDecod) + measurementobj.append(measurementobji) + return measurementobj + +def getComponents(components): + componentobj = [] + if len(components) > 0: + for i in components: + par = getParameters(i["parameters"]) + mea = getMeasurements(i["measurements"]) + comp = getComponents(i["components"]) + + obj = i + # del obj["value"] + del obj["uuid"] + obj = json.dumps(i) + componentobji = json.loads(obj) + componentobji['parameters'] = par + componentobji['measurements'] = mea + componentobji['components'] = comp + componentobj.append(componentobji) + return componentobj - print(functionobj) - print(parameterobj) - # exec(open("writefile.py").read()) - wf.writeinserver(jsonobj["name"], jsonobj["description"], measurementobj, parameterobj, functionobj, iscomponent) def main(): @@ -190,8 +242,9 @@ def main(): robotload = json.loads(file.read()) wf.writebeginning() createcomponent(robotload, False) - for i in robotload["components"]: - createcomponent(i, True) + components = robotload["components"] + componentobj = getComponents(components) + print(componentobj) wf.writend() diff --git a/newmodeljsonparse.py b/newmodeljsonparse.py new file mode 100644 index 0000000000000000000000000000000000000000..23f4136fff611f0ef5d0f2eb9bbdbfb41f29aa89 --- /dev/null +++ b/newmodeljsonparse.py @@ -0,0 +1,261 @@ +import json +import os +import sys +import writefile as wf +from collections import namedtuple + + +def measurementJsonDecod(measurementdict): + return namedtuple('Measurement', measurementdict.keys())(*measurementdict.values()) + + +def parameterJsonDecod(parameterdict): + return namedtuple('Parameter', parameterdict.keys())(*parameterdict.values()) + + +def functionJsonDecod(functiondict): + return namedtuple('Function', functiondict.keys())(*functiondict.values()) + + +class Measurement: + def __init__(self, name, description, datatype, value, dimension, unit=None, range=None): + self.name = name + self.description = description + self.datatype = datatype + self.range = range + self.dimension = dimension + self.unit = unit + array = [] + if self.datatype == "float": + self.value = float(value) + else: + self.value = value + # calculate a start value + # if self.dimension != 0: + # for i in range(self.dimension): + # arrayval = self.datatype((self.range[0] + self.range[1]) / 2) + # if self.datatype == "float" or self.datatype == "double": + # arrayval = float(arrayval) + # array.append(arrayval) + # self.value = [0.0, 0.0, 0.0] + # else: + # self.value = self.datatype(((self.range[0] + self.range[1]) / 2)) + +class Parameter: + def __init__(self, name, description, datatype, dimension, value, rangevar=None, unit=None, default=None, constant=False): + self.name = name + self.description = description + self.datatype = datatype + # if range == [None, None]: + # self.range = None + # else: + self.range = rangevar + self.dimension = dimension + self.unit = unit + 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) + +class Function: + def __init__(self, name, description, inargsdatatypes = None, outargsdatatypes = None): + self.name = name + self.description = description + self.inargsdatatypes = inargsdatatypes + self.outargsdatatypes = outargsdatatypes + +def dimensionchange(string): + dimarr = string["dimension"] + if dimarr: + value = dimarr[0] + else: + value = 0 + newdimension = {"dimension": value} + string.update(newdimension) + + +def getdatatypes(argarray): + returnarr = [] + if len(argarray) > 0: + for i in argarray: + returnarr.append(i["datatype"]) + return returnarr + else: + return None + + + +def changerange(string): + #print(type(string["range"][0])) + if string["range"] != "[None, None]": + rangeval = string["range"] + rangetuple = (rangeval[0], rangeval[1]) + #print(rangetuple) + string.update({"range": rangetuple}) + #print(string["range"]) + else: + del string["range"] + # print(string) + +def getParameters(parametersDict): + # extracts the measurements of a Json-Model + parameterobj = [] + if len(parametersDict) > 0: + for i in parametersDict: + obj = i + # del obj["value"] + #del obj["uuid"] + dimensionchange(obj) + obj["value"]=getdefaultvalue(obj["dimension"], obj["datatype"]) + obj = json.dumps(i) + parameterobji = json.loads(obj, object_hook=parameterJsonDecod) + parameterobj.append(parameterobji) + return parameterobj + +def getMeasurements(measurementsDict): + #extracts the measurements of a Json-Model + measurementobj = [] + if len(measurementsDict) > 0: + for i in measurementsDict: + obj = i + #del obj["value"] + #del obj["uuid"] + dimensionchange(obj) + obj["value"] = getdefaultvalue(obj["dimension"], obj["datatype"]) + #if i["range"]: + changerange(obj) + obj = json.dumps(i) + measurementobji = json.loads(obj, object_hook=measurementJsonDecod) + measurementobj.append(measurementobji) + return measurementobj + +def searchlists(list1, list2): + objmeasurementlist = [] + # print(obj["measurements"]) + if len(list1) <= 0: + return [] + for input in list1: + for searchobj in list2: + # print(measentrance) + if input["value"] == searchobj["uuid"]: + objmeasurementlist.append(searchobj) + return objmeasurementlist + +def getdefaultvalue(dimension, datatype): + if datatype == "float" or datatype == "double" or datatype == "int": + if dimension == 1: + return 0 + value = [] + for i in range(dimension): + value.append(0) + return value + else: + return True + +def iskeythere(list, key): + for keysearch in list: + if(keysearch == key): + return True + return False + + +def main(): + try: + JSON_MODEL = sys.argv[1][:-5] + if not os.path.exists(os.path.join('..', 'SOIL OPC-UA', f'{JSON_MODEL}.json')): + raise Exception() + except Exception as e: + print('You must provide a file from the folder to be used as root file of the parsing, e.g., "python jsonparser.py model.json".') + exit() + + with open(f'{JSON_MODEL}.json') as file: + + wf.writebeginning() + jsonobj = json.loads(file.read()) + elements = jsonobj["elements"] + if len(elements) <= 0: + exit() + jsonmeasurements = [] + jsonparameters = [] + jsonfunctions= [] + jsoncomponents= [] + jsoninterfaces = [] + for obj in elements: + if obj["elementType"] == "measurement": + jsonmeasurements.append(obj) + elif obj["elementType"] == "parameter": + jsonparameters.append(obj) + elif obj["elementType"] == "function": + jsonfunctions.append(obj) + elif obj["elementType"] == "component": + jsoncomponents.append(obj) + elif obj["elementType"] == "interface": + jsoninterfaces.append(obj) + + + componenttypesdict = {} + for obj in jsoncomponents: + #print(obj["name"]) + del obj["cardOpen"] + #del obj["uuid"] + objname = wf.openobject(obj["name"], obj["description"]) + componenttypesdict[str(obj["name"])] = objname + + if iskeythere(list(obj.keys()), "baseComponent"): + basecomponent = obj["baseComponent"] + for search in jsoncomponents: + #print(search["uuid"]) + if basecomponent == search["uuid"]: + wf.writebasecomponent(componenttypesdict[str(obj["name"])], componenttypesdict[str(search["name"])], search["name"]) + + + objcomponentslist = searchlists(obj["components"], jsoncomponents) + wf.writecomponents(componenttypesdict[obj["name"]], objcomponentslist, componenttypesdict) + objmeasurementlist = searchlists(obj["measurements"], jsonmeasurements) + measurementsobjs = getMeasurements(objmeasurementlist) + #print(objmeasurementlist) + wf.writemeasurement(measurementsobjs, componenttypesdict[str(obj["name"])]) + objparameterlist = searchlists(obj["parameters"], jsonparameters) + parameterobjs = getParameters(objparameterlist) + wf.writemeasurement(parameterobjs, componenttypesdict[str(obj["name"])]) + + for obj in jsoninterfaces: + for searchobj in jsoncomponents: + if searchobj["uuid"] == obj["rootComponent"]: + wf.writeinterface(componenttypesdict[searchobj["name"]], obj["name"]) + + + + wf.writend() + + + + + + # print("Measurements: ") + # print(jsonmeasurements) + # print("\n") + # print("Components: ") + # print(jsoncomponents) + # print("\n") + # print("Parameters: ") + # print(jsonparameters) + # print("\n") + # print("Functions: ") + # print(jsonfunctions) + + + + +if __name__ == '__main__': + main() diff --git a/writefile.py b/writefile.py index 634cf6ea189e760e5c281e42e9633be78e0eb419..a4a1ddbfe8d66975d48f7cc2d2d080a67d3d32bc 100644 --- a/writefile.py +++ b/writefile.py @@ -26,82 +26,132 @@ def getVariantType(datatype): elif datatype == "Boolean": varianttype = "ua.VariantType.Boolean" return varianttype -def writeinserver(objname, objdescription, measurementobj, parameterobj, functionobj, iscomponent): +def writebeginning(): + if os.path.exists("opcua-server.py"): + os.remove("opcua-server.py") server = open("opcua-server.py", "a") - indent = 1 - writeindent = "" - for j in range(indent): - writeindent = writeindent + " " + server.write("""import logging +import asyncio + +from asyncua import ua, Server +from asyncua.common.methods import uamethod +from asyncua.common.structures104 import new_struct, new_enum, new_struct_field +from asyncua.common import node + +logging.basicConfig(level=logging.INFO) +_logger = logging.getLogger('asyncua') +""") + + server.write("\nasync def main():") + #äinten = "\tab" + server.write(""" + # setup our server + server = Server() + await server.init() + server.set_endpoint('opc.tcp://0.0.0.0:4840/freeopcua/server/') + + # setup our own namespace, not really necessary but should as spec + uri = 'http://examples.freeopcua.github.io/' + idx = await server.register_namespace(uri) + #id of rangetype + rangeid = await server.nodes.base_data_type.get_child(["0:Structure", "0:Range"]) + + + + #creating dataypes for parameters and measurements + measurementtype = await server.nodes.base_data_type.add_data_type(idx, "Measurement") + parametertype = await server.nodes.base_data_type.add_data_type(idx, "Parameter") +""") +def openobject(objname, description): + server = open("opcua-server.py", "a") + writeindent = " " server.write(writeindent + "#creating the objecttype\n") objtypename = (objname.lower()).replace(" ", "") + "type" - server.write(writeindent + objtypename + "= await server.nodes.base_object_type.add_object_type(idx, \"" + objname + "\" )\n") + server.write(writeindent + objtypename + "= await server.nodes.base_object_type.add_object_type(idx, \"" + objname +"\" )\n") + return objtypename + +def writebasecomponent(headnode, objtype,name): + server = open("opcua-server.py", "a") + writeindent = " " + objname = objtype + "component" + server.write(writeindent + objname + " = await " + headnode + ".add_object(idx, \""+ name + "\", " + objtype + ".nodeid)\n") + server.write(writeindent + "await " + objname + "." + "set_modelling_rule(True)\n") - server.write("\n" + writeindent + "# creating all measurements with their properterties\n") +def writecomponents(headnode, componentslist, typesdict): + server = open("opcua-server.py", "a") + writeindent = " " + for component in componentslist: + objname = typesdict[component["name"]] + "component" + server.write(writeindent + objname + " = await " + headnode + ".add_object(idx, \""+ component["name"] + "\", " + typesdict[component["name"]] + ".nodeid)\n") + server.write(writeindent + "await " + objname + "." + "set_modelling_rule(True)\n") +def writemeasurement(measurementobj, headnode): + server = open("opcua-server.py", "a") + writeindent = " " measurementdict = {} for i in measurementobj: varianttype = getVariantType(i.datatype) datatype = "measurementtype.nodeid" varname = ((i.name).lower()).replace(" ", "") + "var" measurementdict[i.name] = varname - server.write(writeindent + varname + " = " + "await " + objtypename + ".add_variable(idx, \"" + str(i.name) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") + server.write(writeindent + varname + " = " + "await " + headnode + ".add_variable(idx, \"" + str( + i.name) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") server.write(writeindent + "await " + varname + "." + "set_modelling_rule(True)\n") - headnode = "" - if iscomponent: - headnode = objtypename - else: - headnode = varname - if i.range is not None and i.range is not "(None, None)": - rangename = "rangeprop" - server.write(writeindent + rangename + " = await " + headnode + ".add_property(idx, \"range\", ua.Range(" + str(i.range[0]) + "," + str(i.range[1]) + "))\n") - server.write(writeindent + "await " + rangename + ".set_modelling_rule(True)\n") - if i.unit != "UNITLESS": - unitname = "unitprop" - server.write(writeindent + unitname + " = await " + headnode + ".add_property(idx, \"unit\"," + "\"" + i.unit + "\")\n") - server.write(writeindent + "await " + unitname + ".set_modelling_rule(True)\n") - - server.write(writeindent + "description = await " + headnode + ".add_property(idx, \"Description\", " + "\"" + i.description + "\")" + "\n") - server.write(writeindent + "await description.set_modelling_rule(True)\n\n") + # if i.range is not None and i.range is not "(None, None)": + # rangename = "rangeprop" + # server.write( + # writeindent + rangename + " = await " + headnode + ".add_property(idx, \"range\", ua.Range(" + str( + # i.range[0]) + "," + str(i.range[1]) + "))\n") + # server.write(writeindent + "await " + rangename + ".set_modelling_rule(True)\n") + # if i.unit != "UNITLESS": + # unitname = "unitprop" + # server.write( + # writeindent + unitname + " = await " + headnode + ".add_property(idx, \"unit\"," + "\"" + i.unit + "\")\n") + # 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("\n" + writeindent + "#creating all parameters with their properties\n") + return measurementdict +def writeparameter(parameterobj, headnode): + writeindent = " " + server = open("opcua-server.py", "a") parameterdict = {} for i in parameterobj: varianttype = getVariantType(i.datatype) datatype = "parametertype.nodeid" varname = ((i.name).lower()).replace(" ", "") + "var" parameterdict[i.name] = varname - server.write(writeindent + varname + " = " + "await " + objtypename + ".add_variable(idx, \"" + str(i.name) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") + server.write(writeindent + varname + " = " + "await " + headnode + ".add_variable(idx, \"" + str( + i.name) + "\", " + str(i.value) + ", " + varianttype + ", " + datatype + ")\n") server.write(writeindent + "await " + varname + "." + "set_modelling_rule(True)\n") - if iscomponent: - headnode = objtypename - else: - headnode = varname - if i.range is not None and i.range is not (None, None): + if i.range is not None or i.range != (None, None): rangename = "rangeprop" - server.write(writeindent + rangename + " = await " + headnode + ".add_property(idx, \"range\", ua.Range(" + str(i.range[0]) + "," + str(i.range[1]) + "))\n") + server.write( + writeindent + rangename + " = await " + headnode + ".add_property(idx, \"range\", ua.Range(" + str( + i.range[0]) + "," + str(i.range[1]) + "))\n") server.write(writeindent + "await " + rangename + ".set_modelling_rule(True)\n") - if i.unit is not "UNITLESS": + if i.unit != "UNITLESS": unitname = "unitprop" - server.write(writeindent + unitname + " = await " + headnode + ".add_property(idx, \"unit\"," + "\"" + i.unit + "\")\n") + server.write( + writeindent + unitname + " = await " + headnode + ".add_property(idx, \"unit\"," + "\"" + i.unit + "\")\n") server.write(writeindent + "await " + unitname + ".set_modelling_rule(True)\n") - server.write(writeindent + "description = await " + headnode + ".add_property(idx, \"Description\", " + "\"" + i.description + "\")" + "\n") - server.write(writeindent + "await description.set_modelling_rule(True)\n\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") - objnamevar = (objname.lower()).replace(" ", "") - if(not iscomponent): - server.write(writeindent + objnamevar + "= await server.nodes.objects.add_object(idx, \"" + objname + "\"," + objtypename + ".nodeid)\n") - else: - server.write(writeindent + "headnodeid = await server.nodes.objects.get_child([\"2:Mobile Robot\"])\n") - server.write(writeindent + objnamevar + "= await headnodeid.add_object(idx,\"" + objname + "\")\n") - - server.write(writeindent + "#adding functions to our robot\n") +def writefunction(functionobj, headnode): + server = open("opcua-server.py", "a") + writeindent = " " for i in functionobj: functionname = (i.name.lower()).replace(" ", "") - defFunction(functionname, server, indent, i.inargsnames) + defFunction(functionname, server, 1, i.inargsnames) server.write("\n") inargslist = [] if i.inargsdatatypes != None: @@ -112,50 +162,20 @@ def writeinserver(objname, objdescription, measurementobj, parameterobj, functio for j in i.outargsdataypes: inargslist.append(getVariantType(j)) server.write(writeindent + "await mobilerobot.add_method(idx, \"" + i.name +"\", " + functionname + ", " + str(inargslist) + ", "+ str(outargslist) + ")\n\n") -def writebeginning(): - if os.path.exists("opcua-server.py"): - os.remove("opcua-server.py") - server = open("opcua-server.py", "a") - server.write("""import logging -import asyncio -from asyncua import ua, Server -from asyncua.common.methods import uamethod -from asyncua.common.structures104 import new_struct, new_enum, new_struct_field -from asyncua.common import node - -logging.basicConfig(level=logging.INFO) -_logger = logging.getLogger('asyncua') -""") - - server.write("\nasync def main():") - #äinten = "\tab" - server.write(""" - # setup our server - server = Server() - await server.init() - server.set_endpoint('opc.tcp://0.0.0.0:4840/freeopcua/server/') - - # setup our own namespace, not really necessary but should as spec - uri = 'http://examples.freeopcua.github.io/' - idx = await server.register_namespace(uri) - #id of rangetype - rangeid = await server.nodes.base_data_type.get_child(["0:Structure", "0:Range"]) - - - - #creating dataypes for parameters and measurements - measurementtype = await server.nodes.base_data_type.add_data_type(idx, "Measurement") - parametertype = await server.nodes.base_data_type.add_data_type(idx, "Parameter") -""") +def writeinterface(objtype, objname): + server = open("opcua-server.py", "a") + writeindent = " " + objtypename = (objname.lower()).replace(" ","") + "var" + server.write(writeindent + objtypename + "= await server.nodes.objects.add_object(idx, \"" + objname + "\", " + objtype + ".nodeid)\n") def writend(): server = open("opcua-server.py", "a") server.write(""" async with server: print("Server is running!") - + while True: await asyncio.sleep(1) @@ -167,3 +187,5 @@ if __name__ == '__main__': + +