Commit 367c869f authored by Gino Tosti's avatar Gino Tosti
Browse files

added generation of methods for server model

parent 41b04177
Loading
Loading
Loading
Loading

GenDevice/excelIcd.py

100644 → 100755
+11 −11
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ class excelIcd:
		self.SetSheet={}
		self.CmdSheet={}
		self.ModeSheet={}
		self.MethodsSheet={}
		self.debug=False
		self._getExcelWorkbook()
	def setDebugModeOn(self):
@@ -44,7 +45,10 @@ class excelIcd:
		self.SetSheet=self.getSheet("SET")
		self.CmdSheet=self.getSheet("CMD")
		self.ModeSheet=self.getSheet("MODE")
		
		if "Methods" in self.book.sheet_names:
			self.MethodsSheet=self.sheets["Methods"]
		else:
			self.MethodsSheet=None

	def getMain(self):
		self.sheets["Main"].columns=self.sheets["Main"].iloc[0]
@@ -93,7 +97,3 @@ class excelIcd:
		except:
			print("sheet:",name,"does not exist")
			return None



+364 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd">
<!-- *  Generated by: $Author
 *  Date: $Date
 *  Description: $Description !-->

#set $ns=$str(int($ns)-1)
#set $rr=$int($ns)
<NamespaceUris>
#for $i in $range(0,$rr-1)
          <Uri>http://localhost/$Assembly$str($i)/</Uri>
#end for
	  <Uri>http://localhost/$Assembly/</Uri>
</NamespaceUris>

<Aliases>
<Alias Alias="Boolean">i=1</Alias>
<Alias Alias="SByte">i=2</Alias>
<Alias Alias="Byte">i=3</Alias>
<Alias Alias="Int16">i=4</Alias>
<Alias Alias="UInt16">i=5</Alias>
<Alias Alias="Int32">i=6</Alias>
<Alias Alias="UInt32">i=7</Alias>
<Alias Alias="Int64">i=8</Alias>
<Alias Alias="UInt64">i=9</Alias>
<Alias Alias="Float">i=10</Alias>
<Alias Alias="Double">i=11</Alias>
<Alias Alias="DateTime">i=13</Alias>
<Alias Alias="String">i=12</Alias>
<Alias Alias="ByteString">i=15</Alias>
<Alias Alias="Guid">i=14</Alias>
<Alias Alias="XmlElement">i=16</Alias>
<Alias Alias="NodeId">i=17</Alias>
<Alias Alias="ExpandedNodeId">i=18</Alias>
<Alias Alias="QualifiedName">i=20</Alias>
<Alias Alias="LocalizedText">i=21</Alias>
<Alias Alias="StatusCode">i=19</Alias>
<Alias Alias="Structure">i=22</Alias>
<Alias Alias="Number">i=26</Alias>
<Alias Alias="Integer">i=27</Alias>
<Alias Alias="UInteger">i=28</Alias>
<Alias Alias="HasComponent">i=47</Alias>
<Alias Alias="HasProperty">i=46</Alias>
<Alias Alias="Organizes">i=35</Alias>
<Alias Alias="HasEventSource">i=36</Alias>
<Alias Alias="HasNotifier">i=48</Alias>
<Alias Alias="HasSubtype">i=45</Alias>
<Alias Alias="HasTypeDefinition">i=40</Alias>
<Alias Alias="HasModellingRule">i=37</Alias>
<Alias Alias="HasEncoding">i=38</Alias>
<Alias Alias="HasDescription">i=39</Alias>
<Alias Alias="Range">i=884</Alias>
<Alias Alias="Argument">i=296</Alias>
</Aliases>
#silent L=[]
#silent N=[]
#silent T=[]
<UAObject NodeId="ns=${ns};i=1" BrowseName="${ns}:${Assembly}Folder">
  <DisplayName>${Assembly}</DisplayName>
  <Description>The folder of the Assembly</Description>
  <References>
      <Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
      <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
  </References>
</UAObject>
<UAObject NodeId="ns=${ns};i=2" BrowseName="${ns}:${Assembly}_Get_Points" ParentNodeId="ns=${ns};i=1">
  <DisplayName>${Assembly} Monitoring Variables</DisplayName>
  <Description>The folder of the Assembly Monitoring Variables</Description>
  <References>
      <Reference ReferenceType="Organizes" IsForward="false">ns=${ns};i=1</Reference>
      <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
