From 4fb0274ec936cb030c931a1fd603abde04cc5ed4 Mon Sep 17 00:00:00 2001 From: aschwinn <al.schwinn@gsi.de> Date: Wed, 19 Jul 2017 11:18:39 +0200 Subject: [PATCH] Bug 1441 - Restructurization of silecsdeploy - allow to use only one controller-file for identical controllers --- .../xml/fesa/fesa_3_0_0/generateFesaDesign.py | 6 +- .../xml/fesa/fesa_3_0_0/generateSourceCode.py | 6 +- silecs-codegen/src/xml/genduwrapper.py | 72 +- .../src/xml/genduwrappertemplate.py | 4 +- silecs-codegen/src/xml/genparam.py | 276 +--- silecs-codegen/src/xml/genplcsrc.py | 42 +- silecs-codegen/src/xml/iecommon.py | 12 - silecs-codegen/src/xml/iefiles.py | 10 +- .../src/xml/migration/2_0_xto2_1_x.py | 3 + .../migration2_0_Xto2_1_X/migrators.py | 114 +- .../migration2_0_Xto2_1_X/testMigration.py | 63 +- .../src/xml/migration/migrationBase.py | 2 +- .../src/xml/model/{ => Class}/Block.py | 15 +- .../src/xml/model/{ => Class}/Class.py | 6 +- .../src/xml/model/{ => Class}/Register.py | 28 +- .../src/xml/model/Class/__init__.py | 0 .../src/xml/model/Deploy/Controller.py | 151 ++ silecs-codegen/src/xml/model/Deploy/Deploy.py | 93 ++ silecs-codegen/src/xml/model/Deploy/Device.py | 43 + .../src/xml/model/Deploy/SilecsDesign.py | 33 + .../src/xml/model/Deploy/__init__.py | 0 .../src/xml/test/AllTypesDU.silecsdeploy | 153 +- .../xml/test/AllTypesDU.silecsdeploy.backup | 103 ++ .../src/xml/test/general/genDuWrapperTest.py | 2 +- .../src/xml/test/general/genplcsrcTest.py | 14 +- .../xml/test/generated_correct/AllTypes.cpp | 2 +- .../src/xml/test/generated_correct/AllTypes.h | 2 +- .../client/Beckhoff_BC9020.silecsparam | 4 +- .../client/Beckhoff_CX9020.silecsparam | 4 +- .../client/Rabbit_BlockMode.silecsparam | 4 +- .../client/Rabbit_DeviceMode.silecsparam | 4 +- .../client/Schneider_M340.silecsparam | 4 +- .../Schneider_PremiumQuantum.silecsparam | 4 +- .../client/Siemens_Step7Block.silecsparam | 4 +- .../client/Siemens_Step7Device.silecsparam | 4 +- .../client/Siemens_TiaBlock.silecsparam | 4 +- .../client/Siemens_TiaDevice.silecsparam | 4 +- .../wrapper/Beckhoff_BC9020.h | 23 + .../wrapper/Beckhoff_CX9020.h | 23 + .../wrapper/Rabbit_BlockMode.h | 23 + .../wrapper/Rabbit_DeviceMode.h | 23 + .../wrapper/Schneider_M340.h | 23 + .../wrapper/Schneider_PremiumQuantum.h | 23 + .../wrapper/Siemens_Step7Block.h | 23 + .../wrapper/Siemens_Step7Device.h | 23 + .../wrapper/Siemens_TiaBlock.h | 23 + .../wrapper/Siemens_TiaDevice.h | 23 + .../generated_correct/wrapper/SilecsHeader.h | 38 + .../wrapper/Virtual_SiemensBlock.h | 23 + .../wrapper/Virtual_SiemensDevice.h | 23 + .../diagnostictoolmainview.cpp | 2 +- .../src/silecs-diagnostic/silecsmodule.cpp | 18 +- silecs-model/src/xml/DeploySchema.xsd | 1274 +++++++++-------- 53 files changed, 1774 insertions(+), 1129 deletions(-) rename silecs-codegen/src/xml/model/{ => Class}/Block.py (95%) rename silecs-codegen/src/xml/model/{ => Class}/Class.py (98%) rename silecs-codegen/src/xml/model/{ => Class}/Register.py (96%) create mode 100644 silecs-codegen/src/xml/model/Class/__init__.py create mode 100644 silecs-codegen/src/xml/model/Deploy/Controller.py create mode 100644 silecs-codegen/src/xml/model/Deploy/Deploy.py create mode 100644 silecs-codegen/src/xml/model/Deploy/Device.py create mode 100644 silecs-codegen/src/xml/model/Deploy/SilecsDesign.py create mode 100644 silecs-codegen/src/xml/model/Deploy/__init__.py create mode 100644 silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy.backup create mode 100644 silecs-codegen/src/xml/test/generated_correct/wrapper/SilecsHeader.h diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py index 25224e4..e7fbb14 100644 --- a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py +++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py @@ -30,9 +30,9 @@ import fesaTemplates import iefiles from iecommon import * -from model.Register import DesignRegister -from model.Block import DesignBlock -from model.Class import DesignClass +from model.Class.Register import DesignRegister +from model.Class.Block import DesignBlock +from model.Class.Class import DesignClass import libxml2 diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py index 1208ea4..019408f 100644 --- a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py +++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py @@ -28,9 +28,9 @@ import fesaTemplates import iefiles from iecommon import * -from model.Register import DesignRegister -from model.Block import DesignBlock -from model.Class import DesignClass +from model.Class.Register import DesignRegister +from model.Class.Block import DesignBlock +from model.Class.Class import DesignClass import libxml2 def findBlockServerSetActionName(fesaRoot, propName): diff --git a/silecs-codegen/src/xml/genduwrapper.py b/silecs-codegen/src/xml/genduwrapper.py index dc8036b..2034155 100644 --- a/silecs-codegen/src/xml/genduwrapper.py +++ b/silecs-codegen/src/xml/genduwrapper.py @@ -24,21 +24,17 @@ import iefiles import genduwrappertemplate from iecommon import * -from model.Register import DesignRegister -from model.Block import DesignBlock -from model.Class import DesignClass +from model.Class.Register import DesignRegister +from model.Class.Block import DesignBlock +from model.Class.Class import DesignClass + +from model.Deploy.Deploy import Deploy -def genClassHeader(workspacePath, deployName, classNode, funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile, logTopics): - designName = classNode.prop("silecs-design-name") - designVersion = classNode.prop("silecs-design-version") - designFile = funcGetSilecsDesignFilePath(workspacePath, designName) - designDOM = libxml2.parseFile(designFile) +def genClassHeader(workspacePath, deploy, design, funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile, logTopics): + designDOM = iefiles.loadSilecsDesignDOM(workspacePath, design, deploy.silecsVersion, funcGetSilecsDesignFilePath) designClass = DesignClass.getDesignClassFromRootNode(designDOM) - if(not os.path.isfile(designFile)): - raise Exception("File not found: " + designFile) classDeclarations = "" - #construct Block class for block in designClass.getDesignBlocks(): registerInitializerList = genduwrappertemplate.getBlockInitializerList(block) registerGetterSetter = genduwrappertemplate.getRegisterGetterSetter(block) @@ -54,42 +50,38 @@ def genClassHeader(workspacePath, deployName, classNode, funcGetSilecsDesignFile classDeclarations += genduwrappertemplate.getDeviceClass(blockGetters,sendRecvBlocks) sendRecvBlocks = genduwrappertemplate.getControllerSendRecvBlocks(designClass.getBlockNodes()) - classDeclarations = genduwrappertemplate.getDesignClass(designName, designVersion) - designWrapper = genduwrappertemplate.designFileTemplate.substitute({'designNameCapitalized' : iecommon.capitalizeString(designName),'designNameUpper' : designName.upper(),'classDeclarations' : classDeclarations}) + classDeclarations = genduwrappertemplate.getDesignClass(design.name, design.version) + designWrapper = genduwrappertemplate.designFileTemplate.substitute({'designNameCapitalized' : iecommon.capitalizeString(design.name),'designNameUpper' : design.name.upper(),'classDeclarations' : classDeclarations}) - designWrapperFile = funcGetDuDesignWrapperFile(workspacePath, deployName, designName) + designWrapperFile = funcGetDuDesignWrapperFile(workspacePath, deploy.name, design.name) fdesc = open(designWrapperFile, "w") fdesc.write(designWrapper) - iecommon.logInfo('Generated Wrapper for Design %s'%(designName), logTopics) + iecommon.logInfo('Generated Wrapper for Design %s'%(design.name), logTopics) fdesc.close() -def genDuWrapperBase(deployFile,funcGetDuWrapperFile,workspacePath,funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile,deployName,deployVersion,logTopics={'errorlog': True}): - deployDOM = libxml2.parseFile(deployFile) - for controllerNode in deployDOM.xpathEval("/SILECS-Deploy/Controller"): - controllerName = controllerNode.prop("host-name") - controllerDomain = "" # GSI-Hack - No Support for domains at GSI - deployCustomInclude = constructorBody = destructorBody = designGetters = designMemberDeclarations = "" - for classNode in controllerNode.xpathEval("SilecsDesign"): - designName = classNode.prop("silecs-design-name") - designNameCapitalized = iecommon.capitalizeString(designName) - genClassHeader(workspacePath, deployName, classNode, funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile, logTopics) - deployCustomInclude += genduwrappertemplate.deployIncludeTemplate.substitute({'designNameCapitalized' : designNameCapitalized}) - constructorBody += genduwrappertemplate.designAllocation.substitute({'designName' : designName,'designNameCapitalized' : designNameCapitalized}) - destructorBody += genduwrappertemplate.designDeallocation.substitute({'designName' : designName}) - designGetters += genduwrappertemplate.designGetterTemplate.substitute({'designName' : designName,'designNameCapitalized' : designNameCapitalized}) - designMemberDeclarations += genduwrappertemplate.deployUnitMembersDeclaration.substitute({'designName' : designName,'designNameCapitalized' : designNameCapitalized}) - +def genDuWrapperBase(deployFile,funcGetDuWrapperFile,workspacePath,funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile,logTopics={'errorlog': True}): + deploy = Deploy.getDeployFromFile(deployFile) + + for controller in deploy.controllers: + deployCustomInclude = constructorBody = destructorBody = designGetters = designMemberDeclarations = '' + for design in controller.getUsedDesigns(): + genClassHeader(workspacePath, deploy, design, funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile, logTopics) + deployCustomInclude += genduwrappertemplate.deployIncludeTemplate.substitute({'designNameCapitalized' : design.getNameCapitalized()}) + constructorBody += genduwrappertemplate.designAllocation.substitute({'designName' : design.name,'designNameCapitalized' : design.getNameCapitalized()}) + destructorBody += genduwrappertemplate.designDeallocation.substitute({'designName' : design.name}) + designGetters += genduwrappertemplate.designGetterTemplate.substitute({'designName' : design.name,'designNameCapitalized' : design.getNameCapitalized()}) + designMemberDeclarations += genduwrappertemplate.deployUnitMembersDeclaration.substitute({'designName' : design.name,'designNameCapitalized' : design.getNameCapitalized()}) + controllerCtor = deviceGetter = '' - for deviceNode in controllerNode.xpathEval("*/Device"): - deviceName = deviceNode.prop("device-name") - controllerCtor += genduwrappertemplate.controllerDeviceInit.substitute({'deviceName' : deviceName}) - deviceGetter += genduwrappertemplate.deviceGetterTemplate.substitute({'deviceName' : deviceName, 'deviceNameCapitalizedNoUndercore' : iecommon.capitalizeString(deviceName.replace("-","_"))}) - controllerClass = genduwrappertemplate.getControllerClass(controllerCtor,deviceGetter,controllerName, controllerDomain) - code = genduwrappertemplate.generateControllerFile(deployName,deployVersion,deployCustomInclude,constructorBody,destructorBody,designGetters,designMemberDeclarations,controllerClass) + for device in controller.devices: + controllerCtor += genduwrappertemplate.controllerDeviceInit.substitute({'deviceName' : device.silecsDeviceLabel}) + deviceGetter += genduwrappertemplate.deviceGetterTemplate.substitute({'deviceName' : device.silecsDeviceLabel, 'deviceNameCapitalizedNoUndercore' : device.getSilecsDeviceLabelCapitalizedNoUnderscore()}) + controllerClass = genduwrappertemplate.getControllerClass(controllerCtor,deviceGetter,controller.hostName, controller.domain) + code = genduwrappertemplate.generateControllerFile(deploy.name,deploy.version,deployCustomInclude,constructorBody,destructorBody,designGetters,designMemberDeclarations,controllerClass) - fdesc = open(funcGetDuWrapperFile(workspacePath, deployName, controllerNode.prop("host-name")) , "w") + fdesc = open(funcGetDuWrapperFile(workspacePath, deploy.name, controller.hostName) , "w") fdesc.write(code) - iecommon.logInfo('Generated Wrapper for Controller %s'%(controllerNode.prop("host-name")), logTopics) + iecommon.logInfo('Generated Wrapper for Controller %s'%(controller.hostName), logTopics) fdesc.close() def genDuWrapper(workspacePath,deployName,deployVersion,logTopics={'errorlog': True}): @@ -101,6 +93,6 @@ def genDuWrapper(workspacePath,deployName,deployVersion,logTopics={'errorlog': T if not os.path.exists(sourcePath): os.makedirs(sourcePath) - genDuWrapperBase(deployFile,funcGetDuWrapperFile,workspacePath,iefiles.getSilecsDesignFilePath, iefiles.getDuDesignWrapperFile,deployName,deployVersion,logTopics) + genDuWrapperBase(deployFile,funcGetDuWrapperFile,workspacePath,iefiles.getSilecsDesignFilePath, iefiles.getDuDesignWrapperFile,logTopics) diff --git a/silecs-codegen/src/xml/genduwrappertemplate.py b/silecs-codegen/src/xml/genduwrappertemplate.py index af7cf95..3f0e9b4 100644 --- a/silecs-codegen/src/xml/genduwrappertemplate.py +++ b/silecs-codegen/src/xml/genduwrappertemplate.py @@ -16,8 +16,8 @@ import string import iecommon -from model.Register import DesignRegister -from model.Block import DesignBlock +from model.Class.Register import DesignRegister +from model.Class.Block import DesignBlock #================================================================= # Deploy Unit Class diff --git a/silecs-codegen/src/xml/genparam.py b/silecs-codegen/src/xml/genparam.py index 4dfecb5..206c607 100644 --- a/silecs-codegen/src/xml/genparam.py +++ b/silecs-codegen/src/xml/genparam.py @@ -28,9 +28,12 @@ import xmltemplate import iefiles from iecommon import * -from model.Register import * -from model.Block import * -from model.Class import * +from model.Class.Register import * +from model.Class.Block import * +from model.Class.Class import * +from model.Deploy.Deploy import * +from model.Deploy.Controller import * +import model.Deploy.Device #------------------------------------------------------------------------- # Global definitions @@ -49,19 +52,6 @@ blockCounter = 0 # used for NI block address generation regCounter = 0 # used for NI register address generation -#========================================================================= -# Sub-function -#========================================================================= - -#------------------------------------------------------------------------- -# Decode HTML mapping < , > , " , ' in the appropiate coding -def decode(html): - html = html.replace("<","<") - html = html.replace(">",">") - html = html.replace('"',""") - html = html.replace("'","'") - return html - #------------------------------------------------------------------------- # Trimming: remove new-line, tabulation and spaces of the string # Used to compute CRC32 on significant data only @@ -457,29 +447,19 @@ def computeSchneiderAnyNextBaseAddress(classAddr, nbBlk, nbDev, devSize): def computeNiAnyNextBaseAddress(classAddr, nbBlk, nbDev, devSize): return 0 -#------------------------------------------------------------------------- -# computeChecksumController -# checksum procedure: -# CRC = Major-number + PLC-base-address -# For each PLC-Class (cluster) of the controller mapping: -# CRC += class-name + class-version + class-access //DEVICE/BLOCK -# For each Block -# CRC += block-name + block-mode //R/W -# For each Register -# CRC += reg-name + reg-format + array-dim1 + array-dim2 + (string-length) optional -# CRC += nb-instance -# -def computeChecksumController( workspacePath, controllerNode, silecsVersion, PLCbaseAddress, funcGetSilecsDesignFilePath, logTopics={'errorlog': True}): +def computeChecksumController( workspacePath, deploy, controller, silecsVersion, funcGetSilecsDesignFilePath, logTopics={'errorlog': True}): majorSilecsVersion = iecommon.getMajorSilecsVersion(silecsVersion) CRC32 = zlib.crc32(trim(str(majorSilecsVersion)),0)& 0xffffffff - CRC32 = zlib.crc32(trim(str(PLCbaseAddress)),CRC32)& 0xffffffff - for silecsDesign in controllerNode.xpathEval("SilecsDesign"): - CRC32 = zlib.crc32(trim(silecsDesign.prop("silecs-design-name")),CRC32)& 0xffffffff - CRC32 = zlib.crc32(trim(silecsDesign.prop("silecs-design-version")),CRC32)& 0xffffffff - designDOM = loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath) - CRC32 = computeChecksumClass(designDOM,CRC32,logTopics) - for device in silecsDesign.xpathEval("Device"): - CRC32 = zlib.crc32(trim(device.prop("device-name")),CRC32)& 0xffffffff + CRC32 = zlib.crc32(trim(str(controller.baseAddress)),CRC32)& 0xffffffff + for silecsDesign in deploy.silecsDesigns: + devices = controller.getDevicesOfDesign(silecsDesign.name) + if len(devices) > 0: + CRC32 = zlib.crc32(trim(silecsDesign.name),CRC32)& 0xffffffff + CRC32 = zlib.crc32(trim(silecsDesign.version),CRC32)& 0xffffffff + designDOM = iefiles.loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath) + CRC32 = computeChecksumClass(designDOM,CRC32,logTopics) + for device in devices: + CRC32 = zlib.crc32(trim(device.silecsDeviceLabel),CRC32)& 0xffffffff iecommon.logInfo("CRC32: %s" % str(CRC32),logTopics) return CRC32 @@ -495,30 +475,6 @@ def computeChecksumClass(designDOM, CRC32, logTopics={'errorlog': True}): CRC32 = zlib.crc32(trim(str(register.stringLength)),CRC32)& 0xffffffff return CRC32 -#------------------------------------------------------------------------- -# Hash table -#------------------------------------------------------------------------- - -whichPLCBrand = { - 'SIMATIC_S7-300' : 'SIEMENS', - 'SIMATIC_S7-400' : 'SIEMENS', - 'SIMATIC_S7-1200' : 'SIEMENS', - 'SIMATIC_S7-1500' : 'SIEMENS', - 'SIMATIC_ET-200S' : 'SIEMENS', - 'SIMATIC_S7-VIRTUAL': 'SIEMENS', - 'Premium' : 'SCHNEIDER', - 'Quantum' : 'SCHNEIDER', - 'M340' : 'SCHNEIDER', - 'Compact_RIO' : 'NI', - 'PXI_RT' : 'NI', - 'PXI_Windows' : 'NI', - 'PC_Windows' : 'NI', - 'Other_Support_CNV' : 'NI', - 'Rabbit_RCM_4010' : 'DIGI', - 'Rabbit_RCM_2000' : 'DIGI', - 'BC9020' : 'BECKHOFF', - 'CX9020' : 'BECKHOFF' -} # The following constant are used to align the address of a device block {set of registers}. # With SCHNEIDER PLC, block is aligned depending on his 'worst-case' alignement {16bits or 32bits}. @@ -619,43 +575,10 @@ whichBaseAddressFunction = { 'BECKHOFF'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress } -#Base address provided by the user in the Deployment relies on the PLC model: -#Unity Premium/Quantum is interpreted as 16bit address -#Unity M340 is interpreted as 32bit address -#Factor is used to convert the base-address to byte-addressing for computation. -whichAddressFactor = { - 'SIMATIC_S7-300' : 1, # Simatic does not use absolute addressing {DB-number} - 'SIMATIC_S7-400' : 1, - 'SIMATIC_S7-1200' : 1, - 'SIMATIC_S7-1500' : 1, - 'SIMATIC_ET-200S' : 1, - 'SIMATIC_S7-VIRTUAL': 1, - 'Premium' : 2, # Premium/Quantum uses 16bit adressing for 32bit values - 'Quantum' : 2, - 'M340' : 2, - 'Compact_RIO' : 0, - 'PXI_RT' : 0, - 'PXI_Windows' : 0, - 'PC_Windows' : 0, - 'Other_Support_CNV' : 0, - 'Rabbit_RCM_4010' : 2, - 'Rabbit_RCM_2000' : 2, - 'BC9020' : 2, # BC90xx use 16 bit addressing - 'CX9020' : 1 -} - -def loadSilecsDesignDOM(workspacePath, classNode, silecsVersion, funcGetSilecsDesignFilePath): - if classNode.prop("silecs-design-name") == "SilecsHeader": - silecsHeader = xmltemplate.getSilecsHeader(silecsVersion) - return libxml2.parseDoc(silecsHeader) - else: - designPath = funcGetSilecsDesignFilePath(workspacePath, classNode.prop("silecs-design-name")) - return libxml2.parseFile(designPath) - # Needed to encapsulate "genParam" in order to allow unit-testing (fake all file interactions) def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSilecsDeployFilePath, funcGetParameterFileDirectory, workspacePath, deployName, deployVersion, silecsVersion, logTopics={'debuglog': True}): # Global variable links - global plcModel, plcBrand, plcSystem, plcProtocol, plcSize, plcLast + global plcModel, plcSize, plcLast global PLCbaseAddress, checksumRef, owner, deviceMemSize, blkAddr, nbBlock, msize global blkMemSize global instAddr, classAddr @@ -669,26 +592,8 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile if(not os.path.isfile(deployPath)): iecommon.logError(deployName + "deployment file cannot be found in provided workspace",logTopics) - # Create the Deployment DOM object - deployDOM = libxml2.parseFile(deployPath) - - # Check that Deployment data are consistent - deployUnitNode = deployDOM.xpathEval("/SILECS-Deploy/Deploy-Unit")[0] # only one Deploy-Unit - - if (deployUnitNode.prop('name') != deployName): - iecommon.logError("Deployment name is not consistent", True,logTopics) + deploy = Deploy.getDeployFromFile(deployPath) - #------------------------------------------------------------------------- - # Extract information from the XML - #------------------------------------------------------------------------- - - # Extract Deployment owner from the Information node - owner = deployDOM.xpathEval("/SILECS-Deploy/Information/Owner")[0].prop('user-login') - - #------------------------------------------------------------------------- - # SECOND pass on each Design documents: Generate parameters - # For each class generate XML-ouput document relying on Design & Deployment - #------------------------------------------------------------------------- iecommon.logDebug("------Processing for output file generation------",logTopics) paramPath = funcGetParameterFileDirectory(workspacePath, deployName) @@ -697,54 +602,20 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile os.makedirs(paramPath) iecommon.logDebug("create directory %s" %paramPath,logTopics) - iecommon.addSilecsHeaderToClasses(deployDOM) - controllerNodes = deployDOM.xpathEval("/SILECS-Deploy/Controller") - for controllerNode in controllerNodes: - plcNode = controllerNode.xpathEval("*[@system]")[0] - # Extract PLC global information - plcSystem = plcNode.prop('system') - plcModel = plcNode.prop('model') - plcBrand = whichPLCBrand[plcModel] - plcProtocol = plcNode.prop('protocol') - addressFactor = whichAddressFactor[plcModel] - - if plcBrand == 'SIEMENS': - PLCbaseAddress = long(plcNode.prop('base-DB-number')) - - elif plcBrand == 'SCHNEIDER': - PLCbaseAddress = long(plcNode.prop('base-address')) - PLCbaseAddress = PLCbaseAddress * addressFactor - - elif plcBrand == 'BECKHOFF': - PLCbaseAddress = long(plcNode.prop('base-address')) - # Use plcModel to set appropriate initial offset - if plcModel == 'BC9020': - offset = 32768 - elif plcModel == 'CX9020': - offset = 24576 - PLCbaseAddress = (PLCbaseAddress * addressFactor) + offset - - elif plcBrand == 'DIGI': - PLCbaseAddress = long(plcNode.prop('base-address')) - PLCbaseAddress = PLCbaseAddress * addressFactor - - else: # plcBrand == 'NI' - PLCbaseAddress = 0 - - classBaseAddress = PLCbaseAddress - + for controller in deploy.controllers: + classBaseAddress = controller.baseAddress + plcModel = controller.model # Messagges for debugging purpose iecommon.logDebug("------ XML extracted informations ------",logTopics) - iecommon.logDebug("owner = "+owner,logTopics) - iecommon.logDebug("plcSystem = "+plcSystem,logTopics) - iecommon.logDebug("plcModel = "+plcModel,logTopics) - iecommon.logDebug("plcBrand = "+plcBrand,logTopics) - iecommon.logDebug("plcProtocol = "+plcProtocol,logTopics) - iecommon.logDebug("addressFactor = %d" %addressFactor,logTopics) - iecommon.logDebug("PLCbaseAddress = %d" %PLCbaseAddress,logTopics) + iecommon.logDebug("owner = " + deploy.owner,logTopics) + iecommon.logDebug("plcSystem = " + controller.system,logTopics) + iecommon.logDebug("plcModel = " + controller.model,logTopics) + iecommon.logDebug("plcBrand = " + controller.brand,logTopics) + iecommon.logDebug("plcProtocol = " + controller.protocol,logTopics) + iecommon.logDebug("PLCbaseAddress = %d" %controller.baseAddress,logTopics) - paramFile = funcGetParameterFile(workspacePath, deployName, controllerNode.prop('host-name')) - iecommon.logInfo("Generate xml for parameters file: "+paramFile,logTopics) + paramFile = funcGetParameterFile(workspacePath, deployName, controller.hostName ) + iecommon.logInfo("Generate xml for parameters file: " + paramFile,logTopics) # Create the parameter DOM for the output file paramDOM = libxml2.newDoc(version='1.0') @@ -752,26 +623,20 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile outputRoot.setProp("silecs-version", silecsVersion) paramDOM.addChild(outputRoot) - #------------------------------------------------------------------------- - # Generate section <Mapping-Info></Mapping-Infon> - #------------------------------------------------------------------------- paramMappingInfoNode = libxml2.newNode("Mapping-Info") outputRoot.addChild(paramMappingInfoNode) - # Add Owner paramOwnerNode = libxml2.newNode('Owner') - paramOwnerNode.setProp("user-login", owner) + paramOwnerNode.setProp("user-login", deploy.owner) paramMappingInfoNode.addChild(paramOwnerNode) - # Add Generation element2 = libxml2.newNode('Generation') currentDate = str(datetime.datetime.now()) element2.setProp("date",currentDate) paramMappingInfoNode.addChild(element2) - # Add Deployment element2 = libxml2.newNode('Deployment') - CRC32 = computeChecksumController(workspacePath, controllerNode, silecsVersion, PLCbaseAddress, funcGetSilecsDesignFilePath, logTopics) + CRC32 = computeChecksumController(workspacePath, deploy, controller, silecsVersion, funcGetSilecsDesignFilePath, logTopics) element2.setProp("checksum", str(CRC32)) paramMappingInfoNode.addChild(element2) @@ -779,35 +644,33 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile # Generate section <SILECS-Mapping></SILECS-Mapping> #------------------------------------------------------------------------- paramSilecsMappingNode = libxml2.newNode("SILECS-Mapping") - paramSilecsMappingNode.setProp("plc-name", controllerNode.prop('host-name')) - paramSilecsMappingNode.setProp("plc-brand", plcBrand) - paramSilecsMappingNode.setProp("plc-system", plcSystem) - paramSilecsMappingNode.setProp("plc-model", plcModel) - paramSilecsMappingNode.setProp("protocol", plcProtocol) - paramSilecsMappingNode.setProp("address", str(PLCbaseAddress)) - paramSilecsMappingNode.setProp("domain", "NotUsed") + paramSilecsMappingNode.setProp("plc-name", controller.hostName) + paramSilecsMappingNode.setProp("plc-brand", controller.brand) + paramSilecsMappingNode.setProp("plc-system", controller.system) + paramSilecsMappingNode.setProp("plc-model", controller.model) + paramSilecsMappingNode.setProp("protocol", controller.protocol) + paramSilecsMappingNode.setProp("address", str(controller.baseAddress)) + paramSilecsMappingNode.setProp("domain", controller.domain) paramSilecsMappingNode.setProp("used-mem", "TODO") outputRoot.addChild(paramSilecsMappingNode) - classNodes = controllerNode.xpathEval('SilecsDesign') - - for classNode in classNodes: + for deployDesign in deploy.silecsDesigns: + devices = controller.getDevicesOfDesign(deployDesign.name) + nbDevice = len(devices) + iecommon.logDebug("Class %s has %s devices" %(deployDesign.name,nbDevice),logTopics) + if nbDevice == 0: + continue #skip unused design + iecommon.logDebug("-----------------------------------------",logTopics) - iecommon.logDebug("------ Analysing Class %s ------"%classNode.prop("silecs-design-name"),logTopics) + iecommon.logDebug("------ Analysing Class " + deployDesign.name + " ------",logTopics) iecommon.logDebug("-----------------------------------------",logTopics) - designDOM = loadSilecsDesignDOM(workspacePath, classNode, silecsVersion, funcGetSilecsDesignFilePath) + designDOM = iefiles.loadSilecsDesignDOM(workspacePath, deployDesign, silecsVersion, funcGetSilecsDesignFilePath) designClass = DesignClass.getDesignClassFromRootNode(designDOM) paramClass = ParamClass() paramClass.initWithDesignClass(designClass) paramSilecsMappingNode.addChild(paramClass.xmlNode) - # Extract the number of devices ------------------------------------------ - deviceLabelList=classNode.xpathEval('Device') - nbDevice = len(deviceLabelList) - iecommon.logDebug("Class %s uses device-list and has %s devices" %(classNode,nbDevice),logTopics) - - #------------------------------------------------------------------------- # Generate section <Block></Block> #------------------------------------------------------------------------- @@ -817,10 +680,10 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile blkAddr = 0 # memory address of the block (using byte addressing) nbBlock = 0 # number of block of the class - computeBlkAddress = whichBlkAddressFunction[plcBrand + plcProtocol] + computeBlkAddress = whichBlkAddressFunction[controller.brand + controller.protocol] - # INNER LOOP TO ACCESS AT BLOCK LEVEL (LOOP-2) - for designBlock in designClass.getDesignBlocks(): #LOOP-2 + # INNER LOOP TO ACCESS AT BLOCK LEVEL + for designBlock in designClass.getDesignBlocks(): paramBlock = ParamBlock() paramBlock.initWithDesignBlock(designBlock) @@ -831,17 +694,17 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile blockMemSize = 0 # block size (sum of the regist) instAddr = 0 # initial class address BUG FIXED regCounter = 0 # used for NI register address generation - alignRegAddress = whichRegAddressFunction [plcModel] + alignRegAddress = whichRegAddressFunction [controller.model] #------------------------------------------------------------------------- # Generate section <Register></Register> #------------------------------------------------------------------------- - # INNER LOOP TO ACCESS AT REGISTER LEVEL (LOOP-3) + # INNER LOOP TO ACCESS AT REGISTER LEVEL for designRegister in designBlock.getDesignRegisters(): iecommon.logDebug("------ Processing Register " + designRegister.name + " ------",logTopics) # Set length attribute only for string registers if designRegister.format == 'string': - if plcBrand == 'RABBIT': + if controller.brand == 'RABBIT': # RABBIT has 8bit memory alignment but uses 16bit word communication protocol (MODBUS). # String buffer (8bit elements) must have even number of bytes. if ((int(designRegister.dim1)*int(designRegister.dim2)*int(designRegister.stringLength)) % 2 == 1): #XML CliX cannot check that constraint! @@ -857,12 +720,12 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile paramRegister = ParamRegister() paramRegister.initWithDesignRegister(designRegister,regSize,regAddress,msize) # Compute address for the next register - regAddress = computeAnyNextRegAddress(plcBrand, regAddress, designRegister.dim1, designRegister.dim2) + regAddress = computeAnyNextRegAddress(controller.brand, regAddress, designRegister.dim1, designRegister.dim2) paramBlock.xmlNode.addChild(paramRegister.xmlNode) #paramRegister.xmlNode.shellPrintNode() #iterativelly compute the block size (accumulator initialized outside the loop) blockSize = blockSize + (int(regSize) * designRegister.dim1 * designRegister.dim2) - # END OF INNER LOOP TO ACCESS AT REGISTER LEVEL (LOOP-3) + # END OF INNER LOOP TO ACCESS AT REGISTER LEVEL paramBlock.setSize(blockSize) paramBlock.setAddress(computeBlkAddress(regAddress, int(classBaseAddress),nbDevice)) @@ -878,20 +741,20 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile # Set block Address paramClass.setAddress(classBaseAddress) - computeInstAddress = whichInstAddressFunction[ plcBrand + plcProtocol ] - for device in deviceLabelList: - instance = libxml2.newNode("Instance") - instance.setProp("label", device.prop("device-name")) + computeInstAddress = whichInstAddressFunction[ controller.brand + controller.protocol ] + for device in devices: + instance = libxml2.newNode("Instance") + instance.setProp("label", device.silecsDeviceLabel) instance.setProp("address", str(computeInstAddress(classBaseAddress, deviceMemSize))) paramClass.xmlNode.addChild(instance) # Compute the memory address for the next class - computeBaseAddress = whichBaseAddressFunction [plcBrand+plcProtocol] + computeBaseAddress = whichBaseAddressFunction [controller.brand + controller.protocol] classBaseAddress = computeBaseAddress(classBaseAddress, nbBlock, nbDevice, deviceMemSize); # Set class used-memory paramClass.setUsedMemory(classMem) - iecommon.logInfo("Used-memory for Class "+classNode.prop("silecs-design-version")+": "+str(classMem),logTopics) + iecommon.logInfo("Used-memory for Class " + deployDesign.name + ": "+str(classMem),logTopics) #------------------------------------------------------ # Generate output XML @@ -901,21 +764,6 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile iecommon.logDebug("---------------------------------------------------------",logTopics) iecommon.logDebug("------GENERATED FILE: %s "%paramFile,logTopics) iecommon.logDebug("---------------------------------------------------------",logTopics) - - # GSI-Fix there are more then two types now ... better say nothing than something which could be wrong for the else-case - #Display details about the PLC memory using for the global configuration - #if (plcBrand == 'SIEMENS'): - # # SIEMENS works with data-block addressing - # plcUsedMem = "DB"+str(PLCbaseAddress)+"..DB"+str(plcLast)+" / "+str(plcSize)+" bytes" - #else: - # # SCHNEIDER works with absolute addressing - # startAddr = PLCbaseAddress /2 #Memory info uses word-addressing - # lastAddr = plcLast #Already computed as byte-address - # plcUsedMem = "MW"+str(startAddr)+"..MW"+str(lastAddr)+" / "+str(plcSize)+" words" - - # print plc used memory - # iecommon.logInfo("Used-memory for PLC "+deployName+": "+str(plcUsedMem),logTopics) - #========================================================================= # Entry point diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py index 005156f..13b4147 100644 --- a/silecs-codegen/src/xml/genplcsrc.py +++ b/silecs-codegen/src/xml/genplcsrc.py @@ -2,7 +2,6 @@ # Copyright 2016 CERN and GSI # # This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # @@ -28,9 +27,10 @@ import virtualS7Template import rabbitTemplate from iecommon import * -from model.Register import ParamRegister -from model.Block import ParamBlock -from model.Class import ParamClass +from model.Class.Register import ParamRegister +from model.Class.Block import ParamBlock +from model.Class.Class import ParamClass +from model.Deploy.Deploy import * #========================================================================= # General remarks @@ -42,7 +42,7 @@ from model.Class import ParamClass # Deploy global information -class Deploy(object): +class DeploymentInfo(object): plcModel = None # S7-300, .., Premium, .. plcSystem = None # UNITY, STEP-7, TIA-PORTAL, ... plcProtocol = None # DEVICE_MODE or BLOCK_MODE @@ -560,7 +560,7 @@ def generateNISources(paramDOM, sourceFolderPath ,logTopics): return def getDeploymentInformation(paramDOM): - deploy = Deploy() + deploy = DeploymentInfo() mapping = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping")[0] deploy.plcModel = mapping.prop('plc-model') @@ -586,20 +586,19 @@ def generateControllerFiles(sourceFolderPath,deploy,fileExtention,source,logTopi fdesc.close() # Needed for unit-testing -def generateControllerCode(controllerNode, paramsFile, sourceFolderPath, logTopics={'errorlog': True}): +def generateControllerCode(controller, paramsFile, sourceFolderPath, logTopics={'errorlog': True}): paramDOM = libxml2.parseFile(paramsFile) - plcNode = controllerNode.xpathEval("*[@system]")[0] - if plcNode.get_name() == 'Siemens-PLC': + if controller.plcNode.get_name() == 'Siemens-PLC': generateSiemensSources(paramDOM,sourceFolderPath,logTopics) - elif plcNode.get_name() == 'Virtual-Controller': + elif controller.plcNode.get_name() == 'Virtual-Controller': generateVirtualS7Sources(paramDOM,sourceFolderPath,logTopics) - elif plcNode.get_name() == 'Schneider-PLC': + elif controller.plcNode.get_name() == 'Schneider-PLC': generateSchneiderSources(paramDOM,sourceFolderPath,logTopics) - elif plcNode.get_name() == 'Rabbit-uC': + elif controller.plcNode.get_name() == 'Rabbit-uC': generateRabbitSources(paramDOM,sourceFolderPath,logTopics) - elif plcNode.get_name() == 'Beckhoff-PLC': + elif controller.plcNode.get_name() == 'Beckhoff-PLC': generateBeckhoffSources(paramDOM,sourceFolderPath,logTopics) - elif plcNode.get_name() == 'NI-Controller': + elif controller.plcNode.get_name() == 'NI-Controller': generateNISources(paramDOM,sourceFolderPath,logTopics) else: iecommon.logError("The PLC-Type %s is not supported" %plcNode.get_name(), True,logTopics) @@ -610,7 +609,6 @@ def generateControllerCode(controllerNode, paramsFile, sourceFolderPath, logTopi #========================================================================= def genPlcSrc(workspacePath, deployName,silecsVersion,logTopics={'errorlog': True}): deployFilePath = iefiles.getSilecsDeployFilePath(workspacePath,deployName) - deployDOM = libxml2.parseFile(deployFilePath) iecommon.logInfo("Load Deployment document: %s" %deployFilePath,logTopics); # Create the source folder if needed @@ -618,16 +616,10 @@ def genPlcSrc(workspacePath, deployName,silecsVersion,logTopics={'errorlog': Tru if not os.path.exists(sourceFolderPath): os.makedirs(sourceFolderPath) - # Add xml of the silecs-header - iecommon.addSilecsHeaderToClasses(deployDOM) - - controllerNodes = deployDOM.xpathEval("/SILECS-Deploy/Controller") - for controllerNode in controllerNodes: - paramsFile = iefiles.getParameterFile(workspacePath, deployName,controllerNode.prop("host-name")) - generateControllerCode(controllerNode,paramsFile,sourceFolderPath,logTopics) - - # Clean-up the memory before exit - deployDOM.freeDoc() + silecsDeploy = Deploy.getDeployFromFile(deployFilePath) + for controller in silecsDeploy.controllers: + paramsFile = iefiles.getParameterFile(workspacePath, deployName,controller.hostName) + generateControllerCode(controller,paramsFile,sourceFolderPath,logTopics) return "Genplcsrc succeded!" diff --git a/silecs-codegen/src/xml/iecommon.py b/silecs-codegen/src/xml/iecommon.py index 720e594..a93685b 100644 --- a/silecs-codegen/src/xml/iecommon.py +++ b/silecs-codegen/src/xml/iecommon.py @@ -155,18 +155,6 @@ def capitalizeString(text): str += text[0].upper() str += text[1:] return str - -def addSilecsHeaderToClasses(silecsDeployDOM): - controllers = silecsDeployDOM.xpathEval("/SILECS-Deploy/Controller") - for controller in controllers: - silecsHeaderDesign = libxml2.newNode("SilecsDesign") - silecsHeaderDesign.setProp("silecs-design-name","SilecsHeader") - silecsHeaderDesign.setProp("silecs-design-version","1.0.0") - silecsHeaderDevice = libxml2.newNode("Device") - silecsHeaderDevice.setProp("device-name","SilecsHeader") - silecsHeaderDesign.addChild(silecsHeaderDevice) - silecsDesigns = controller.xpathEval("SilecsDesign") - silecsDesigns[0].addPrevSibling(silecsHeaderDesign) #Major changes: Public API, database and PLC code generation may be impacted def getMajorSilecsVersion(silecsVersionString): diff --git a/silecs-codegen/src/xml/iefiles.py b/silecs-codegen/src/xml/iefiles.py index 4c40de7..32376c9 100644 --- a/silecs-codegen/src/xml/iefiles.py +++ b/silecs-codegen/src/xml/iefiles.py @@ -17,7 +17,7 @@ import iecommon import xmltemplate import socket - +import libxml2 import os import fnmatch import shutil @@ -26,6 +26,14 @@ designFormat = '.silecsdesign' deployFormat = '.silecsdeploy' paramFormat = '.silecsparam' +def loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath): + if silecsDesign.name == "SilecsHeader": + silecsHeader = xmltemplate.getSilecsHeader(silecsVersion) + return libxml2.parseDoc(silecsHeader) + else: + designPath = funcGetSilecsDesignFilePath(workspacePath, silecsDesign.name) + return libxml2.parseFile(designPath) + #================================================================== # FILE ACCESS #================================================================== diff --git a/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py b/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py index 4c9dbdd..408fd90 100644 --- a/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py +++ b/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py @@ -31,6 +31,8 @@ class Migration(MigrationBase): def migrateClass(self, context, projectDir ): modified = false + + # fix reverted, since FESA does not allow to have code outside of the "src" folder #modified = fesaClassIncludeHeaderMigrator(context,self.silecsDocument) #removeSilecsDesignGenCode(context, self.silecsDocument) #modified |= fesaClassMakeSpecificMigrator(self.silecsDocument) @@ -45,6 +47,7 @@ class Migration(MigrationBase): def migrateDeployUnit(self, context, projectDir ): modified = False + modified |= silecsDeployMigrator(context) removeSilecsDeployGenCode(context, projectDir) self.updateFESAMakeSpecific() return modified diff --git a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py index 293ede6..6e77a37 100644 --- a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py +++ b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py @@ -15,54 +15,54 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import libxml2 -from migration import FileUtils +#from migration import FileUtils import os import shutil -def fesaClassIncludeHeaderMigrator(context,silecsDocument): - print("Migration-Info: The include calls in all FESA source files will be updated to use the new 'generated-silecs' folder") - modified = False - silecsClassNodes = context.xpathEval("//SILECS-Class") - if not silecsClassNodes: - raise Exception('Node "SILECS-Class" not found') - silecsClassNodes = silecsClassNodes[0] - silecsClassName = silecsClassNodes.prop("name") - projectDir = FileUtils.getProjectDir(silecsDocument) - sourceFiles = FileUtils.getFesaSourceFiles(silecsClassName, projectDir) - - searchString = "<" + os.path.join(silecsClassName,"Common",silecsClassName) + ".h>" - replaceString = "<" + os.path.join(silecsClassName,"GeneratedCode",silecsClassName) + ".h>" - for sourceFile in sourceFiles: - FileUtils.replaceInFile(sourceFile,searchString,replaceString) - modified = True - return modified +#------------------- def fesaClassIncludeHeaderMigrator(context,silecsDocument): + # print("Migration-Info: The include calls in all FESA source files will be updated to use the new 'generated-silecs' folder") + #---------------------------------------------------------- modified = False + #-------------------- silecsClassNodes = context.xpathEval("//SILECS-Class") + #-------------------------------------------------- if not silecsClassNodes: + #---------------------- raise Exception('Node "SILECS-Class" not found') + #------------------------------------ silecsClassNodes = silecsClassNodes[0] + #--------------------------- silecsClassName = silecsClassNodes.prop("name") + #---------------------- projectDir = FileUtils.getProjectDir(silecsDocument) + #--- sourceFiles = FileUtils.getFesaSourceFiles(silecsClassName, projectDir) +#------------------------------------------------------------------------------ + # searchString = "<" + os.path.join(silecsClassName,"Common",silecsClassName) + ".h>" + # replaceString = "<" + os.path.join(silecsClassName,"GeneratedCode",silecsClassName) + ".h>" + #-------------------------------------------- for sourceFile in sourceFiles: + #-------- FileUtils.replaceInFile(sourceFile,searchString,replaceString) + #------------------------------------------------------- modified = True + #----------------------------------------------------------- return modified -def fesaClassMakeSpecificMigrator(silecsDocument): - print("Migration-Info: Compiler flags for new codegen-folder will be added into the Makefile.specific of your FESA class") - modified = False - projectDir = FileUtils.getProjectDir(silecsDocument) - makeSpecific = os.path.join(projectDir,"myProject","Makefile.specific") - if os.path.isfile(makeSpecific): - with open(makeSpecific, "a") as myfile: - myfile.write("\nCOMPILER_FLAGS += -I./generated-silecs/cpp") - modified = True - return modified +#---------------------------- def fesaClassMakeSpecificMigrator(silecsDocument): + # print("Migration-Info: Compiler flags for new codegen-folder will be added into the Makefile.specific of your FESA class") + #---------------------------------------------------------- modified = False + #---------------------- projectDir = FileUtils.getProjectDir(silecsDocument) + #--- makeSpecific = os.path.join(projectDir,"myProject","Makefile.specific") + #------------------------------------------ if os.path.isfile(makeSpecific): + #------------------------------- with open(makeSpecific, "a") as myfile: + #------ myfile.write("\nCOMPILER_FLAGS += -I./generated-silecs/cpp") + #------------------------------------------------------- modified = True + #----------------------------------------------------------- return modified -def removeSilecsDesignGenCode(context, silecsDocument): - print("Migration-Info: The silecs generated C++ code which was located in 'Common' moved to 'generated-silecs' in the root directory. The old code will be removed") - silecsClassNodes = context.xpathEval("//SILECS-Class") - if not silecsClassNodes: - raise Exception('Node "SILECS-Class" not found') - silecsClassNodes = silecsClassNodes[0] - silecsClassName = silecsClassNodes.prop("name") - projectDir = FileUtils.getProjectDir(silecsDocument) - commonFolder = os.path.join(projectDir,"src",silecsClassName,"Common") - cppFile = os.path.join(commonFolder,silecsClassName + ".cpp") - hppFile = os.path.join(commonFolder,silecsClassName + ".h") - if os.path.isfile(cppFile): - os.remove(cppFile) - if os.path.isfile(hppFile): - os.remove(hppFile) +#----------------------- def removeSilecsDesignGenCode(context, silecsDocument): + # print("Migration-Info: The silecs generated C++ code which was located in 'Common' moved to 'generated-silecs' in the root directory. The old code will be removed") + #-------------------- silecsClassNodes = context.xpathEval("//SILECS-Class") + #-------------------------------------------------- if not silecsClassNodes: + #---------------------- raise Exception('Node "SILECS-Class" not found') + #------------------------------------ silecsClassNodes = silecsClassNodes[0] + #--------------------------- silecsClassName = silecsClassNodes.prop("name") + #---------------------- projectDir = FileUtils.getProjectDir(silecsDocument) + #---- commonFolder = os.path.join(projectDir,"src",silecsClassName,"Common") + #------------- cppFile = os.path.join(commonFolder,silecsClassName + ".cpp") + #--------------- hppFile = os.path.join(commonFolder,silecsClassName + ".h") + #----------------------------------------------- if os.path.isfile(cppFile): + #---------------------------------------------------- os.remove(cppFile) + #----------------------------------------------- if os.path.isfile(hppFile): + #---------------------------------------------------- os.remove(hppFile) def removeSilecsDeployGenCode(context, projectDir): print("Migration-Info: the silecsdeploy folder 'generated' will be named 'generated-silecs' to be consistant with silecsdesign. The old folder will be removed.") @@ -81,3 +81,31 @@ def removeFesaConfigurationFieldParameterFile(context): for paramField in paramFields: paramField.unlinkNode() + +def silecsDeployMigrator(silecsDocument): + print("Migration-Info: re-order .silecsdeploy document to provide more configuration-options") + modified = False + deployUnitNodes = silecsDocument.xpathEval("/SILECS-Deploy/Deploy-Unit") + if not len(deployUnitNodes) == 1: + return + deployUnitNode = deployUnitNodes[0] + controllers = silecsDocument.xpathEval("/SILECS-Deploy/Controller") + for controller in controllers: + silecsDesigns = controller.xpathEval("SilecsDesign") + plc = controller.xpathEval("*[@system]")[0] + for silecsDesign in silecsDesigns: + devices = silecsDesign.xpathEval("Device") + for device in devices: + modified = True + device.newProp("silecs-design-ref",silecsDesign.prop("silecs-design-name")) + device.newProp("silecs-device-label",device.prop("device-name")) + device.unsetProp("device-name") + device.unlinkNode() + plc.addChild(device) + silecsDesign.unlinkNode() + alreadyThere = silecsDocument.xpathEval("/SILECS-Deploy/SilecsDesign[@silecs-design-name='" + silecsDesign.prop("silecs-design-name") + "']") + if len(alreadyThere) == 0: + deployUnitNode.addNextSibling(silecsDesign) + modified = True + return modified + diff --git a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py index 08688f5..8af7f43 100644 --- a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py +++ b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py @@ -22,16 +22,58 @@ import inspect # get caller name from shutil import copyfile import os -def testFesaClassMakeSpecificMigrator(): - currentDirectory = os.path.dirname(os.path.abspath(__file__)) - makefileSpecific = os.path.join(currentDirectory, "myProject", "Makefile.specific") - makefileSpecificOriginal = os.path.join(currentDirectory, "myProject", "Makefile.specific.original") - makefileSpecificCorrect = os.path.join(currentDirectory, "myProject", "Makefile.specific.correct") - if os.path.isfile(makefileSpecific): - os.remove(makefileSpecific) - copyfile(makefileSpecificOriginal, makefileSpecific) - fesaClassMakeSpecificMigrator(makefileSpecific) - assertFileEqual(makefileSpecific,makefileSpecificCorrect) +#-------------------------------------- def testFesaClassMakeSpecificMigrator(): + #------------- currentDirectory = os.path.dirname(os.path.abspath(__file__)) + # makefileSpecific = os.path.join(currentDirectory, "myProject", "Makefile.specific") + # makefileSpecificOriginal = os.path.join(currentDirectory, "myProject", "Makefile.specific.original") + # makefileSpecificCorrect = os.path.join(currentDirectory, "myProject", "Makefile.specific.correct") + #-------------------------------------- if os.path.isfile(makefileSpecific): + #------------------------------------------- os.remove(makefileSpecific) + #---------------------- copyfile(makefileSpecificOriginal, makefileSpecific) + #--------------------------- fesaClassMakeSpecificMigrator(makefileSpecific) + #----------------- assertFileEqual(makefileSpecific,makefileSpecificCorrect) + + +def testSilecsDeployMigrator(): + silecsDeployDocOld = '''<?xml version="1.0" encoding="UTF-8"?> +<SILECS-Deploy silecs-version="1.0.1" created="05/03/17" updated="05/03/17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/silecs-model/1.0.1/xml/DeploySchema.xsd"> + <Information> + <Owner user-login="schwinn" /> + <Editor user-login="schwinn" /> + </Information> + <Deploy-Unit name="AlexTestDU" version="0.1.0" /> + <Controller host-name="asl733"> + <Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest1"> + <Device device-name="myDev1" /> + <Device device-name="myDev2" /> + </SilecsDesign> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest2"> + <Device device-name="myDev3" /> + <Device device-name="myDev4" /> + </SilecsDesign> + </Controller> + <Controller host-name="asl744"> + <Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest1"> + <Device device-name="myDev1" /> + <Device device-name="myDev2" /> + </SilecsDesign> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AlexTest2"> + <Device device-name="myDev3" /> + <Device device-name="myDev4" /> + </SilecsDesign> + </Controller> +</SILECS-Deploy>''' + context = libxml2.parseDoc(silecsDeployDocOld) + silecsDeployMigrator(context) + print context + silecsDesigns = context.xpathEval("/SILECS-Deploy/SilecsDesign") + assertEqual(len(silecsDesigns),2) + devices = context.xpathEval("/SILECS-Deploy/Controller[@host-name='asl733']/*/Device") + assertEqual(len(devices),4) + assertEqual(devices[0].prop("silecs-design-ref"),"AlexTest1") + assertEqual(devices[0].prop("silecs-device-label"),"myDev1") def testremoveFesaConfigurationFieldParameterFile(): FesaDocOld = '''<?xml version="1.0" encoding="UTF-8"?> @@ -73,4 +115,5 @@ def testremoveFesaConfigurationFieldParameterFile(): def runTests(): #testFesaClassMakeSpecificMigrator() testremoveFesaConfigurationFieldParameterFile() + testSilecsDeployMigrator() # print deployDoc # for debugging diff --git a/silecs-codegen/src/xml/migration/migrationBase.py b/silecs-codegen/src/xml/migration/migrationBase.py index 8277ab5..f404048 100644 --- a/silecs-codegen/src/xml/migration/migrationBase.py +++ b/silecs-codegen/src/xml/migration/migrationBase.py @@ -37,7 +37,7 @@ class MigrationBase(object): def fixSilecsVersion(self, context): root = context.xpathEval("/*")[0] if root.prop("silecs-version") != self.versionOld: - raise IOError("Wrong Silecs Version - migration cancelled") + raise IOError("Wrong Silecs Version. Document-version: '" + root.prop("silecs-version") + "' script start version: '" + self.versionOld + "' - migration cancelled") root.setProp("silecs-version",self.versionNew) print("Info: Replaced old silecs-versiong string: " + self.versionOld + " with: " + self.versionNew) diff --git a/silecs-codegen/src/xml/model/Block.py b/silecs-codegen/src/xml/model/Class/Block.py similarity index 95% rename from silecs-codegen/src/xml/model/Block.py rename to silecs-codegen/src/xml/model/Class/Block.py index 45ed1f6..0ae09cb 100644 --- a/silecs-codegen/src/xml/model/Block.py +++ b/silecs-codegen/src/xml/model/Class/Block.py @@ -15,7 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from iecommon import * -from model.Register import * +from model.Class.Register import * import libxml2 @@ -24,9 +24,6 @@ class Block(object): ___settingBlockType = "Setting-Block" ___acquisitionBlockType = "Acquisition-Block" ___commandBlockType = "Command-Block" - name = "" - ___type = "" - xmlNode = None def __init__(self, xmlNode): self.xmlNode = xmlNode @@ -99,14 +96,14 @@ class ParamBlock(Block): class DesignBlock(Block): - generateFesaProperty = False - fesaPropertyName = "" - fesaGetServerActionName = "" - fesaSetServerActionName = "" def __init__(self, xmlNode): super(DesignBlock, self).__init__(xmlNode) - + self.generateFesaProperty = False + self.fesaPropertyName = "" + self.fesaGetServerActionName = "" + self.fesaSetServerActionName = "" + if self.xmlNode.hasProp("fesaPropertyName"): self.fesaPropertyName = xmlNode.prop("fesaPropertyName") else: diff --git a/silecs-codegen/src/xml/model/Class.py b/silecs-codegen/src/xml/model/Class/Class.py similarity index 98% rename from silecs-codegen/src/xml/model/Class.py rename to silecs-codegen/src/xml/model/Class/Class.py index f7fd3d0..2794060 100644 --- a/silecs-codegen/src/xml/model/Class.py +++ b/silecs-codegen/src/xml/model/Class/Class.py @@ -15,14 +15,10 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from iecommon import * -from model.Block import * +from model.Class.Block import * import libxml2 class Class(object): - - name = "" - version = "" - xmlNode = None def __init__(self, xmlNode): self.xmlNode = xmlNode diff --git a/silecs-codegen/src/xml/model/Register.py b/silecs-codegen/src/xml/model/Class/Register.py similarity index 96% rename from silecs-codegen/src/xml/model/Register.py rename to silecs-codegen/src/xml/model/Class/Register.py index ac69f21..079dcde 100644 --- a/silecs-codegen/src/xml/model/Register.py +++ b/silecs-codegen/src/xml/model/Class/Register.py @@ -22,15 +22,6 @@ class Register(object): ___acquisitionRegisterType = "Acquisition-Register" ___volatileRegisterType = "Volatile-Register" - ___type = "" - xmlNode = None - name = "" - valueTypeNode = None - valueType = "" - dim1 = 1 - dim2 = 1 - stringLength = 1 # ... currently needs to be default because of some old convention - format = "" def __init__(self, xmlNode): self.xmlNode = xmlNode @@ -38,7 +29,13 @@ class Register(object): #xmlNode.shellPrintNode() self.name = xmlNode.prop("name") self.___type = xmlNode.get_name() - + self.valueTypeNode = None + self.valueType = "" + self.dim1 = 1 + self.dim2 = 1 + self.stringLength = 1 # ... currently needs to be default because of some old convention + self.format = "" + valueTypes = xmlNode.xpathEval("*[name()='scalar' or name()='array' or name()='array2D' or name()='string' or name()='stringArray' or name()='stringArray2D']") if not valueTypes: iecommon.logError('ERROR: The register '+ self.name +' has no valueTypes.', True, {'errorlog': True}) @@ -177,12 +174,12 @@ class Register(object): #has some additionalValues class ParamRegister(Register): - size = 0 - address = 0 - memSize = 0 + def __init__(self ): - size = 0 + self.size = 0 + self.address = 0 + self.memSize = 0 def initWithParamRegisterNode(self, xmlNode): super(ParamRegister, self).__init__(xmlNode) @@ -218,12 +215,11 @@ class ParamRegister(Register): class DesignRegister(Register): - fesaFieldName = "" - generateFesaValueItem=True def __init__(self, xmlNode): super(DesignRegister, self).__init__(xmlNode) self.fesaFieldName = self.name + self.generateFesaValueItem=True if self.xmlNode.hasProp("fesaFieldName"): self.fesaFieldName = xmlNode.prop("fesaFieldName") if self.xmlNode.hasProp("generateFesaValueItem"): #SilecsHEader does not have this attribute diff --git a/silecs-codegen/src/xml/model/Class/__init__.py b/silecs-codegen/src/xml/model/Class/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/silecs-codegen/src/xml/model/Deploy/Controller.py b/silecs-codegen/src/xml/model/Deploy/Controller.py new file mode 100644 index 0000000..9d1c700 --- /dev/null +++ b/silecs-codegen/src/xml/model/Deploy/Controller.py @@ -0,0 +1,151 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from model.Deploy.Device import * +from model.Deploy.SilecsDesign import * +import libxml2 + +class Controller(object): + + def __init__(self, xmlNode): + self.hostName = "" + self.domain = "" + self.system = "" + self.model = "" + self.protocol = "" + self.brand = "" + self.baseAddress = long(0) + self.xmlNode = None + self.plcNode = None + self.devices = [] + + self.xmlNode = xmlNode + self.hostName = xmlNode.prop("host-name") + if xmlNode.hasProp("domain"): + self.domain = xmlNode.prop("domain") + self.plcNode = Controller.getPLCNode(xmlNode) + self.system = self.plcNode.prop('system') + self.model = self.plcNode.prop('model') + self.protocol = self.plcNode.prop('protocol') + + silecsHeader = Device() + silecsHeader.silecsDeviceLabel = "SilecsHeader" + silecsHeader.silecsDesignRef = "SilecsHeader" + self.devices.append(silecsHeader) + + for deviceNode in self.plcNode.xpathEval('Device'): + device = Device() + device.initFromXMLNode(deviceNode) + self.devices.append(device) + + def connectDesignObjects(self,silecsDesigns): + for device in self.devices: + for design in silecsDesigns: + if device.silecsDesignRef == design.name: + device.silecsDesign = design + + def getDevicesOfDesign(self, designName): + deviceList = [] + for device in self.devices: + if device.silecsDesignRef == designName: + deviceList.append(device) + return deviceList + + def getUsedDesigns(self): + designList = [] + for device in self.devices: + if not device.silecsDesign in designList: + designList.append(device.silecsDesign) + return designList + + @staticmethod + def getPLCNode(controllerNode): + hostName = controllerNode.prop("host-name") + plcNodes = controllerNode.xpathEval('*') + if len(plcNodes) > 1: + raise Exception( "Error: multiple plc-nodes found for controller: " + hostName ) + if len(plcNodes) < 1: + raise Exception( "Error: no plc-node found for controller: " + hostName ) + return plcNodes[0] + + @staticmethod + def createController(controllerNode): + plcNode = Controller.getPLCNode(controllerNode) + type = plcNode.get_name() + if type == "Siemens-PLC": + return SiemensController(controllerNode) + elif type == "Schneider-PLC": + return SchneiderController(controllerNode) + elif type == "Beckhoff-PLC": + return BeckhoffController(controllerNode) + elif type == "Rabbit-uC": + return DigiController(controllerNode) + elif type == "NI-Controller": + return NIController(controllerNode) + elif type == "Virtual-Controller": + return SiemensController(controllerNode) + else: + raise Exception( "Controller-Type " + type + " not supported" ) + +class SiemensController(Controller): + def __init__(self, xmlNode): + super(SiemensController, self).__init__(xmlNode) + self.brand = "SIEMENS" + self.baseAddress = long(self.plcNode.prop('base-DB-number')) + +class BeckhoffController(Controller): + addressFactor_BC9020 = 2 # BC90xx use 16 bit addressing + addressFactor_CX9020 = 1 + offset_BC9020 = 32768 + offset_CX9020 = 24576 + def __init__(self, xmlNode): + super(BeckhoffController, self).__init__(xmlNode) + self.brand = "BECKHOFF" + self.baseAddress = long(self.plcNode.prop('base-address')) + if self.model == 'BC9020': + self.baseAddress = ( self.baseAddress * self.addressFactor_BC9020 ) + self.offset_BC9020 + elif self.model == 'CX9020': + self.baseAddress = ( self.baseAddress * self.addressFactor_CX9020 ) + self.offset_CX9020 + else: + raise Exception( "Unknown beckhoff plc-model:" + self.model ) + +class SchneiderController(Controller): + addressFactor = 2 + # Premium/Quantum uses 16bit adressing for 32bit values + # Unity M340 is interpreted as 32bit address + def __init__(self, xmlNode): + super(SchneiderController, self).__init__(xmlNode) + self.brand = "SCHNEIDER" + self.baseAddress = long(self.plcNode.prop('base-address')) + self.baseAddress = self.baseAddress * self.addressFactor + +# Formally known as "Rabbit Controller" +class DigiController(Controller): + addressFactor = 2 + def __init__(self, xmlNode): + super(DigiController, self).__init__(xmlNode) + self.brand = "DIGI" + self.baseAddress = long(self.plcNode.prop('base-address')) + self.baseAddress = self.baseAddress * self.addressFactor + +class NIController(Controller): + def __init__(self, xmlNode): + super(NIController, self).__init__(xmlNode) + self.brand = "NI" + self.baseAddress = 0 + + + #xmlNode.shellPrintNode() diff --git a/silecs-codegen/src/xml/model/Deploy/Deploy.py b/silecs-codegen/src/xml/model/Deploy/Deploy.py new file mode 100644 index 0000000..4adf1a0 --- /dev/null +++ b/silecs-codegen/src/xml/model/Deploy/Deploy.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import libxml2 + +from iecommon import * +from model.Deploy.Controller import * +from model.Deploy.SilecsDesign import * + +class Deploy(object): + + def ___initInformation(self): + ownerNodes = self.xmlNode.xpathEval('Information/Owner') + if len(ownerNodes) > 1: + raise Exception( "Error: multiple owner-nodes found in deploy-document" ) + if len(ownerNodes) < 1: + raise Exception( "Error: no owner-node found in deploy-document" ) + if not ownerNodes[0].hasProp("user-login"): + raise Exception( "Error: no name property found on owner-node" ) + self.owner = ownerNodes[0].prop("user-login") + editorNodes = self.xmlNode.xpathEval('Information/Editor') + for editorNode in editorNodes: + if editorNode.hasProp("user-login"): + self.editors.append(editorNode.prop("user-login")) + + + def __init__(self, xmlNode): + self.name = "" + self.owner = "" + self.editors = [] + self.silecsVersion = "" + self.controllers = [] + self.silecsDesigns = [] + self.xmlNode = xmlNode + self.silecsVersion = xmlNode.prop("silecs-version") + self.created = xmlNode.prop("created") + self.updated = xmlNode.prop("updated") + self.___initInformation() + + deployUnitNodes = self.xmlNode.xpathEval('Deploy-Unit') + if len(deployUnitNodes) > 1: + raise Exception( "Error: multiple Deploy-Unit nodes found in deploy-document" ) + if len(deployUnitNodes) < 1: + raise Exception( "Error: no Deploy-Unit node found in deploy-document" ) + if not deployUnitNodes[0].hasProp("name"): + raise Exception( "Error: no name property found on Deploy-Unit node" ) + if not deployUnitNodes[0].hasProp("version"): + raise Exception( "Error: no version property found on Deploy-Unit node" ) + self.name = deployUnitNodes[0].prop("name") + self.version = deployUnitNodes[0].prop("version") + + ownerNodes = self.xmlNode.xpathEval('Information/Owner') + + silecsHeader = SilecsDesign() + silecsHeader.name = "SilecsHeader" + silecsHeader.version = "1.0.0" + self.silecsDesigns.append(silecsHeader) + + for designNode in self.xmlNode.xpathEval('SilecsDesign'): + design = SilecsDesign() + design.initFromXMLNode(designNode) + self.silecsDesigns.append(design) + + for controllerNode in self.xmlNode.xpathEval('Controller'): + controller = Controller.createController(controllerNode) + self.controllers.append(controller) + controller.connectDesignObjects(self.silecsDesigns) + + #xmlNode.shellPrintNode() + + + @staticmethod + def getDeployFromFile(deployFile): + root = libxml2.parseFile(deployFile) + deployNodes = root.xpathEval('/SILECS-Deploy') + if len(deployNodes) > 1: + raise Exception( "Error: multiple Deploy nodes found in deploy-document" ) + if len(deployNodes) < 1: + raise Exception( "Error: no Deploy node found in deploy-document" ) + return Deploy(deployNodes[0]) \ No newline at end of file diff --git a/silecs-codegen/src/xml/model/Deploy/Device.py b/silecs-codegen/src/xml/model/Deploy/Device.py new file mode 100644 index 0000000..855d4b7 --- /dev/null +++ b/silecs-codegen/src/xml/model/Deploy/Device.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import libxml2 +from iecommon import * + +class Device(object): + + def __init__(self): + self.xmlNode = None + self.silecsDeviceLabel = "" + self.silecsDesignRef = "" + self.fesaDeviceName = "" + self.fesaFecName = "" + self.silecsDesign = None #reference to SIlecsDesign object + + # not in init, in order to fake a silecsheader + def initFromXMLNode(self,xmlNode): + self.name = xmlNode.prop("silecs-design-name") + self.version = xmlNode.prop("silecs-design-version") + self.silecsDeviceLabel = xmlNode.prop("silecs-device-label") + self.silecsDesignRef = xmlNode.prop("silecs-design-ref") + if xmlNode.hasProp("fesa-device-name"): + self.fesaDeviceName = xmlNode.prop("fesa-device-name") + if xmlNode.hasProp("fesa-fec-name"): + self.fesaFecName = xmlNode.prop("fesa-fec-name") + #xmlNode.shellPrintNode() + + def getSilecsDeviceLabelCapitalizedNoUnderscore(self): + return iecommon.capitalizeString(self.silecsDeviceLabel.replace("-","_")) \ No newline at end of file diff --git a/silecs-codegen/src/xml/model/Deploy/SilecsDesign.py b/silecs-codegen/src/xml/model/Deploy/SilecsDesign.py new file mode 100644 index 0000000..545c263 --- /dev/null +++ b/silecs-codegen/src/xml/model/Deploy/SilecsDesign.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import libxml2 +from iecommon import * + +class SilecsDesign(object): + + def __init__(self): + self.xmlNode = None + self.name = "" + self.version = "" + + def initFromXMLNode(self,xmlNode): + self.xmlNode = xmlNode + self.name = xmlNode.prop("silecs-design-name") + self.version = xmlNode.prop("silecs-design-version") + + def getNameCapitalized(self): + return iecommon.capitalizeString(self.name) \ No newline at end of file diff --git a/silecs-codegen/src/xml/model/Deploy/__init__.py b/silecs-codegen/src/xml/model/Deploy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy index 871b51c..7b44e99 100644 --- a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy +++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy @@ -1,103 +1,100 @@ <?xml version="1.0" encoding="UTF-8"?> -<SILECS-Deploy silecs-version="2.0.0" created="06/27/16" updated="06/27/16" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/git/silecs-model/src/xml/DeploySchema.xsd"> +<SILECS-Deploy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" silecs-version="2.1.0" created="06/27/16" updated="06/27/16" xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/git/silecs-model/src/xml/DeploySchema.xsd"> <Information> - <Owner user-login="schwinn"/> - <Editor user-login="schwinn"/> + <Owner user-login="schwinn" /> + <Editor user-login="schwinn" /> </Information> - <Deploy-Unit name="AllTypesDU" version="0.1.0"/> - <Controller host-name="Siemens_TiaDevice"> - <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="DEVICE_MODE" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Deploy-Unit name="AllTypesDU" version="0.1.0" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + + + </SilecsDesign> + <Controller host-name="Siemens_TiaDevice"> + <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="DEVICE_MODE"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Siemens-PLC> + </Controller> - <Controller host-name="Siemens_TiaBlock"> - <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="BLOCK_MODE" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Controller host-name="Siemens_TiaBlock"> + <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="BLOCK_MODE"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Siemens-PLC> + </Controller> - <Controller host-name="Siemens_Step7Block"> - <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="DEVICE_MODE" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Controller host-name="Siemens_Step7Block"> + <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="DEVICE_MODE"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Siemens-PLC> + </Controller> <Controller host-name="Siemens_Step7Device"> - <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="BLOCK_MODE" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="BLOCK_MODE"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Siemens-PLC> + </Controller> <Controller host-name="Virtual_SiemensDevice"> - <Virtual-Controller model="SIMATIC_S7-VIRTUAL" - system="SNAP7 linux32" base-DB-number="0" protocol="DEVICE_MODE" /> - - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" base-DB-number="0" protocol="DEVICE_MODE"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Virtual-Controller> + + </Controller> <Controller host-name="Virtual_SiemensBlock"> - <Virtual-Controller model="SIMATIC_S7-VIRTUAL" - system="SNAP7 linux32" base-DB-number="0" protocol="BLOCK_MODE" /> - - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" base-DB-number="0" protocol="BLOCK_MODE"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Virtual-Controller> + + </Controller> <Controller host-name="Beckhoff_BC9020"> - <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Beckhoff-PLC> + </Controller> <Controller host-name="Beckhoff_CX9020"> - <Beckhoff-PLC model="CX9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Beckhoff-PLC model="CX9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Beckhoff-PLC> + </Controller> <Controller host-name="Schneider_PremiumQuantum"> - <Schneider-PLC model="Premium" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Schneider-PLC model="Premium" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Schneider-PLC> + </Controller> <Controller host-name="Schneider_M340"> - <Schneider-PLC model="M340" system="UNITY Pro" - protocol="BLOCK_MODE" base-address="0" /> - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Schneider-PLC model="M340" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Schneider-PLC> + </Controller> <Controller host-name="Rabbit_DeviceMode"> - <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C" - protocol="DEVICE_MODE" base-address="0" /> - - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C" protocol="DEVICE_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Rabbit-uC> + + </Controller> <Controller host-name="Rabbit_BlockMode"> - <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C" - protocol="BLOCK_MODE" base-address="0" /> - - <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> - <Device device-name="testDevice1"/> - <Device device-name="testDevice2"/> - </SilecsDesign> + <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Rabbit-uC> + + </Controller> </SILECS-Deploy> diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy.backup b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy.backup new file mode 100644 index 0000000..871b51c --- /dev/null +++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy.backup @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<SILECS-Deploy silecs-version="2.0.0" created="06/27/16" updated="06/27/16" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/git/silecs-model/src/xml/DeploySchema.xsd"> + <Information> + <Owner user-login="schwinn"/> + <Editor user-login="schwinn"/> + </Information> + <Deploy-Unit name="AllTypesDU" version="0.1.0"/> + <Controller host-name="Siemens_TiaDevice"> + <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="DEVICE_MODE" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Siemens_TiaBlock"> + <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="BLOCK_MODE" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Siemens_Step7Block"> + <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="DEVICE_MODE" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Siemens_Step7Device"> + <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="BLOCK_MODE" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Virtual_SiemensDevice"> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" + system="SNAP7 linux32" base-DB-number="0" protocol="DEVICE_MODE" /> + + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Virtual_SiemensBlock"> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" + system="SNAP7 linux32" base-DB-number="0" protocol="BLOCK_MODE" /> + + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Beckhoff_BC9020"> + <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Beckhoff_CX9020"> + <Beckhoff-PLC model="CX9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Schneider_PremiumQuantum"> + <Schneider-PLC model="Premium" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Schneider_M340"> + <Schneider-PLC model="M340" system="UNITY Pro" + protocol="BLOCK_MODE" base-address="0" /> + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Rabbit_DeviceMode"> + <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C" + protocol="DEVICE_MODE" base-address="0" /> + + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> + <Controller host-name="Rabbit_BlockMode"> + <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C" + protocol="BLOCK_MODE" base-address="0" /> + + <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes"> + <Device device-name="testDevice1"/> + <Device device-name="testDevice2"/> + </SilecsDesign> + </Controller> +</SILECS-Deploy> diff --git a/silecs-codegen/src/xml/test/general/genDuWrapperTest.py b/silecs-codegen/src/xml/test/general/genDuWrapperTest.py index d0b43d0..78040c1 100644 --- a/silecs-codegen/src/xml/test/general/genDuWrapperTest.py +++ b/silecs-codegen/src/xml/test/general/genDuWrapperTest.py @@ -47,6 +47,6 @@ def CompareGeneratedFiles(): assertFileEqual( duControllerWrapperGenerated, duControllerWrapperCorrect) def runTests(): - genDuWrapperBase(deployFilePath,fakeGetDuWrapperFile,"fake",fakeGetSilecsDesignFilePath, fakeGetDuDesignWrapperFile,"AllTypesDU","0.1.0") + genDuWrapperBase(deployFilePath,fakeGetDuWrapperFile,"fake",fakeGetSilecsDesignFilePath, fakeGetDuDesignWrapperFile) CompareGeneratedFiles() allTestsOk() diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.py b/silecs-codegen/src/xml/test/general/genplcsrcTest.py index 12e56fa..73cc097 100644 --- a/silecs-codegen/src/xml/test/general/genplcsrcTest.py +++ b/silecs-codegen/src/xml/test/general/genplcsrcTest.py @@ -22,21 +22,23 @@ from test.testBase import * import genplcsrc import iecommon import iefiles +from model.Deploy.Deploy import Deploy import libxml2 + + testFolder = "test" generationFolder = testFolder + "/generated_temp" comparisonFolder = testFolder + "/generated_correct" generationFoldeController = generationFolder + "/controller" comparisonFolderController = comparisonFolder + "/controller" def generatePLCSources(): - deployDOM = libxml2.parseFile(testFolder + "/AllTypesDU.silecsdeploy") - controllerNodes = deployDOM.xpathEval("/SILECS-Deploy/Controller") - for controllerNode in controllerNodes: - paramsFile = generationFolder + "/client/" + controllerNode.prop("host-name") + ".silecsparam" - genplcsrc.generateControllerCode(controllerNode, paramsFile, generationFoldeController ,{'errorlog': True}) - deployDOM.freeDoc() + silecsDeploy = Deploy.getDeployFromFile(testFolder + "/AllTypesDU.silecsdeploy") + for controller in silecsDeploy.controllers: + paramsFile = generationFolder + "/client/" + controller.hostName + ".silecsparam" + genplcsrc.generateControllerCode(controller, paramsFile, generationFoldeController ,{'errorlog': True}) + def CompareGeneratedFiles(hostName,fileExtension): fileGeneratedPath = generationFoldeController + "/" + hostName + fileExtension diff --git a/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp b/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp index 40f7be4..76cd36e 100644 --- a/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp +++ b/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp @@ -60,7 +60,7 @@ namespace AllTypes // Retrieve the PLC related to the current FESA device // (from 'plcHostName' FESA field defined on that purpose). - Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get()); + Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get()); // Update the PLC Slave registers from related FESA fields just before synchronising done at connection time setPLCSlaveRegisters(pPLC, serviceLocator); diff --git a/silecs-codegen/src/xml/test/generated_correct/AllTypes.h b/silecs-codegen/src/xml/test/generated_correct/AllTypes.h index af3396c..79ecda2 100644 --- a/silecs-codegen/src/xml/test/generated_correct/AllTypes.h +++ b/silecs-codegen/src/xml/test/generated_correct/AllTypes.h @@ -138,7 +138,7 @@ namespace AllTypes static bool isInitialized(){ return AbstractAllTypes::isInitialized(); } static Silecs::PLC* getPLC(Device* pDevice) { - return AbstractAllTypes::theCluster()->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get()); + return AbstractAllTypes::theCluster()->getPLC(pDevice->plcHostName.get()); } static MyROBlock_Type MyROBlock; diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam index ca98dcf..163cd5f 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.858569"/> + <Generation date="2017-07-20 10:34:35.153287"/> <Deployment checksum="1037751963"/> </Mapping-Info> - <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" usedMemory="MW16384..MW16407 / 24 words"> <Acquisition-Block name="hdrBlk" size="14" address="32768" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="17"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam index 4fcb642..b711383 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.893890"/> + <Generation date="2017-07-20 10:34:35.186172"/> <Deployment checksum="2754857673"/> </Mapping-Info> - <SILECS-Mapping plc-name="Beckhoff_CX9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Beckhoff_CX9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" usedMemory="MW12288..MW12313 / 26 words"> <Acquisition-Block name="hdrBlk" size="14" address="24576" mem-size="52"> <Acquisition-Register name="_version" size="1" address="0" mem-size="17"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam index 023db86..161f848 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:47.039562"/> + <Generation date="2017-07-20 10:34:35.299118"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam index 62778b0..c762cf3 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:47.005686"/> + <Generation date="2017-07-20 10:34:35.271989"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam index f46258a..6a7ba61 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.968837"/> + <Generation date="2017-07-20 10:34:35.244711"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam index 6c0873b..0daaea4 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.931934"/> + <Generation date="2017-07-20 10:34:35.214606"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam index 857d51b..1bbf34f 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.708946"/> + <Generation date="2017-07-20 10:34:35.015979"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam index 6ae45a1..fadc781 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.747628"/> + <Generation date="2017-07-20 10:34:35.051991"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam index cc3461d..783f886 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.675405"/> + <Generation date="2017-07-20 10:34:34.977960"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam index 7488b87..e4721ef 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam @@ -2,10 +2,10 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-06-08 16:28:46.637256"/> + <Generation date="2017-07-20 10:34:34.943897"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO"> + <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h index 0434b10..7db9cbf 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Beckhoff_BC9020", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h index 7feef99..a5e255f 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Beckhoff_CX9020", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h index c562005..b59164f 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Rabbit_BlockMode", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h index a90d775..747806c 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Rabbit_DeviceMode", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h index d31fa17..78d39f6 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Schneider_M340", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h index 58576f6..895132c 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Schneider_PremiumQuantum", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h index 9e32650..0ff25b6 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Siemens_Step7Block", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h index be5bd8a..d74d9da 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Siemens_Step7Device", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h index 63877a3..95fc78e 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Siemens_TiaBlock", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h index e6a3029..8041e9f 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Siemens_TiaDevice", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/SilecsHeader.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/SilecsHeader.h new file mode 100644 index 0000000..af86363 --- /dev/null +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/SilecsHeader.h @@ -0,0 +1,38 @@ +/* Copyright CERN 2015 + * + * WARNING: This code is automatically generated from your SILECS deploy unit document. + * You should never modify the content of this file as it would break consistency. + * Furthermore, any changes will be overwritten in the next code generation. + * Any modification shall be done using the SILECS development environment + * and regenerating this source code. + */ + +#ifndef SILECSHEADER_H_ +#define SILECSHEADER_H_ + +#include <silecs-communication/wrapper/Block.h> +#include <silecs-communication/wrapper/DeployUnit.h> +#include <silecs-communication/wrapper/Design.h> +#include <silecs-communication/wrapper/Device.h> + +namespace SilecsHeader +{ + + +class Design : public SilecsWrapper::Design +{ +public: + + Design(SilecsWrapper::DeployUnit *deployUnit) : + SilecsWrapper::Design("SilecsHeader", "1.0.0", deployUnit) + { + } + + ~Design() + { + } +}; + +} /* namespace SilecsHeader */ + +#endif /* SILECSHEADER_H_ */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h index 1681d8b..48a682a 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Virtual_SiemensBlock", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h index 8b1ef27..f37dd1c 100644 --- a/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h +++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h @@ -14,6 +14,7 @@ #include <silecs-communication/wrapper/DeployUnit.h> #include <silecs-communication/wrapper/Design.h> +#include "SilecsHeader.h" #include "AllTypes.h" namespace AllTypesDU @@ -63,6 +64,14 @@ public: return getInstance("", globalConfig); } + /*! + * \brief Return pointer to the deployed design SilecsHeader. + */ + SilecsHeader::Design* getSilecsHeader() + { + return _SilecsHeader; + } + /*! * \brief Return pointer to the deployed design AllTypes. */ @@ -73,11 +82,15 @@ public: private: + SilecsHeader::Design* _SilecsHeader; AllTypes::Design* _AllTypes; DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) : SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig) { + // Construct Design SilecsHeader + _SilecsHeader = new SilecsHeader::Design((SilecsWrapper::DeployUnit*) this); + // Construct Design AllTypes _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this); @@ -85,6 +98,7 @@ private: ~DeployUnit() { + delete _SilecsHeader; delete _AllTypes; } }; @@ -96,6 +110,7 @@ public: Controller(SilecsWrapper::Design *design, const std::string parameterFile) : SilecsWrapper::Controller("Virtual_SiemensDevice", "", design, parameterFile) { + _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("SilecsHeader", new SilecsWrapper::Device("SilecsHeader", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this))); _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this))); } @@ -127,6 +142,14 @@ public: return _deviceMap; } + /*! + * \brief Get pointer to device SilecsHeader. + */ + SilecsWrapper::Device* getSilecsHeader() + { + return _deviceMap["SilecsHeader"]; + } + /*! * \brief Get pointer to device testDevice1. */ diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp index 991e0e9..31ec128 100755 --- a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp +++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp @@ -762,7 +762,7 @@ void diagnosticToolMainView::fillClassNameComboBox() boost::ptr_vector<ElementXML> classNodes; try { - classNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/Controller/SilecsDesign"); + classNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/SilecsDesign"); } catch(const Silecs::SilecsException& ex2) { diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp index b264bde..115f40d 100755 --- a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp +++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp @@ -125,7 +125,7 @@ Item *silecsModule::generateTree(string className, string deployFile) } else { - ElementXML silecsDesign = parserDeploy.getFirstElementFromXPath("/SILECS-Deploy/Controller/SilecsDesign[@silecs-design-name='" + className + "']"); + ElementXML silecsDesign = parserDeploy.getFirstElementFromXPath("/SILECS-Deploy/SilecsDesign[@silecs-design-name='" + className + "']"); string classVersion = silecsDesign.getAttribute("silecs-design-version"); silecsCluster = silecsService->getCluster(className,classVersion); root->setText(0,QString::fromStdString(className+" v"+classVersion)); @@ -133,26 +133,20 @@ Item *silecsModule::generateTree(string className, string deployFile) root->setWhatsThis(0,QString::fromStdString(CLUSTER_TYPE)); root->setLinkedObject(silecsCluster); + ElementXML deployUnitNode = parserDeploy.getFirstElementFromXPath("/SILECS-Deploy/Deploy-Unit"); + string deployName = deployUnitNode.getAttribute("name"); + std::size_t deployFolderPos = deployFile.find(deployName); + string deployProjectPath = deployFile.substr(0,deployFolderPos) + deployName; boost::ptr_vector<ElementXML> controllerNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/Controller"); boost::ptr_vector<ElementXML>::const_iterator controllerIter; for(controllerIter = controllerNodes.begin(); controllerIter != controllerNodes.end(); controllerIter++) { std::string plcName = controllerIter->getAttribute("host-name"); - if(plcName.compare("")==true) - { - Utils::logError(messageConsole_,"PLC name empty - will be skipped"); - break; - } Silecs::PLC *plc; string parameterFile = ""; try { - ElementXML deployUnitNode = parserDeploy.getFirstElementFromXPath("/SILECS-Deploy/Deploy-Unit"); - string deployName = deployUnitNode.getAttribute("name"); - std::size_t deployFolderPos = deployFile.find(deployName); - string deployProject = deployFile.substr(0,deployFolderPos) + deployName; - parameterFile = deployProject + "/generated/client/" + plcName + ".silecsparam"; - + parameterFile = deployProjectPath + "/generated-silecs/client/" + plcName + ".silecsparam"; Utils::logInfo(messageConsole_,"Loading parameter file: " + parameterFile); plc = silecsCluster->getPLC(plcName,parameterFile); } diff --git a/silecs-model/src/xml/DeploySchema.xsd b/silecs-model/src/xml/DeploySchema.xsd index c736042..1bace0f 100644 --- a/silecs-model/src/xml/DeploySchema.xsd +++ b/silecs-model/src/xml/DeploySchema.xsd @@ -2,644 +2,668 @@ <!-- Copyright 2016 CERN and GSI This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. --> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> - <xs:include schemaLocation="shared.xsd" /> + <xs:include schemaLocation="shared.xsd" /> - <xs:element name="SILECS-Deploy"> - <xs:annotation> - <xs:documentation>A SILECS configuration contains the class designs, - the memory mapping and the hardware distribution for a given set of - PLCs. - </xs:documentation> - <xs:appinfo> - <doc> - The SILECS configuration defines the data structure and the - communication parameters required for the interconnection of the - PLCs and the Front-End clients. It consists of 3 parts: - <ol> - <li> Design: to define the structure of the exchanged data - <li> Mapping: to define the PLC memory mapping and the - protocol - parameters - <li> Generation: to define the hardware on - which we will deployed the - different Mapping - </ol> - Generally - under the responsability of a unique expert entity, an SILECS - configuration is done for a set of classes and PLCs in the scope of - a particular project or set of equipment. - </doc> - </xs:appinfo> - </xs:annotation> - <xs:complexType> - <xs:sequence> - <xs:element name="Information"> - <xs:complexType> - <xs:sequence> - <xs:element name="Owner"> - <xs:complexType> - <xs:attribute name="user-login" type="xs:string" use="required" /> - </xs:complexType> - </xs:element> - <xs:element name="Editor" maxOccurs="unbounded"> - <xs:complexType> - <xs:attribute name="user-login" type="xs:string" use="required" /> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="Deploy-Unit"> - <xs:complexType> - <xs:attribute name="name" type="DeployNameType" use="required" /> - <xs:attribute name="version" type="VersionType" use="required" /> - </xs:complexType> - </xs:element> - <xs:element name="SilecsDesign" type="SilecsDesignType" maxOccurs="unbounded" minOccurs="1"> - <xs:unique name="Design-name-uniquer"> - <xs:selector xpath="." /> - <xs:field xpath="@silecs-design-name" /> - </xs:unique> - </xs:element> - <xs:element name="Controller" type="ControllerType" maxOccurs="unbounded" minOccurs="1"> - <xs:unique name="silecs-device-label-unique-per-controller"> - <xs:selector xpath="*/Device" /> - <xs:field xpath="@silecs-device-label" /> - </xs:unique> - </xs:element> - </xs:sequence> - <xs:attribute name="silecs-version" type="xs:string" use="required"> - <xs:annotation> - <xs:appinfo> - <doc>Silecs framework version</doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="created" type="xs:string" use="required"> - <xs:annotation> - <xs:appinfo> - <doc>Creation date</doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="updated" type="xs:string" use="required"> - <xs:annotation> - <xs:appinfo> - <doc>Last update Date</doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:complexType> - <xs:unique name="Host-name-unique-per-silecsdeploy"> - <xs:selector xpath="Controller" /> - <xs:field xpath="@host-name" /> - </xs:unique> - <xs:unique name="fesa-device-name-unique"> - <xs:selector xpath="Controller/*/Device" /> - <xs:field xpath="@fesa-device-name" /> - </xs:unique> - <xs:keyref name="SilecsDesignRef" refer="SilecsDesign"> - <xs:selector xpath="Controller/*/Device" /> - <xs:field xpath="@silecs-design-ref" /> - </xs:keyref> - <xs:key name="SilecsDesign"> - <xs:selector xpath="SilecsDesign" /> - <xs:field xpath="@silecs-design-name" /> - </xs:key> - </xs:element> + <xs:element name="SILECS-Deploy"> + <xs:annotation> + <xs:documentation>A SILECS configuration contains the class designs, + the memory mapping and the hardware distribution for a given set of + PLCs. + </xs:documentation> + <xs:appinfo> + <doc> + The SILECS configuration defines the data structure and the + communication parameters required for the interconnection of the + PLCs and the Front-End clients. It consists of 3 parts: + <ol> + <li> Design: to define the structure of the exchanged data + <li> Mapping: to define the PLC memory mapping and the + protocol + parameters + <li> Generation: to define the hardware on + which we will deployed the + different Mapping + </ol> + Generally + under the responsability of a unique expert entity, an SILECS + configuration is done for a set of classes and PLCs in the scope of + a particular project or set of equipment. + </doc> + </xs:appinfo> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name="Information"> + <xs:complexType> + <xs:sequence> + <xs:element name="Owner"> + <xs:complexType> + <xs:attribute name="user-login" type="xs:string" use="required" /> + </xs:complexType> + </xs:element> + <xs:element name="Editor" maxOccurs="unbounded"> + <xs:complexType> + <xs:attribute name="user-login" type="xs:string" use="required" /> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="Deploy-Unit"> + <xs:complexType> + <xs:attribute name="name" type="DeployNameType" use="required" /> + <xs:attribute name="version" type="VersionType" use="required" /> + </xs:complexType> + </xs:element> + <xs:element name="SilecsDesign" type="SilecsDesignType" maxOccurs="unbounded" minOccurs="1"> + <xs:unique name="Design-name-uniquer"> + <xs:selector xpath="." /> + <xs:field xpath="@silecs-design-name" /> + </xs:unique> + </xs:element> + <xs:element name="Controller" type="ControllerType" maxOccurs="unbounded" minOccurs="1"> + <xs:unique name="silecs-device-label-unique-per-controller"> + <xs:selector xpath="*/Device" /> + <xs:field xpath="@silecs-device-label" /> + </xs:unique> + </xs:element> + </xs:sequence> + <xs:attribute name="silecs-version" type="xs:string" use="required"> + <xs:annotation> + <xs:appinfo> + <doc>Silecs framework version</doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="created" type="xs:string" use="required"> + <xs:annotation> + <xs:appinfo> + <doc>Creation date</doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="updated" type="xs:string" use="required"> + <xs:annotation> + <xs:appinfo> + <doc>Last update Date</doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:unique name="Host-name-unique-per-silecsdeploy"> + <xs:selector xpath="Controller" /> + <xs:field xpath="@host-name" /> + </xs:unique> + <xs:unique name="fesa-device-name-unique"> + <xs:selector xpath="Controller/*/Device" /> + <xs:field xpath="@fesa-device-name" /> + </xs:unique> + <xs:keyref name="SilecsDesignRef" refer="SilecsDesign"> + <xs:selector xpath="Controller/*/Device" /> + <xs:field xpath="@silecs-design-ref" /> + </xs:keyref> + <xs:key name="SilecsDesign"> + <xs:selector xpath="SilecsDesign" /> + <xs:field xpath="@silecs-design-name" /> + </xs:key> + </xs:element> - <xs:complexType name="ControllerType"> - <xs:sequence> - <xs:choice> - <xs:element name="Siemens-PLC" type="SiemensPLCType"> - <xs:annotation> - <xs:documentation>A Siemens-Mapping defines a particular Mapping - of classes intended to SIMATIC PLCs - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Schneider-PLC" type="SchneiderPLCType"> - <xs:annotation> - <xs:documentation>A Schneider-Mapping defines a particular Mapping - of classes intended to PL7/UNITY PLCs - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Beckhoff-PLC" type="BeckhoffPLCType"> - <xs:annotation> - <xs:documentation>A Beckhoff-Mapping defines a particular Mapping - of classes intended to TwinCat PLCs - </xs:documentation> - </xs:annotation> - </xs:element> - <!-- No support for this type in CERN codegen so far<xs:element name="Beckhoff-RIO" type="BeckhoffRIOType"> <xs:annotation> <xs:documentation>A Beckhoff-RIO deployment defines the physical Mapping of TwinCAT Remote IO modules.</xs:documentation> </xs:annotation> </xs:element> --> - <xs:element name="Rabbit-uC" type="RabbituCType"> - <xs:annotation> - <xs:documentation>A Rabbit-Mapping defines a particular Mapping of - classes intended for Rabbit microcontrollers - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Virtual-Controller" type="VirtualControllerType"> - <xs:annotation> - <xs:documentation>Defines a particular C++ code mapping of classes - intended for Software controller - </xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="NI-Controller" type="NIControllerType"> - <xs:annotation> - <xs:documentation>A NI-Mapping defines a particular Mapping of - classes intended to National Instrument Controllers - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:choice> - </xs:sequence> - <xs:attribute name="host-name" type="HostNameType" use="required" /> - </xs:complexType> + <xs:complexType name="ControllerType"> + <xs:sequence> + <xs:choice> + <xs:element name="Siemens-PLC" type="SiemensPLCType"> + <xs:annotation> + <xs:documentation>A Siemens-Mapping defines a particular Mapping + of classes intended to SIMATIC PLCs + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Schneider-PLC" type="SchneiderPLCType"> + <xs:annotation> + <xs:documentation>A Schneider-Mapping defines a particular Mapping + of classes intended to PL7/UNITY PLCs + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Beckhoff-PLC" type="BeckhoffPLCType"> + <xs:annotation> + <xs:documentation>A Beckhoff-Mapping defines a particular Mapping + of classes intended to TwinCat PLCs + </xs:documentation> + </xs:annotation> + </xs:element> + <!-- No support for this type in CERN codegen so far<xs:element name="Beckhoff-RIO" type="BeckhoffRIOType"> <xs:annotation> <xs:documentation>A Beckhoff-RIO deployment defines the physical Mapping of TwinCAT Remote IO modules.</xs:documentation> </xs:annotation> </xs:element> --> + <xs:element name="Rabbit-uC" type="RabbituCType"> + <xs:annotation> + <xs:documentation>A Rabbit-Mapping defines a particular Mapping of + classes intended for Rabbit microcontrollers + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Virtual-Controller" type="VirtualControllerType"> + <xs:annotation> + <xs:documentation>Defines a particular C++ code mapping of classes + intended for Software controller + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NI-Controller" type="NIControllerType"> + <xs:annotation> + <xs:documentation>A NI-Mapping defines a particular Mapping of + classes intended to National Instrument Controllers + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + </xs:sequence> + <xs:attribute name="host-name" type="HostNameType" use="required" /> + <xs:attribute name="domain" type="DomainType" use="optional"> + <xs:annotation> + <xs:documentation>Defines the domain of deployment (Accelerator or Test)</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> - <xs:complexType name="SilecsDesignType"> - <xs:attribute name="silecs-design-name" type="SilecsClassNameType" use="required" /> - <xs:attribute name="silecs-design-version" type="VersionType" use="required" /> - </xs:complexType> + <xs:complexType name="SilecsDesignType"> + <xs:attribute name="silecs-design-name" type="SilecsClassNameType" use="required" /> + <xs:attribute name="silecs-design-version" type="VersionType" use="required" /> + </xs:complexType> - <xs:complexType name="DeviceType"> - <xs:sequence> - <xs:annotation> - <xs:documentation>The device is an instance of the related - silecs-design. - </xs:documentation> - <xs:appinfo> - <doc> - The device is an instance of the related SILECS design class. - The label is dedicated to the PLC process and the SILECS client - software to identify the device in the scope of that class in that - particular Mapping. - It does not identify a unique device instance - of the control system - at the supervision level. - The device sequence - will occupy contiguous segment of PLC memory - respecting their exact - ordering. - The SILECS tool assists the expert in ordering devices as - required. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:sequence> - <xs:attribute name="silecs-device-label" type="DeviceNameType" use="required" /> - <xs:attribute name="silecs-design-ref" type="SilecsClassNameType" use="required" /> - <xs:attribute name="fesa-device-name" type="DeviceNameType" use="optional" /> - <xs:attribute name="fesa-fec-name" type="HostNameType" use="optional" /> - </xs:complexType> + <xs:complexType name="DeviceType"> + <xs:sequence> + <xs:annotation> + <xs:documentation>The device is an instance of the related + silecs-design. + </xs:documentation> + <xs:appinfo> + <doc> + The device is an instance of the related SILECS design class. + The label is dedicated to the PLC process and the SILECS client + software to identify the device in the scope of that class in that + particular Mapping. + It does not identify a unique device instance + of the control system + at the supervision level. + The device sequence + will occupy contiguous segment of PLC memory + respecting their exact + ordering. + The SILECS tool assists the expert in ordering devices as + required. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:sequence> + <xs:attribute name="silecs-device-label" type="DeviceNameType" use="required" /> + <xs:attribute name="silecs-design-ref" type="SilecsClassNameType" use="required" /> + <xs:attribute name="fesa-device-name" type="DeviceNameType" use="optional" /> + <xs:attribute name="fesa-fec-name" type="HostNameType" use="optional" /> + </xs:complexType> - <xs:simpleType name="HostNameType"> - <xs:restriction base="xs:string"> - <xs:minLength value="1" /> - <xs:pattern value="[_A-Za-z0-9]*" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="DeployNameType"> - <xs:restriction base="xs:string"> - <xs:minLength value="1" /> - <xs:maxLength value="20" /> - <xs:pattern value="[_A-Za-z]+[_A-Za-z0-9]*" /> - </xs:restriction> - </xs:simpleType> + <xs:simpleType name="HostNameType"> + <xs:restriction base="xs:string"> + <xs:minLength value="1" /> + <xs:pattern value="[_A-Za-z0-9]*" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="DeployNameType"> + <xs:restriction base="xs:string"> + <xs:minLength value="1" /> + <xs:maxLength value="20" /> + <xs:pattern value="[_A-Za-z]+[_A-Za-z0-9]*" /> + </xs:restriction> + </xs:simpleType> - <xs:simpleType name="DeviceNameType"> - <xs:restriction base="xs:string"> - <xs:minLength value="1" /> - <xs:maxLength value="30" /> - <!-- In FESA the deviceName is restricted to max. 30 characters --> - <xs:pattern value="[_A-Za-z][_A-Za-z0-9]*" /> - </xs:restriction> - </xs:simpleType> + <xs:simpleType name="DeviceNameType"> + <xs:restriction base="xs:string"> + <xs:minLength value="1" /> + <xs:maxLength value="30" /> + <!-- In FESA the deviceName is restricted to max. 30 characters --> + <xs:pattern value="[_A-Za-z][_A-Za-z0-9]*" /> + </xs:restriction> + </xs:simpleType> - <xs:simpleType name="SiemensSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="STEP-7" /> - <xs:enumeration value="TIA-PORTAL" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="SchneiderSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="UNITY Pro" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="BeckhoffSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="TWINCat" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="RabbitSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="Standard-C" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="NISystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="Labview" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="BothProtocolType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="DEVICE_MODE" /> - <xs:enumeration value="BLOCK_MODE" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="DeviceProtocolType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="DEVICE_MODE" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="BlockProtocolType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="BLOCK_MODE" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="PCSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="SNAP7 linux32" /> - <xs:enumeration value="SNAP7 linux64" /> - </xs:restriction> - </xs:simpleType> + <xs:simpleType name="SiemensSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="STEP-7" /> + <xs:enumeration value="TIA-PORTAL" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="SchneiderSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="UNITY Pro" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="BeckhoffSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="TWINCat" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="RabbitSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Standard-C" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NISystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Labview" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="BothProtocolType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="DEVICE_MODE" /> + <xs:enumeration value="BLOCK_MODE" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="DeviceProtocolType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="DEVICE_MODE" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="BlockProtocolType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="BLOCK_MODE" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="PCSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="SNAP7 linux32" /> + <xs:enumeration value="SNAP7 linux64" /> + </xs:restriction> + </xs:simpleType> - <xs:complexType name="PLCBaseType"> - <xs:sequence> - <xs:element name="Device" type="DeviceType" maxOccurs="unbounded" /> - </xs:sequence> - </xs:complexType> + <xs:simpleType name="DomainType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="ALL"/> + <xs:enumeration value="ADE"/> + <xs:enumeration value="CPS"/> + <xs:enumeration value="CTF"/> + <xs:enumeration value="ISO"/> + <xs:enumeration value="LEI"/> + <xs:enumeration value="LHC"/> + <xs:enumeration value="LIN"/> + <xs:enumeration value="LN3"/> + <xs:enumeration value="LN4"/> + <xs:enumeration value="PSB"/> + <xs:enumeration value="REX"/> + <xs:enumeration value="SPS"/> + <xs:enumeration value="TST"/> + </xs:restriction> + </xs:simpleType> + + <xs:complexType name="PLCBaseType"> + <xs:sequence> + <xs:element name="Device" type="DeviceType" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> - <xs:complexType name="SiemensPLCType"> - <xs:complexContent> - <xs:extension base="PLCBaseType"> - <xs:attribute name="system" type="SiemensSystemType" use="required"> - <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> - <xs:appinfo> - <doc> - System infrastructure used to develop and/or configure the - controller - software. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="model" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="SIMATIC_S7-300" /> - <xs:enumeration value="SIMATIC_S7-400" /> - <xs:enumeration value="SIMATIC_S7-1200" /> - <xs:enumeration value="SIMATIC_S7-1500" /> - <xs:enumeration value="SIMATIC_ET-200S" /> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="protocol" type="BothProtocolType" use="required"> - <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> - <xs:appinfo> - <doc> - DEVICE_MODE: One S7-DB per class/device - ([class-name]_[device-label|id]), - <br>containing the - corresponding ordered list of Blocks - <br>BLOCK_MODE: One - S7-DB per class/block - ([class-name]_[block-name]), - <br>containing array of - corresponding Block, one element - per device - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required"> - <xs:annotation> - <xs:documentation>Number of the diagnostic DB that is the first - one of the global configuration (corresponds to the common - SilecsHeader data-block). - </xs:documentation> - <xs:appinfo> - <doc> - Number of the diagnostic DB that is the first one of the - global - configuration ( >=1) - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> + <xs:complexType name="SiemensPLCType"> + <xs:complexContent> + <xs:extension base="PLCBaseType"> + <xs:attribute name="system" type="SiemensSystemType" use="required"> + <xs:annotation> + <xs:documentation>System infrastructure used to develop and/or + configure the controller software. + </xs:documentation> + <xs:appinfo> + <doc> + System infrastructure used to develop and/or configure the + controller + software. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="model" use="required"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="SIMATIC_S7-300" /> + <xs:enumeration value="SIMATIC_S7-400" /> + <xs:enumeration value="SIMATIC_S7-1200" /> + <xs:enumeration value="SIMATIC_S7-1500" /> + <xs:enumeration value="SIMATIC_ET-200S" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="protocol" type="BothProtocolType" use="required"> + <xs:annotation> + <xs:documentation>Data access mode is defined at PLC level for all + the classes + </xs:documentation> + <xs:appinfo> + <doc> + DEVICE_MODE: One S7-DB per class/device + ([class-name]_[device-label|id]), + <br>containing the + corresponding ordered list of Blocks + <br>BLOCK_MODE: One + S7-DB per class/block + ([class-name]_[block-name]), + <br>containing array of + corresponding Block, one element + per device + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required"> + <xs:annotation> + <xs:documentation>Number of the diagnostic DB that is the first + one of the global configuration (corresponds to the common + SilecsHeader data-block). + </xs:documentation> + <xs:appinfo> + <doc> + Number of the diagnostic DB that is the first one of the + global + configuration ( >=1) + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> - <xs:complexType name="SchneiderPLCType"> - <xs:complexContent> - <xs:extension base="PLCBaseType"> - <xs:attribute name="system" type="SchneiderSystemType" use="required"> - <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> - <xs:appinfo> - <doc> - System infrastructure used to develop and/or configure the - controller - software. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="model" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="Premium" /> - <xs:enumeration value="Quantum" /> - <xs:enumeration value="M340" /> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="protocol" type="BlockProtocolType" use="required"> - <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> - <xs:appinfo> - <doc> - BLOCK_MODE: One data-segment per class/block - ([class-name]_[block-name]), - <br>containing array of - corresponding Block, one element per - device - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> - <xs:annotation> - <xs:documentation>Start address of the SILECS configuration - (corresponds to the common SilecsHeader block address). Attention: - 16bit address value is expected independently from the HW model (16 - or 32 bit). - </xs:documentation> - <xs:appinfo> - <doc> - Start address of the SILECS configuration (corresponds to the - common - SilecsHeader block address). - <br>Attention: 16bit - address value is expected independently from the HW model - (16 or 32 - bit) - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> + <xs:complexType name="SchneiderPLCType"> + <xs:complexContent> + <xs:extension base="PLCBaseType"> + <xs:attribute name="system" type="SchneiderSystemType" use="required"> + <xs:annotation> + <xs:documentation>System infrastructure used to develop and/or + configure the controller software. + </xs:documentation> + <xs:appinfo> + <doc> + System infrastructure used to develop and/or configure the + controller + software. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="model" use="required"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="Premium" /> + <xs:enumeration value="Quantum" /> + <xs:enumeration value="M340" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="protocol" type="BlockProtocolType" use="required"> + <xs:annotation> + <xs:documentation>Data access mode is defined at PLC level for all + the classes + </xs:documentation> + <xs:appinfo> + <doc> + BLOCK_MODE: One data-segment per class/block + ([class-name]_[block-name]), + <br>containing array of + corresponding Block, one element per + device + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> + <xs:annotation> + <xs:documentation>Start address of the SILECS configuration + (corresponds to the common SilecsHeader block address). Attention: + 16bit address value is expected independently from the HW model (16 + or 32 bit). + </xs:documentation> + <xs:appinfo> + <doc> + Start address of the SILECS configuration (corresponds to the + common + SilecsHeader block address). + <br>Attention: 16bit + address value is expected independently from the HW model + (16 or 32 + bit) + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> - <xs:complexType name="BeckhoffPLCType"> - <xs:complexContent> - <xs:extension base="PLCBaseType"> - <xs:attribute name="system" type="BeckhoffSystemType" use="required"> - <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> - <xs:appinfo> - <doc> - System infrastructure used to develop and/or configure the - Controller - software. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="model" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="BC9020" /> - <xs:enumeration value="CX9020" /> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="protocol" type="BlockProtocolType" use="required"> - <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> - <xs:appinfo> - <doc> - BLOCK_MODE: One data-segment per class/block - ([class-name]_[block-name]), - <br>containing array of - corresponding Block, one element per - device - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> - <xs:annotation> - <xs:documentation>Start address of the SILECS configuration - (corresponds to the common SilecsHeader block address). Attention: - 16bit address value is expected independently from the HW model (16 - or 32 bit). - </xs:documentation> - <xs:appinfo> - <doc> - Start address of the SILECS configuration (corresponds to the - common - SilecsHeader block address). - <br>Attention: 16bit - address value is expected independently from the HW model - (16 or 32 - bit) - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> + <xs:complexType name="BeckhoffPLCType"> + <xs:complexContent> + <xs:extension base="PLCBaseType"> + <xs:attribute name="system" type="BeckhoffSystemType" use="required"> + <xs:annotation> + <xs:documentation>System infrastructure used to develop and/or + configure the controller software. + </xs:documentation> + <xs:appinfo> + <doc> + System infrastructure used to develop and/or configure the + Controller + software. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="model" use="required"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="BC9020" /> + <xs:enumeration value="CX9020" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="protocol" type="BlockProtocolType" use="required"> + <xs:annotation> + <xs:documentation>Data access mode is defined at PLC level for all + the classes + </xs:documentation> + <xs:appinfo> + <doc> + BLOCK_MODE: One data-segment per class/block + ([class-name]_[block-name]), + <br>containing array of + corresponding Block, one element per + device + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> + <xs:annotation> + <xs:documentation>Start address of the SILECS configuration + (corresponds to the common SilecsHeader block address). Attention: + 16bit address value is expected independently from the HW model (16 + or 32 bit). + </xs:documentation> + <xs:appinfo> + <doc> + Start address of the SILECS configuration (corresponds to the + common + SilecsHeader block address). + <br>Attention: 16bit + address value is expected independently from the HW model + (16 or 32 + bit) + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> - <!-- No support for this type in CERN codegen so far <xs:complexType name="BeckhoffRIOType"> <xs:attribute name="system" type="BeckhoffSystemType" use="required"> <xs:annotation> <xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation> <xs:appinfo> <doc> System infrastructure used to develop and/or configure the Controller software. </doc> </xs:appinfo> </xs:annotation> </xs:attribute> <xs:attribute name="model" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="BK9000"/> <xs:enumeration value="BK9050"/> <xs:enumeration value="BK9100"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="io-base-address" type="xs:unsignedInt" use="required"> <xs:annotation> <xs:documentation>Start address of the Remote IO modules (can be 0 if not required). Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).</xs:documentation> <xs:appinfo> <doc> Start - address of the Remote IO modules (can be 0 if not required). <br>Attention: 16bit address value is expected independently from the HW model (16 or 32 bit). </doc> </xs:appinfo> </xs:annotation> </xs:attribute> </xs:complexType> --> + <!-- No support for this type in CERN codegen so far <xs:complexType name="BeckhoffRIOType"> <xs:attribute name="system" type="BeckhoffSystemType" use="required"> <xs:annotation> <xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation> <xs:appinfo> <doc> System infrastructure used to develop and/or configure the Controller software. </doc> </xs:appinfo> </xs:annotation> </xs:attribute> <xs:attribute name="model" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="BK9000"/> <xs:enumeration value="BK9050"/> <xs:enumeration value="BK9100"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="io-base-address" type="xs:unsignedInt" use="required"> <xs:annotation> <xs:documentation>Start address of the Remote IO modules (can be 0 if not required). Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).</xs:documentation> <xs:appinfo> <doc> + Start address of the Remote IO modules (can be 0 if not required). <br>Attention: 16bit address value is expected independently from the HW model (16 or 32 bit). </doc> </xs:appinfo> </xs:annotation> </xs:attribute> </xs:complexType> --> - <xs:complexType name="RabbituCType"> - <xs:complexContent> - <xs:extension base="PLCBaseType"> - <xs:attribute name="system" type="RabbitSystemType" use="required"> - <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> - <xs:appinfo> - <doc> - System infrastructure used to develop and/or configure the - Controller - software. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="model" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="Rabbit_RCM_4010" /> - <xs:enumeration value="Rabbit_RCM_2000" /> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="protocol" type="BothProtocolType" use="required"> - <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> - <xs:appinfo> - <doc> - DEVICE_MODE: One C struct field per class/device - ([class-name]_[device-label|id]), <br>containing the - corresponding ordered list of Blocks - <br>BLOCK_MODE: One C - struct field per class/block ([class-name]_[block-name]), - <br>containing array of corresponding Block, one element per - device - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> - <xs:annotation> - <xs:documentation>Start address of the entire SILECS configuration - interpreted as 16bit address. - </xs:documentation> - <xs:appinfo> - <doc> - Start address of the entire SILECS configuration interpreted - as 16bit - address. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> + <xs:complexType name="RabbituCType"> + <xs:complexContent> + <xs:extension base="PLCBaseType"> + <xs:attribute name="system" type="RabbitSystemType" use="required"> + <xs:annotation> + <xs:documentation>System infrastructure used to develop and/or + configure the controller software. + </xs:documentation> + <xs:appinfo> + <doc> + System infrastructure used to develop and/or configure the + Controller + software. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="model" use="required"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="Rabbit_RCM_4010" /> + <xs:enumeration value="Rabbit_RCM_2000" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="protocol" type="BothProtocolType" use="required"> + <xs:annotation> + <xs:documentation>Data access mode is defined at PLC level for all + the classes + </xs:documentation> + <xs:appinfo> + <doc> + DEVICE_MODE: One C struct field per class/device + ([class-name]_[device-label|id]), <br>containing the + corresponding ordered list of Blocks + <br>BLOCK_MODE: One C + struct field per class/block ([class-name]_[block-name]), + <br>containing array of corresponding Block, one element per + device + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="base-address" type="xs:unsignedInt" use="required"> + <xs:annotation> + <xs:documentation>Start address of the entire SILECS configuration + interpreted as 16bit address. + </xs:documentation> + <xs:appinfo> + <doc> + Start address of the entire SILECS configuration interpreted + as 16bit + address. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> - <xs:complexType name="VirtualControllerType"> - <xs:complexContent> - <xs:extension base="PLCBaseType"> - <xs:attribute name="system" type="PCSystemType" use="required"> - <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> - <xs:appinfo> - <doc> - System infrastructure used to develop and/or configure the - Controller - software. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="model" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="SIMATIC_S7-VIRTUAL" /> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="protocol" type="BothProtocolType" use="required"> - <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> - <xs:appinfo> - <doc> - DEVICE_MODE: One C struct field per class/device - ([class-name]_[device-label|id]), <br>containing the - corresponding ordered list of Blocks - <br>BLOCK_MODE: One C - struct field per class/block ([class-name]_[block-name]), - <br>containing array of corresponding Block, one element per - device - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required"> - <xs:annotation> - <xs:documentation>Number of the diagnostic DB that is the first one - of the global configuration (corresponds to the common SilecsHeader - data-block). - </xs:documentation> - <xs:appinfo> - <doc> - Number of the diagnostic DB that is the first one of the - global - configuration ( >=1) - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> + <xs:complexType name="VirtualControllerType"> + <xs:complexContent> + <xs:extension base="PLCBaseType"> + <xs:attribute name="system" type="PCSystemType" use="required"> + <xs:annotation> + <xs:documentation>System infrastructure used to develop and/or + configure the controller software. + </xs:documentation> + <xs:appinfo> + <doc> + System infrastructure used to develop and/or configure the + Controller + software. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="model" use="required"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="SIMATIC_S7-VIRTUAL" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="protocol" type="BothProtocolType" use="required"> + <xs:annotation> + <xs:documentation>Data access mode is defined at PLC level for all + the classes + </xs:documentation> + <xs:appinfo> + <doc> + DEVICE_MODE: One C struct field per class/device + ([class-name]_[device-label|id]), <br>containing the + corresponding ordered list of Blocks + <br>BLOCK_MODE: One C + struct field per class/block ([class-name]_[block-name]), + <br>containing array of corresponding Block, one element per + device + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required"> + <xs:annotation> + <xs:documentation>Number of the diagnostic DB that is the first one + of the global configuration (corresponds to the common SilecsHeader + data-block). + </xs:documentation> + <xs:appinfo> + <doc> + Number of the diagnostic DB that is the first one of the + global + configuration ( >=1) + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> - <xs:complexType name="NIControllerType"> - <xs:complexContent> - <xs:extension base="PLCBaseType"> - <xs:attribute name="model" use="required"> - <xs:simpleType> - <xs:restriction base="xs:string"> - <xs:enumeration value="Compact_RIO" /> - <xs:enumeration value="PXI_RT" /> - <xs:enumeration value="PXI_Windows" /> - <xs:enumeration value="PC_Windows" /> - <xs:enumeration value="Other_Support_CNV" /> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - <xs:attribute name="system" type="NISystemType" use="required"> - <xs:annotation> - <xs:documentation>System infrastructure used to develop and/or - configure the controller software. - </xs:documentation> - <xs:appinfo> - <doc> - System infrastructure used to develop and/or configure the - Controller - software. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - <xs:attribute name="protocol" type="DeviceProtocolType" use="required"> - <xs:annotation> - <xs:documentation>Data access mode is defined at PLC level for all - the classes - </xs:documentation> - <xs:appinfo> - <doc> - DEVICE_MODE: One shared variable per class/device - (//class-name//controllerName//device-label), <br>containing - the corresponding ordered list of Blocks. - </doc> - </xs:appinfo> - </xs:annotation> - </xs:attribute> - </xs:extension> - </xs:complexContent> - </xs:complexType> + <xs:complexType name="NIControllerType"> + <xs:complexContent> + <xs:extension base="PLCBaseType"> + <xs:attribute name="model" use="required"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="Compact_RIO" /> + <xs:enumeration value="PXI_RT" /> + <xs:enumeration value="PXI_Windows" /> + <xs:enumeration value="PC_Windows" /> + <xs:enumeration value="Other_Support_CNV" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="system" type="NISystemType" use="required"> + <xs:annotation> + <xs:documentation>System infrastructure used to develop and/or + configure the controller software. + </xs:documentation> + <xs:appinfo> + <doc> + System infrastructure used to develop and/or configure the + Controller + software. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + <xs:attribute name="protocol" type="DeviceProtocolType" use="required"> + <xs:annotation> + <xs:documentation>Data access mode is defined at PLC level for all + the classes + </xs:documentation> + <xs:appinfo> + <doc> + DEVICE_MODE: One shared variable per class/device + (//class-name//controllerName//device-label), <br>containing + the corresponding ordered list of Blocks. + </doc> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:extension> + </xs:complexContent> + </xs:complexType> </xs:schema> -- GitLab