#for $idx in $range(0,$x["NRows"])
#set $ss=$x['OPC_UA node'][$idx].split(";")
	<Reference ReferenceType="HasProperty">ns=${ns};$ss[1]</Reference>
#end for
  </References>
</UAObject>
<UAObject NodeId="ns=${ns};i=3" BrowseName="${ns}:${Assembly}_Set_Points" ParentNodeId="ns=${ns};i=1">
  <DisplayName>${Assembly} Setting Variables</DisplayName>
  <Description>The folder of the Assembly Setting Variables</Description>
  <References>
      <Reference ReferenceType="Organizes" IsForward="false">ns=${ns};i=1</Reference>
      <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
#for $idx in $range(0,$y["NRows"])
#set $ss=$y['OPC_UA node'][$idx].split(";")
	<Reference ReferenceType="HasProperty">ns=${ns};$ss[1]</Reference>
#end for
  </References>
</UAObject>
<UAObject NodeId="ns=${ns};i=4" BrowseName="${ns}:${Assembly}_Mode_cmd" ParentNodeId="ns=${ns};i=1">
  <DisplayName>${Assembly} Mode Variables</DisplayName>
  <Description>The folder of the Assembly Setting Variables</Description>
  <References>
      <Reference ReferenceType="Organizes" IsForward="false">ns=${ns};i=1</Reference>
      <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
#for $idx in $range(0,$m["NRows"])
#if not $m['OPC_UA node'][$idx] in T
#set $ss=$m['OPC_UA node'][$idx].split(";")
	<Reference ReferenceType="HasProperty">ns=${ns};$ss[1]</Reference>
#silent T.append($m['OPC_UA node'][$idx])
#end if
#end for
  </References>
</UAObject>
<UAObject NodeId="ns=${ns};i=5" BrowseName="${ns}:${Assembly}_Commands" ParentNodeId="ns=${ns};i=1">
  <DisplayName>${Assembly} Command Variables</DisplayName>
  <Description>The folder of the Assembly Monitoring Variables</Description>
  <References>
      <Reference ReferenceType="Organizes" IsForward="false">ns=${ns};i=1</Reference>
      <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
#for $idx in $range(0,$c["NRows"])
#if not $c['OPC_UA node'][$idx] in T
#set $ss=$c['OPC_UA node'][$idx].split(";")
	<Reference ReferenceType="HasProperty">ns=${ns};$ss[1]</Reference>
#silent T.append($c['OPC_UA node'][$idx])
#end if
#end for
  </References>
</UAObject>

#for $idx in $range(0,$x["NRows"])
#silent L.append($x["Short name"][$idx])
#if not $x['OPC_UA node'][$idx] in N
#set $ss=$x['OPC_UA node'][$idx].split(";")
#if ($x["OPC UA Data type"][$idx]).upper()[-1]==']' ## test for arrays
 #set $sp=($x["OPC UA Data type"][$idx].upper()).split("[")
 #set $type=$sp[0].capitalize()
    #if $type[0]=="U"
	#set $type=$type.replace("i","I")
  #end if
 #set $dim=$sp[1].replace("]","")
<UAVariable ArrayDimensions="$dim" NodeId="ns=${ns};$ss[1]" BrowseName="${ns}:$x['Name of command'][$idx]" DataType="$type" ParentNodeId="ns=${ns};i=2" ValueRank="1">
  <DisplayName>$x['Name of command'][$idx]</DisplayName>
  <Description>$x['Description'][$idx]</Description>
  <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=${ns};i=2</Reference>
  </References>
</UAVariable>
#else
  #set $type=$x["OPC UA Data type"][$idx].capitalize()
    #if $type[0]=="U"
	#set $type=$type.replace("i","I")
  #end if
<UAVariable NodeId="ns=${ns};$ss[1]" BrowseName="${ns}:$x['Name of command'][$idx]" DataType="$type" ParentNodeId="ns=${ns};i=2">
  <DisplayName>$x['Name of command'][$idx]</DisplayName>
  <Description>$x['Description'][$idx]</Description>
  <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=${ns};i=2</Reference>
  </References>
#if $type!="String" and $type != "Boolean"
      <Value>
       #set $val=str($x['Default value'][$idx])
       #if $val=="nan" or $val=="NA"
	#set $val="0"
       #end if
       #if $x["OPC UA Data type"][$idx].upper()=="INT16" or $x["OPC UA Data type"][$idx].upper()=="INT32"
		#set $val=str($val).split(".")[0]
       #end if
      <uax:$type>$val</uax:$type>
  </Value>
#end if
</UAVariable>
#silent N.append($x['OPC_UA node'][$idx])
#end if
#end if
#end for
#for $idx in $range(0,$y["NRows"])
#silent L.append($y["Short name"][$idx])
#if not $y['OPC_UA node'][$idx] in N
#set $ss=$y['OPC_UA node'][$idx].split(";")
#if ($y["OPC UA Data type"][$idx]).upper()[-1]==']' ## test for arrays
  #set $sp=($y["OPC UA Data type"][$idx].upper()).split("[")
   #set $type=$sp[0].capitalize()
    #if $type[0]=="U"
	#set $type=$type.replace("i","I")
  #end if
   #set $dim=$sp[1].replace("]","")

  <UAVariable ArrayDimensions="$dim" NodeId="ns=${ns};$ss[1]" BrowseName="${ns}:$y['Name of command'][$idx]" DataType="$type" ParentNodeId="ns=${ns};i=3" UserAccessLevel="3" AccessLevel="3" ValueRank="1">
  <DisplayName>$y['Name of command'][$idx]</DisplayName>
  <Description>$y['Description'][$idx]</Description>
  <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=${ns};i=3</Reference>
  </References>
</UAVariable>
#else
  #set $type=$y["OPC UA Data type"][$idx].capitalize()
  #if $type[0]=="U"
	#set $type=$type.replace("i","I")
  #end if

  <UAVariable NodeId="ns=${ns};$ss[1]" BrowseName="${ns}:$y['Name of command'][$idx]" DataType="$type" ParentNodeId="ns=${ns};i=3" UserAccessLevel="3" AccessLevel="3">
  <DisplayName>$y['Name of command'][$idx]</DisplayName>
  <Description>$y['Description'][$idx]</Description>
  <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=${ns};i=3</Reference>
  </References>
#if $type!="String" and $type != "Boolean"
      <Value>
       #set $val=str($y['Default value'][$idx])
       #if $val=="nan" or $val=="NA"
	#set $val="0"
       #end if
      <uax:$type>$val</uax:$type>
  </Value>
#end if
</UAVariable>
#silent N.append($y['OPC_UA node'][$idx])
#end if
#end if
#end for

#for $idx in $range(0,$m["NRows"])
#set $name=($m["OPC_UA node"][$idx].split(";")[1]).split("=")[1].replace(".","_")
#if not $name in L
#set $ss=$m['OPC_UA node'][$idx].split(";")
#if not $m['OPC_UA node'][$idx] in N
    #set $type=$m["OPC UA Data type"][$idx].capitalize()
    #if $type[0]=="U"
	#set $type=$type.replace("i","I")
    #end if
   <UAVariable NodeId="ns=${ns};$ss[1]" BrowseName="${ns}:$name" DataType="$type" ParentNodeId="ns=${ns};i=4" UserAccessLevel="3" AccessLevel="3">
  <DisplayName>$name</DisplayName>
  <Description>$m['Description'][$idx]</Description>
  <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=${ns};i=4</Reference>
  </References>
      <Value>
      <uax:$type>0</uax:$type>
  </Value>
</UAVariable>
#silent N.append($m['OPC_UA node'][$idx])
#end if
#silent L.append($name)
#end if
#end for
#for $idx in $range(0,$c["NRows"])
#set $name=($c["OPC_UA node"][$idx].split(";")[1]).split("=")[1].replace(".","_")
#if not $name in L
#set $ss=$c['OPC_UA node'][$idx].split(";")
#if not $c['OPC_UA node'][$idx] in N
    #set $type=$c["OPC UA Data type"][$idx].capitalize()
    #if $type[0]=="U"
	#set $type=$type.replace("i","I")
    #end if
   <UAVariable NodeId="ns=${ns};$ss[1]" BrowseName="${ns}:$c['Name of command'][$idx]" DataType="$type" ParentNodeId="ns=${ns};i=5" UserAccessLevel="3" AccessLevel="3">
  <DisplayName>$c['Name of command'][$idx]</DisplayName>
  <Description>$c['Description'][$idx]</Description>
  <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasProperty" IsForward="false">ns=${ns};i=5</Reference>
  </References>
      <Value>
      <uax:$type>0</uax:$type>
  </Value>
</UAVariable>
#silent N.append($c['OPC_UA node'][$idx])
#end if
#silent L.append($name)
#end if
#end for
#if $hasMet
<UAObject BrowseName="${ns}:${Met['Device']}_Methods" NodeId="ns=${ns};i=7" ParentNodeId="i=85">
  <DisplayName>${Met['Device']}_Methods</DisplayName>
  <Description>This folder contains all ${Met['Device']} Methods</Description>
  <References>
    <Reference IsForward="false" ReferenceType="Organizes">i=85</Reference>
    <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
#for $id in $range(0,$Met['NumMethods'])
    <Reference ReferenceType="HasComponent">ns=${ns};${Met["Methods"][$id]["OpcUaMethNodeId"]['i']}</Reference>
#end for
  </References>
</UAObject>
#for $id in $range(0,$Met['NumMethods'])
<UAMethod BrowseName="${ns}:$Met["Methods"][$id]["OpcUaMethName"]" NodeId="ns=${ns};${Met["Methods"][$id]["OpcUaMethNodeId"]['i']}" ParentNodeId="ns=${ns};i=7">
  <DisplayName>$Met["Methods"][$id]["OpcUaMethName"]</DisplayName>
  <Description>$Met["Methods"][$id]["Desc"]</Description>
  <References>
    <Reference IsForward="false" ReferenceType="HasComponent">ns=${ns};i=7</Reference>
    <Reference ReferenceType="HasProperty">ns=${ns};$Met["Methods"][$id]['Input']['NodeId']['i']</Reference>
    <Reference ReferenceType="HasProperty">ns=${ns};$Met["Methods"][$id]['Output']['NodeId']['i']</Reference>
    <Reference ReferenceType="HasModellingRule">i=78</Reference>
  </References>
</UAMethod>
<UAVariable BrowseName="InputArguments" DataType="Argument" NodeId="ns=${ns};$Met["Methods"][$id]['Input']['NodeId']['i']" ParentNodeId="ns=${ns};${Met["Methods"][$id]["OpcUaMethNodeId"]['i']}" ValueRank="1" UserAccessLevel="3" AccessLevel="3">
  <DisplayName>InputArguments</DisplayName>
  <Description>InputArguments</Description>
  <References>
    <Reference IsForward="false" ReferenceType="HasProperty">ns=${ns};${Met["Methods"][$id]["OpcUaMethNodeId"]['i']}</Reference>
    <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
    <Reference ReferenceType="HasModellingRule">i=78</Reference>
  </References>
  <Value>
    <uax:ListOfExtensionObject>
#for $idx in $range(0,$len($Met["Methods"][$id]['Input']['Args']))
#set $arg=$Met["Methods"][$id]['Input']['Args'][$idx]
      <uax:ExtensionObject>
        <uax:TypeId>
          <uax:Identifier>i=297</uax:Identifier>
        </uax:TypeId>
        <uax:Body>
          <uax:Argument>
            <uax:Name>$arg['name']</uax:Name>
            <uax:DataType>
              <uax:Identifier>i=11</uax:Identifier>
            </uax:DataType>
            <uax:ValueRank>$arg['isArray']</uax:ValueRank>
            <uax:ArrayDimensions>$arg['ArrayDim']</uax:ArrayDimensions>
            <uax:Description>
              <uax:Encoding>2</uax:Encoding>
              <uax:Locale />
              <uax:Text>$arg['desc']</uax:Text>
            </uax:Description>
          </uax:Argument>
        </uax:Body>
      </uax:ExtensionObject>
#end for
    </uax:ListOfExtensionObject>
  </Value>
</UAVariable>
<UAVariable BrowseName="OutputArguments" DataType="Argument" NodeId="ns=${ns};$Met["Methods"][$id]['Output']['NodeId']['i']" ParentNodeId="ns=${ns};${Met["Methods"][$id]["OpcUaMethNodeId"]['i']}" ValueRank="1">
  <DisplayName>OutputArguments</DisplayName>
  <Description>OutputArguments</Description>
  <References>
    <Reference IsForward="false" ReferenceType="HasProperty">ns=${ns};${Met["Methods"][$id]["OpcUaMethNodeId"]['i']}</Reference>
    <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
    <Reference ReferenceType="HasModellingRule">i=78</Reference>
  </References>
  <Value>
    <uax:ListOfExtensionObject>
#for $idx in $range(0,$len($Met["Methods"][$id]['Output']['Args']))
#set $arg1=$Met["Methods"][$id]['Output']['Args'][$idx]
      <uax:ExtensionObject>
        <uax:TypeId>
          <uax:Identifier>i=297</uax:Identifier>
        </uax:TypeId>
        <uax:Body>
          <uax:Argument>
            <uax:Name>$arg1['name']</uax:Name>
            <uax:DataType>
              <uax:Identifier>i=11</uax:Identifier>
            </uax:DataType>
            <uax:ValueRank>$arg1['isArray']</uax:ValueRank>
            <uax:ArrayDimensions>$arg1['ArrayDim']</uax:ArrayDimensions>
            <uax:Description>
              <uax:Encoding>2</uax:Encoding>
              <uax:Locale />
              <uax:Text>$arg['desc']</uax:Text>
            </uax:Description>
          </uax:Argument>
        </uax:Body>
      </uax:ExtensionObject>
#end for
    </uax:ListOfExtensionObject>
  </Value>
</UAVariable>
#end for
#end if
</UANodeSet>

test/genServerModel.py

0 → 100755
+86 −0
Original line number Diff line number Diff line
from Cheetah.Template import Template
from datetime import date
import sys,os
from optparse import OptionParser
from readMeth import *
import openpyxl.utils.exceptions as ecc
from GenDevice.excelIcd import excelIcd

DEF_DEST ="."
gen_dir=os.environ["PYGEN"]
if gen_dir==None:
    print("PYGEN variable is not set")
    os.exit(0)

def createOPCUModel(book,dest,ns):
    wb=excelIcd(book)
    Main=wb.MainSheet
    Get=wb.GetSheet
    Set=wb.SetSheet
    Cmd=wb.CmdSheet
    Mode=wb.ModeSheet
    device=Main['Device Name'][0]
    hasMeth=False
    print("Working on:",Main['Assembly'][0])

    if wb.MethodsSheet is not None:
        methods=getMethods(wb.MethodsSheet,device)
        # printDict(methods)
        hasMeth=True
    today = date.today()
    outfile=dest+"/"+Main['Assembly'][0]+'_ServerModel.xml'
    #print(today,outfile)
    name_space = {'Author': "Gino Tosti",
            "Date":today.strftime("%y/%m/%d"),
    		'Description':Main["Description"][0],
    		'Assembly': Main['Assembly'][0],
            'Url':Main['OPC UA address'][0],
            'Model':os.path.abspath(outfile),
    		'x': Get,
            'y':Set,
            'z':Main,
            'c':Cmd,
            'm':Mode,
            'ns':ns,
            'hasMet':False}
    if hasMeth:
        name_space['Met']=methods
        name_space['hasMet']=True

    template_file=gen_dir+"/templates/simpleServerModel1.tmpl"
    t1 = Template(file=template_file, searchList=[name_space])
    ff=open(outfile,"w")
    ff.write(str(t1))
    print("File:",outfile," created")



def main():
    defdest=DEF_DEST
    parser = OptionParser(usage='usage: %prog [options] arguments')
    parser.add_option("-f", "--file", dest="book_file", default=None,
            help="ICD Exel File ", metavar="FILE")
    parser.add_option("-o", "--outdir", dest="outdir", default="./SimulationOPCUAserver",
                  help="outputdir will be  /SimulationOPCUAserver/ ", metavar="OUTDIR")
    parser.add_option("-n", "--ns", dest="ns", default=4,
                  help="namespace ", metavar="OUTDIR")
    (options, args) = parser.parse_args()
    if not options.book_file:   # if filename is not given
        parser.error('ICD file not given')
    if options.outdir!=None :
        defdest=options.outdir
    if not os.path.exists(defdest):
    	os.mkdir(defdest)
    	print("Directory " , defdest ,  " Created ")
    else:
        print("Directory " , defdest ,  " already exists")
	#gen_dir=os.environ["PYGEN"]
    ns="2"
    ns=options.ns
    print(type(ns),ns)
    createOPCUModel(options.book_file,os.path.abspath(defdest),ns)
    #print(met)

if __name__ == '__main__':

    main()
+1 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ def createOPCUModel(book,dest,ns):
	Cmd=wb.getSheet("CMD")
	Mode=wb.getSheet("MODE")
	print("Working on:",Main['Assembly'])
	today = date.today()
	outfile=dest+"/"+Main['Assembly'][0]+'_ServerModel.xml'
	scriptfile=dest+"/"+Main['Assembly'][0]+'_opcuaServer.py'
	name_space = {'Author': "Gino Tosti", "Date":today.strftime("%y/%m/%d"),
@@ -49,7 +50,6 @@ def createOPCUModel(book,dest,ns):
if __name__=="__main__":
	defdest=DEF_DEST
	parser = OptionParser(usage='usage: %prog [options] arguments')
	today = date.today()
	parser.add_option("-f", "--file", dest="book_file", default=None,
                  help="ICD Exel File ", metavar="FILE")
	parser.add_option("-o", "--outdir", dest="outdir", default="./SimulationOPCUAserver",

test/readMeth.py

0 → 100755
+128 −0
Original line number Diff line number Diff line
import pandas as pd
from optparse import OptionParser
import json

def readMethodsSheet(icdfile):
    try:
        meths = pd.read_excel(icdfile,sheet_name="Methods")
        return meths
    except FileNotFoundError:
        print("File does not exist")
        return None

def getNumOfMeth(meths):
    return meths.shape

def checkArray(s):
    #s="Double[5]"
    ini=s.find('[')
    #print(ini)
    if ini> 0:
        fin=s.find(']')
        dim=s[ini+1:fin]
        ty=s.split('[')[0].upper()
        isArr=1
    else:
        isArr=-1
        ty=s.upper()
        dim=""
    #print(isArr,ty,dim)
    return isArr,ty,dim

def getInOutArg(el):
    s=el.split(',')
    #print(s)
    ele={}
    if len(s)==3:
        ele["name"]=s[0]
        ele["desc"]=s[1]
        isArr,ty,dim=checkArray(s[2])
        ele["isArray"]=isArr
        ele["dtype"]=ty
        ele["ArrayDim"]=dim
        #ele["NodeId"]={'ns':s[3].split(';')[0],'i':s[3].split(';')[1]}
        return ele
    else:
        return None

def printDict(dct):
    print(json.dumps(dct, sort_keys=False, indent=4))

def getMetArgs(args):
    Args=[]
    a=args.split(':')
    #print(a)
    for el in a:
        #print(el)
        ele=getInOutArg(el)
        #print(ele)
        if ele is not None:
            Args.append(ele)
    return Args

def scanMeth(meth):
    method={}
    method["AcsFunName"]=meth["Name of command"].upper()
    method["OpcUaMethName"]=meth["MethodName"]
    tm=meth["MethodName_NodeId"]
    method["OpcUaMethNodeId"]={'ns':tm.split(';')[0],'i':tm.split(';')[1]}
    tm=meth["InputArgs_NodeId"]
    method["Input"]={'NodeId':{'ns':tm.split(';')[0],'i':tm.split(';')[1]},'Args':getMetArgs(meth["InputArgs"])}
    tm=meth["OutArgs_NodeId"]
    method["Output"]={'NodeId':{'ns':tm.split(';')[0],'i':tm.split(';')[1]},'Args':getMetArgs(meth["OutArgs"])}
    method["Desc"]=meth["Description"]
    return method

def selectMetDevice(sheet,device):
    if device==None:
        return sheet
    else:
        return sheet.loc[sheet['Device Name'] == device]

def getMethods(method,device=None):
    meth=[]
    methods={}
    try:
        meths=selectMetDevice(method,device)
        nm=getNumOfMeth(meths)
        #printDict(meths.loc[2].to_dict())
        print("The file include:",nm[0]," Methods")
        for i  in range(0,nm[0]):
            met=scanMeth(meths.iloc[i].to_dict())
            meth.append(met)
        if device ==None:
            methods["Device"]="ALL"
        else:
            methods["Device"]=device
        methods["NumMethods"]=nm[0]
        methods["Methods"]=meth
        return methods
    except:
        print("Error occurred reading/analyzing File ")
        return None

def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", dest="filename", default=None,
                      help="read data from excel FILENAME")
    parser.add_option("-d", "--device", dest="device", default=None,
                      help="read data for a specific device of an Assembly")
    (options, args) = parser.parse_args()
    icdfile=options.filename
    if icdfile is None:
         parser.print_help()
         exit(1)
    meths=readMethodsSheet(icdfile)
    if options.device is not None:
        device=options.device.upper()
        methods=getMethods(meths,device)
    else:
        methods=getMethods(meths)
    if methods is not None:
        printDict(methods)
        #print(met)

if __name__ == '__main__':

    main()