Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • silecs/opensilecs
  • k.fugiel/opensilecs
  • s.kupiecki/opensilecs
3 results
Show changes
Showing
with 754 additions and 505 deletions
# silecs-codegen
This component of the opensilecs PLC-framework generates FESA and stand-alone C++ code from an existing silecs-project in order to ease the usage of the package silecs-communication-cpp
\ No newline at end of file
This component of the opensilecs PLC-framework generates FESA and stand-alone C++ code from an existing silecs-project in order to ease the usage of the package silecs-communication-cpp
## Tests
In [test](src/xml/test/) directory there are files with {test_name} which contain unit tests written using `unittest` framework. Tests conserning the migration tools are in their own corresponding folders inside [migration](src/xml/migration/).
All tests can be run together using following command from inside [src/xml](src/xml/):
```
python3 -m unittest
```
#!/bin/sh
set -e
RELEASE_DIR_BASE=$1
SILECS_VERSION=$2
SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT") # path where this script is located in
RELEASE_DIR=${RELEASE_DIR_BASE}/${SILECS_VERSION}/silecs-codegen
if [ -d ${RELEASE_DIR} ]; then
echo "Error: ${RELEASE_DIR} already exists ...skipping"
exit 1
fi
cd ${SCRIPTPATH}/src/xml
python3 runTests.py
mkdir -p ${RELEASE_DIR}
cp -r ${SCRIPTPATH}/src/xml ${RELEASE_DIR}
# Make all files write-protected to prevent overwriting an old version by accident
chmod a-w -R ${RELEASE_DIR}
\ No newline at end of file
......@@ -9,6 +9,7 @@
# be specialized on call to append the string to be stored in the file.
#
import string
import time
......@@ -54,17 +55,17 @@ def toWordArray(strg):
#=========================================================================
# C Source template (.c file)
#=========================================================================
header = """
header = string.Template("""
/* +-------------------------------------------------------------------
* | Copyright CERN 2015
* | SILECS - BE/CO-SRC
* | April 2015
* +-------------------------------------------------------------------
*
* Release : %s
* Release : ${silecsRelease}
*
* The following code has been automatically generated by SILECS.
* Code regeneration will overwrite it.
*
* N.B: This file relies on the existence of explicit C data type such
* as int8_t, uint8_t, int16_t, etc....
......@@ -73,7 +74,7 @@ header = """
* web page before including this header file.
*/
#define MODBUS_START_ADDRESS %s
#define MODBUS_START_ADDRESS ${baseAddress}
/*---------------------------------------------------------------------
* DT
......@@ -94,7 +95,7 @@ typedef struct
} dt;
#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
#define _tobcd(a) (((unsigned char)((a)/10)<<4)+((a)%%10))
#define _tobcd(a) (((unsigned char)((a)/10)<<4)+((a)%10))
void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date)
{
......@@ -105,80 +106,72 @@ void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_
date->dd = _tobcd(dd);
date->mm = _tobcd(mm);
date->yy2 = _tobcd((int8_t)(yy/100));
date->yy1 = _tobcd((int8_t)(yy%%100));
date->yy1 = _tobcd((int8_t)(yy%100));
}
"""
""")
#=========================================================================
# DATA TYPE DEFINITION
#=========================================================================
firstBlockUDT = """
firstBlockUDT = string.Template("""
/*---------------------------------------------------------------------
* %s / v%s
* ${className} / v${classVersion}
* BLOCK Type definition
*---------------------------------------------------------------------
*/
"""
""")
blockUDT = """
blockUDT = string.Template("""
typedef struct
{
%s
} _%s_%s;
"""
$regList
} _${className}_${blockName};
""")
regScalar = """ %s %s;
"""
regScalar = string.Template(""" ${regFormat} ${regName};
""")
regArray = """ %s %s[%s];
"""
regArray = string.Template(""" ${regFormat} ${regName}[${strLen}];
""")
regArray2d = """ %s %s[%s][%s];
"""
regArray2d = string.Template(""" ${regFormat} ${regName}[${regDim}][${strLen}];
""")
stringArray = """ %s %s[%s][%s][%s];
"""
stringArray = string.Template(""" ${regFormat} ${regName}[${regDim}][${regDim2}][${strLen}];
""")
#=========================================================================
# INSTANTIATION
#=========================================================================
allocationComment = """
allocationComment = string.Template("""
/*---------------------------------------------------------------------
* MEMORY ALLOCATION
* PROTOCOL: %s
* PROTOCOL: ${plcProtocol}
*---------------------------------------------------------------------
*/
"""
""")
#======= DEVICE MODE =================
deviceModeBlockInstantiation = string.Template(""" _${className}_${blockName} ${blockName};
""")
deviceModeBlockInstantiation = """ _%s_%s %s;
"""
#deviceModeClass_deviceNumber = """
# struct {
# _%s_%s %s;
# } %s_device[%s];
#"""
deviceModeClass_deviceNumber = """
deviceModeClass_deviceNumber = string.Template("""
struct {
%s
} %s_device[NB_%s_DEVICE];
"""
deviceModeClass_deviceList = """
${blockList}
} ${className}_device[NB_${className}_DEVICE];
""")
deviceModeClass_deviceList = string.Template("""
struct {
%s
} %s;
"""
${blockList}
} ${deviceList};
""")
deviceMode_dataInstantiation = """
deviceMode_dataInstantiation = string.Template("""
typedef struct {
%s
${classList}
} _SILECS_DATA_SEGMENT;
#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
......@@ -188,21 +181,20 @@ union silecsData {
uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
} silecsData;
"""
""")
#======= BLOCK MODE =================
blockModeDeviceInstantiation_deviceList = string.Template(""" _${className}_${blockName} ${deviceName};
""")
blockModeDeviceInstantiation_deviceList = """ _%s_%s %s;
"""
blockModeBlockInstantiation = """
blockModeBlockInstantiation = string.Template("""
struct {
%s } %s_%s;
"""
${deviceList} } ${className}_${blockName};
""")
blockMode_dataInstantiation = """
blockMode_dataInstantiation = string.Template("""
typedef struct {
%s
${classList}
} _SILECS_DATA_SEGMENT;
#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
......@@ -212,7 +204,7 @@ union modbus_data {
uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
} silecsData;
"""
""")
#=========================================================================
# init
......@@ -223,44 +215,43 @@ globalAllocation = """
uint16_t modbus_data = & data;
"""
initFunctionDeviceMode = """
initFunctionDeviceMode = string.Template("""
/* Initialization function */
int SILECS_init()
{
/* Silecs version initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "${version}");
/* Silecs checksum initialization */
silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = %s;
silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = ${checksum};
/* Silecs user initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "${user}");
/* Silecs date initialization */
SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
SILECS_set_dt(${dt6},${dt5},${dt4},${dt3},${dt2},${dt1},${dt0},&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
}
"""
""")
#initFunctionBlockMode = """
initFunctionBlockMode = """
initFunctionBlockMode = string.Template("""
/* Initialization function */
int SILECS_init()
{
/* Silecs version initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "${version}");
/* Silecs checksum initialization */
silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = %s;
silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = ${checksum};
/* Silecs user initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "${user}");
/* Silecs date initialization */
SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
SILECS_set_dt(${dt6},${dt5},${dt4},${dt3},${dt2},${dt1},${dt0},&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
}
"""
""")
#=========================================================================
# Example generation
......@@ -270,19 +261,19 @@ instantiationExample = """/*
* Automatically generated Addressing example
*"""
deviceModeDeviceListExample = """
* This example shows how to address the register %s of block %s
* of device %s of the class %s
deviceModeDeviceListExample = string.Template("""
* This example shows how to address the register ${registerName} of block ${blockName}
* of device ${deviceLabel} of the class ${className}
*
* silecsData.%s_%s.%s.%s = ....;
*/"""
* silecsData.${className}_${deviceLabel}.${blockName}.${registerName} = ....;
*/""")
blockModeDeviceListExample = """
* This example shows how to address the register %s of block %s
* of device %s of the class %s
blockModeDeviceListExample = string.Template("""
* This example shows how to address the register ${registerName} of block ${blockName}
* of device ${deviceLabel} of the class ${className}
*
* silecsData.%s_%s.%s.%s = ....;
*/"""
* silecsData.${className}_${blockName}.${deviceLabel}.${registerName} = ....;
*/""")
#=========================================================================
# C code generation Sub-function
......@@ -290,33 +281,33 @@ blockModeDeviceListExample = """
# HEADER file ------------------------------------------------------------
def cHeader(silecsRelease, baseAddress):
return header %(silecsRelease, baseAddress)
return header.substitute(silecsRelease=silecsRelease, baseAddress=baseAddress)
# REGISTER definition ----------------------------------------------------
def cRegister(regName, regFormat, regDim, regDim2=1, strLen=1):
if strLen > 1: # if it's a string
if regDim2 > 1: # add another pair of brackets to hold the string length in case second dimension of array is set
return stringArray %(whichDIGIFormat[regFormat], regName, regDim, regDim2, strLen)
return stringArray.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, regDim=regDim, regDim2=regDim2, strLen=strLen)
elif regDim > 1: # reuse the array2D syntax
return regArray2d %(whichDIGIFormat[regFormat], regName, regDim, strLen)
return regArray2d.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, regDim=regDim, strLen=strLen)
else: # regular string register
return regArray %(whichDIGIFormat[regFormat], regName, strLen)
return regArray.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, strLen=strLen)
else:
if regDim == 1 and regDim2 == 1: # scalar
return regScalar %(whichDIGIFormat[regFormat], regName)
return regScalar.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName)
elif regDim > 1 and regDim2 == 1: # array
return regArray %(whichDIGIFormat[regFormat], regName, regDim)
return regArray.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, strLen=regDim)
else: # dim1>=1 and for whatever dim2, use double array syntax
return regArray2d %(whichDIGIFormat[regFormat], regName, regDim, regDim2)
return regArray2d.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, regDim=regDim, strLen=regDim2)
def cFirstBlockUDT(className, classVersion):
return firstBlockUDT %(className, classVersion)
return firstBlockUDT.substitute(className=className, classVersion=classVersion)
# BLOCK type definition (UDT) --------------------------------------------
def cBlockUDT(className, blockName, regList):
return blockUDT %(regList, className, blockName)
return blockUDT.substitute(regList=regList, className=className, blockName=blockName)
#============= DEVICE instantiation =============
......@@ -324,46 +315,46 @@ def cBlockUDT(className, blockName, regList):
# GLOBAL instantiation ----------------------------------------------
def cAllocationComment(plcProtocol):
return allocationComment %(plcProtocol)
return allocationComment.substitute(plcProtocol=plcProtocol)
# DEVICE MODE instantiation ----------------------------------------------
def cDeviceModeBlockInstantiation(className, blockName):
return deviceModeBlockInstantiation %(className, blockName, blockName)
return deviceModeBlockInstantiation.substitute(className=className, blockName=blockName)
def cDeviceModeClass_deviceNumber(className, blockList):
return deviceModeClass_deviceNumber %(blockList, className, className)
return deviceModeClass_deviceNumber.substitute(blockList=blockList, className=className)
def cDeviceModeClass_deviceList(blockList, deviceList):
return deviceModeClass_deviceList %(blockList, deviceList)
return deviceModeClass_deviceList.substitute(blockList=blockList, deviceList=deviceList)
def cDeviceModeDataInstantiation(classList):
return deviceMode_dataInstantiation %(classList)
return deviceMode_dataInstantiation.substitute(classList=classList)
# BLOCK MODE instantiation ----------------------------------------------
def cBlockModeDeviceInstantiation_deviceList(className, blockName, deviceName):
return blockModeDeviceInstantiation_deviceList %(className, blockName, deviceName)
return blockModeDeviceInstantiation_deviceList.substitute(className=className, blockName=blockName, deviceName=deviceName)
def cBlockModeBlockInstantiation(deviceList, className, blockName):
return blockModeBlockInstantiation %(deviceList, className, blockName)
return blockModeBlockInstantiation.substitute(deviceList=deviceList, className=className, blockName=blockName)
def cBlockModeDataInstantiation(classList):
return blockMode_dataInstantiation %(classList)
return blockMode_dataInstantiation.substitute(classList=classList)
# Init Function ----------------------------------------------
def cInitDeviceMode(ieVersion,ieChecks,ieUser):
dt = time.localtime(time.time())
return initFunctionDeviceMode %("SILECS_"+ieVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0])
return initFunctionDeviceMode.substitute(version="SILECS_"+ieVersion, checksum=ieChecks, user=ieUser, dt6=dt[6], dt5=dt[5], dt4=dt[4], dt3=dt[3], dt2=dt[2], dt1=dt[1], dt0=dt[0])
def cInitBlockMode(ieVersion,ieChecks,ieUser):
dt = time.localtime(time.time())
return initFunctionBlockMode %("SILECS_"+ieVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0])
return initFunctionBlockMode.substitute(version="SILECS_"+ieVersion, checksum=ieChecks, user=ieUser, dt6=dt[6], dt5=dt[5], dt4=dt[4], dt3=dt[3], dt2=dt[2], dt1=dt[1], dt0=dt[0])
# Example function ----------------------------------------------
def cExample(plcProtocol,className, blockName, registerName, deviceLabel =''):
if plcProtocol == 'DEVICE_MODE':
return instantiationExample + deviceModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, deviceLabel, blockName, registerName)
return instantiationExample + deviceModeDeviceListExample.substitute(registerName=registerName, blockName=blockName, deviceLabel=deviceLabel, className=className)
else:
return instantiationExample + blockModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, blockName, deviceLabel, registerName)
return instantiationExample + blockModeDeviceListExample.substitute(registerName=registerName, blockName=blockName, deviceLabel=deviceLabel, className=className)
......@@ -33,9 +33,9 @@ from iecommon import *
# Generates two Makefile.specific, one for the class design
# and another for the deploy unit
#-------------------------------------------------------------------------
def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
def genMakefileClass(projectPath, logTopics={'errorlog': True} ):
# Generate makefile for class design
source = fesaTemplates.genMakeDesign(centralMakefilePath)
source = fesaTemplates.genMakeDesign()
makefile = projectPath + "/" + "Makefile.specific"
if os.path.isfile(makefile): #dont overwrite
return
......@@ -44,9 +44,9 @@ def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': Tr
fdesc.write(source)
fdesc.close()
def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
def genMakefileDU(projectPath, logTopics={'errorlog': True}):
# Generate makefile for class design
source = fesaTemplates.genMakeDeploy(silecsBasePath,snap7BasePath)
source = fesaTemplates.genMakeDeploy()
# Write file and save
makefile = projectPath + "/" + "Makefile.specific"
if os.path.isfile(makefile): #dont overwrite
......
......@@ -87,8 +87,29 @@ class FESADesignGenerator3_0_0(object):
fillAttributes(scalarNode, {'type': register.getFesaType()})
return scalarNode
def getOrCreateType(self,fieldNode,register):
if register.valueType == "scalar":
def getOrCreateCustomScalarType(self, fieldNode, register):
scalarNode = getOrCreateChildElement(fieldNode,'custom-type-scalar')
fillAttributes(scalarNode, {'data-type-name-ref': register.custom_type_name})
return scalarNode
def getOrCreateCustomArrayType(self,fieldNode,register):
arrayNode = getOrCreateChildElement(fieldNode,'custom-type-array')
fillAttributes(arrayNode, {'data-type-name-ref': register.custom_type_name})
dimNode = getOrCreateChildElement(arrayNode,'dim')
dimNode.setContent(str(register.dim1))
return arrayNode
def getOrCreateCustom2DArrayType(self,fieldNode,register):
array2DNode = getOrCreateChildElement(fieldNode,'custom-type-array2D')
fillAttributes(array2DNode, {'data-type-name-ref': register.custom_type_name})
dim1Node = getOrCreateChildElement(array2DNode,'dim1')
dim2Node = getOrCreateChildElement(array2DNode,'dim2')
dim1Node.setContent(str(register.dim1))
dim2Node.setContent(str(register.dim2))
return array2DNode
def getOrCreateType(self,fieldNode, register):
if register.valueType == "scalar":
return self.getOrCreateScalarType(fieldNode,register)
elif register.valueType == "array":
return self.getOrCreateArrayType(fieldNode,register)
......@@ -100,6 +121,12 @@ class FESADesignGenerator3_0_0(object):
return self.getOrCreateStringArrayType(fieldNode,register)
elif register.valueType == "stringArray2D":
iecommon.logError('ERROR: In register '+register.name+' - 2D array of strings not supported in FESA.', True, {'errorlog': True})
elif register.valueType == "custom-type-scalar":
return self.getOrCreateCustomScalarType(fieldNode, register)
elif register.valueType == "custom-type-array":
return self.getOrCreateCustomArrayType(fieldNode, register)
elif register.valueType == "custom-type-array2D":
return self.getOrCreateCustom2DArrayType(fieldNode, register)
else:
iecommon.logError('ERROR: Unknown data-type:' + register.valueType, True, {'errorlog': True})
return None
......
......@@ -51,11 +51,11 @@ def genHSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
for block in designClass.getDesignFesaBlocks():
if block.isAcquisition():
source += fesaTemplates.genHBlock('RO', block.name,block.getFesaName() )
source += fesaTemplates.genHReadBlock(className, block.name)
elif block.isCommand() or block.isConfiguration():
source += fesaTemplates.genHBlock('WO', block.name,block.getFesaName())
source += fesaTemplates.genHWriteBlock(className, block.name, block.getFesaName())
else: # Setting
source += fesaTemplates.genHBlock('RW', block.name,block.getFesaName())
source += fesaTemplates.genHReadWriteBlock(className, block.name, block.getFesaName())
source += fesaTemplates.genHBottom(className)
......@@ -106,7 +106,7 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
for block in blockList:
if block.isSetting() or block.isAcquisition(): #configuration-fields in fesa are not writable, so no setter to generate for them !
finalSource += fesaTemplates.genCCommonGet(block.name,className)
finalSource += fesaTemplates.genCCommonGet(block.name, className)
finalSource += '\n'
finalSource += fesaTemplates.cRecv
for register in block.getDesignRegisters():
......@@ -122,10 +122,43 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCGetArrayReg(register)
elif register.valueType == 'array2D':
finalSource += fesaTemplates.genCGetArray2DReg(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCGetCustomScalarReg(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCGetCustomArrayReg(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCGetCustomArray2DReg(register)
finalSource += '\n }\n'
if block.isSetting():
finalSource += fesaTemplates.genCDatatypeGet(block.name, block.getFesaName(), className)
finalSource += '\n'
finalSource += fesaTemplates.cRecv
for register in block.getDesignRegisters():
if register.valueType == 'string':
finalSource += fesaTemplates.genCGetStringRegData(register)
elif register.valueType == 'stringArray':
finalSource += fesaTemplates.genCGetStringArrayRegData(register)
elif register.valueType == 'stringArray2D':
iecommon.logError('ERROR: In register '+register.name+' - 2D array of strings not supported in FESA.', True, {'errorlog': True})
elif register.valueType == 'scalar':
finalSource += fesaTemplates.genCGetScalarRegData(register)
elif register.valueType == 'array':
finalSource += fesaTemplates.genCGetArrayRegData(register)
elif register.valueType == 'array2D':
finalSource += fesaTemplates.genCGetArray2DRegData(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCGetCustomScalarRegData(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCGetCustomArrayRegData(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCGetCustomArray2DRegData(register)
finalSource += '\n }\n'
if block.isWritable():
finalSource += fesaTemplates.genCCommonSet(block.name,className)
finalSource += fesaTemplates.genCCommonSet(block.name, className)
for register in block.getDesignRegisters():
if register.valueType == 'string':
finalSource += fesaTemplates.genCSetStringReg(register)
......@@ -139,6 +172,12 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCSetArrayReg(register)
elif register.valueType == 'array2D':
finalSource += fesaTemplates.genCSetArray2DReg(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCSetScalarReg(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCSetCustomArrayReg(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCSetCustomArray2DReg(register)
finalSource += fesaTemplates.cSend
finalSource += ' }\n'
finalSource += fesaTemplates.genCDatatypeSet(block.name,block.getFesaName(), className)
......@@ -156,6 +195,12 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCSetArrayRegData(register)
elif register.valueType == 'scalar':
finalSource += fesaTemplates.genCSetScalarRegData(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCSetScalarRegData(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCSetCustomArrayRegData(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCSetCustomArray2DRegData(register)
finalSource += fesaTemplates.cSend
finalSource += '\n }\n' # closing bracket for block
......
......@@ -16,11 +16,11 @@
import fesa.fesa_3_0_0.generateBuildEnvironment
def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileClass(projectPath, centralMakefilePath, logTopics )
def genMakefileClass(projectPath, logTopics={'errorlog': True} ):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileClass(projectPath, logTopics )
def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics )
def genMakefileDU(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileDU(projectPath, logTopics )
def genCProjectFile(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_0_0.generateBuildEnvironment.genCProjectFile(projectPath, logTopics )
......@@ -16,11 +16,11 @@
import fesa.fesa_3_1_0.generateBuildEnvironment
def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
return fesa.fesa_3_1_0.generateBuildEnvironment.genMakefileClass(projectPath, centralMakefilePath, logTopics )
def genMakefileClass(projectPath, logTopics={'errorlog': True} ):
return fesa.fesa_3_1_0.generateBuildEnvironment.genMakefileClass(projectPath, logTopics )
def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
return fesa.fesa_3_1_0.generateBuildEnvironment.genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics )
def genMakefileDU(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_1_0.generateBuildEnvironment.genMakefileDU(projectPath, logTopics )
def genCProjectFile(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_1_0.generateBuildEnvironment.genCProjectFile(projectPath, logTopics )
......@@ -96,3 +96,42 @@ class FESADesignGenerator7_3_0(fesa.fesa_3_1_0.generateFesaDesign.FESADesignGene
else:
globalConfigurationNode = globalDataNode.xpathEval("configuration")[0]
self.getOrCreatePLCClassVersionField(globalConfigurationNode,designClass.version)
# Fill custom-types with enums.
enums = designClass.getEnums()
customTypesNode = doc.xpathEval('/equipment-model/custom-types')[0]
for enum in enums:
enumElement = getOrCreateNamedChildElement(customTypesNode, "enum", enum.name)
existing_items = enumElement.xpathEval("item")
to_add = []
to_edit = []
# Loop through all new enums and check which should be added and which edited.
for item in enum.items:
if item.symbol in [item.prop("symbol") for item in existing_items]:
to_edit.append(item)
else:
to_add.append(item)
# Loop though all existing enums and remove any which are not in new enums.
to_add_edit = to_add + to_edit
for existing in existing_items:
if existing.prop("symbol") not in [item.symbol for item in to_add_edit]:
existing.unlinkNode()
existing.freeNode()
# Edit existing items.
for item in to_edit:
for existing in existing_items:
if existing.prop("symbol") != item.symbol:
continue
existing.setProp("access", item.access)
existing.setProp("value", item.value)
# Add missing items.
for item in to_add:
itemElement = libxml2.newNode("item")
enumElement.addChild(itemElement)
itemElement.setProp("access", item.access)
itemElement.setProp("value", item.value)
itemElement.setProp("symbol", item.symbol)
......@@ -43,13 +43,13 @@ def genClassHeader(workspacePath, deploy, design, funcGetSilecsDesignFilePath, f
classDeclarations += genduwrappertemplate.getBlockClass(block,registerInitializerList,registerGetterSetter,registersDimentionsDeclaration,registersDeclaration)
blockGetters = ""
sendRecvBlocks = genduwrappertemplate.getDeviceSendRecvBlocks(designClass.getBlockNodes())
sendRecvBlocks = genduwrappertemplate.getDeviceSendRecvBlocks(designClass.getBlockNodes(), designClass.customTypesXmlNode)
for block in designClass.getDesignBlocks():
blockGetters += genduwrappertemplate.getDeviceBlockGetterSetter(block)
classDeclarations += genduwrappertemplate.getDeviceClass(blockGetters,sendRecvBlocks)
sendRecvBlocks = genduwrappertemplate.getControllerSendRecvBlocks(designClass.getBlockNodes())
sendRecvBlocks = genduwrappertemplate.getControllerSendRecvBlocks(designClass.getBlockNodes(), designClass.customTypesXmlNode)
classDeclarations = genduwrappertemplate.getDesignClass(design.name, design.version)
designWrapper = genduwrappertemplate.designFileTemplate.substitute({'designNameCapitalized' : iecommon.capitalizeString(design.name),'designNameUpper' : design.name.upper(),'classDeclarations' : classDeclarations})
......
......@@ -337,10 +337,10 @@ controllerSendTemplate = string.Template("""\
""")
def getControllerSendRecvBlocks(blockList):
def getControllerSendRecvBlocks(blockList, customTypesXmlNode):
text = ""
for blockNode in blockList:
block = DesignBlock(blockNode)
block = DesignBlock(blockNode, customTypesXmlNode)
map = {'blockName' : block.name,
'blockNameCapitalized' : block.getNameCapitalized()}
if block.isReadable():
......@@ -405,39 +405,39 @@ ${blockInitialization}\
matrixRegisterAssignementGetter = string.Template("""\
// Copy register ${regName}
${cType} *__${regName} = new ${cType}[block.${regName}Dim1 * block.${regName}Dim2];
getSilecsDevice()->getRegister("${regName}")->getVal${silecsTypeCapitalized}Array2D(__${regName}, block.${regName}Dim1, block.${regName}Dim2);
getSilecsDevice()->getRegister("${regName}")->getValArray2D<${cType}>(__${regName}, block.${regName}Dim1, block.${regName}Dim2);
block.set${regNameCapitalized}(__${regName});
delete[] __${regName};
""")
arrayRegisterAssignementGetter = string.Template("""\
// Copy register ${regName}
${cType} *__${regName} = new ${cType}[block.${regName}Dim1];
getSilecsDevice()->getRegister("${regName}")->getVal${silecsTypeCapitalized}Array(__${regName}, block.${regName}Dim1);
getSilecsDevice()->getRegister("${regName}")->getValArray<${cType}>(__${regName}, block.${regName}Dim1);
block.set${regNameCapitalized}(__${regName});
delete[] __${regName};
""")
scalarRegisterAssignementGetter = string.Template("""\
// Copy register ${regName}
block.set${regNameCapitalized}(getSilecsDevice()->getRegister("${regName}")->getVal${silecsTypeCapitalized}());
block.set${regNameCapitalized}(getSilecsDevice()->getRegister("${regName}")->getVal<${cType}>());
""")
matrixRegisterAssignementSetter = string.Template("""\
// Copy register ${regName}
${cType} *__${regName} = new ${cType}[block.${regName}Dim1 * block.${regName}Dim2];
block.get${regNameCapitalized}(__${regName});
getSilecsDevice()->getRegister("${regName}")->setVal${silecsTypeCapitalized}Array2D(__${regName}, block.${regName}Dim1, block.${regName}Dim2);
getSilecsDevice()->getRegister("${regName}")->setValArray2D<${cType}>(__${regName}, block.${regName}Dim1, block.${regName}Dim2);
delete[] __${regName};
""")
arrayRegisterAssignementSetter = string.Template("""\
// Copy register ${regName}
${cType} *__${regName} = new ${cType}[block.${regName}Dim1];
block.get${regNameCapitalized}(__${regName});
getSilecsDevice()->getRegister("${regName}")->setVal${silecsTypeCapitalized}Array(__${regName}, block.${regName}Dim1);
getSilecsDevice()->getRegister("${regName}")->setValArray<${cType}>(__${regName}, block.${regName}Dim1);
delete[] __${regName};
""")
scalarRegisterAssignementSetter = string.Template("""\
// Copy register ${regName}
getSilecsDevice()->getRegister("${regName}")->setVal${silecsTypeCapitalized}(block.get${regNameCapitalized}());
getSilecsDevice()->getRegister("${regName}")->setVal<${cType}>(block.get${regNameCapitalized}());
""")
def getDeviceBlockGetterSetter(block):
......@@ -447,7 +447,6 @@ def getDeviceBlockGetterSetter(block):
for register in block.getDesignRegisters():
map = {'regName' : register.name,
'regNameCapitalized' : register.getNameCapitalized(),
'silecsTypeCapitalized' : register.getSilecsTypeCapitalized(),
'cType' : register.getCType()}
if register.isArray2D():
blockInitialization += matrixRegisterAssignementGetter.substitute(map)
......@@ -465,7 +464,6 @@ def getDeviceBlockGetterSetter(block):
for register in block.getDesignRegisters():
map = {'regName' : register.name,
'regNameCapitalized' : register.getNameCapitalized(),
'silecsTypeCapitalized' : register.getSilecsTypeCapitalized(),
'cType' : register.getCType()}
if register.isArray2D():
blockInitialization += matrixRegisterAssignementSetter.substitute(map)
......@@ -502,10 +500,10 @@ deviceSendTemplate = string.Template("""\
""")
def getDeviceSendRecvBlocks(blockList):
def getDeviceSendRecvBlocks(blockList, customTypesXmlNode):
text = ""
for blockNode in blockList:
block = DesignBlock(blockNode)
block = DesignBlock(blockNode, customTypesXmlNode)
map = {'blockName' : block.name,
'blockNameCapitalized' : block.getNameCapitalized()}
if block.isReadable():
......
......@@ -36,6 +36,9 @@ from model.Deploy.Controller import *
import model.Deploy.Device
from model.Param.Param import *
# maximum number of boolean bits in the same register address
MAX_BITS_IN_ADDRESS = 8
#-------------------------------------------------------------------------
# Trimming: remove new-line, tabulation and spaces of the string
# Used to compute CRC32 on significant data only
......@@ -123,8 +126,15 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
iecommon.logDebug("-----------------------------------------",logTopics)
iecommon.logDebug("------ Analysing Class " + deployDesign.name + " ------",logTopics)
iecommon.logDebug("-----------------------------------------",logTopics)
designDOM = iefiles.loadSilecsDesignDOM(workspacePath, deployDesign, silecsVersion, funcGetSilecsDesignFilePath)
if iecommon.supportsDateTimeLong(controller):
datetime_format = xmltemplate.DATE_TIME_LONG
else:
datetime_format = xmltemplate.DATE_AND_TIME
iecommon.logDebug("Datetime format is:", datetime_format)
designDOM = iefiles.loadSilecsDesignDOM(workspacePath, deployDesign, silecsVersion, funcGetSilecsDesignFilePath, datetime_format)
designClass = DesignClass.getDesignClassFromRootNode(designDOM)
paramClass = ParamClass()
paramClass.initWithDesignClass(designClass)
......@@ -151,9 +161,37 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
blockSize = 0 # block size (sum of the register size)
blockMemSize = 0 # block size (sum of the regist)
controller.regCounter = 0 # used for NI register address generation
# additional data for managing booleans
isBooleanRegister = False
bitNumber = 0
nextRegister = None
# INNER LOOP TO ACCESS AT REGISTER LEVEL
for designRegister in designBlock.getDesignRegisters():
designRegisters = designBlock.getDesignRegisters()
for i, designRegister in enumerate(designRegisters):
if i + 1 != len(designRegisters):
nextRegister = designRegisters[i+1]
else:
nextRegister = None
iecommon.logDebug("------ Processing Register " + designRegister.name + " ------",logTopics)
# Allow bool register only for Siemens controller
if designRegister.format == 'bool':
isBooleanRegister = True
if not designRegister.isScalar():
iecommon.logError("Invalid format in register: %s Bool format available only for scalars" %designRegister.name, False, logTopics)
sys.exit(2)
if controller.brand != 'SIEMENS':
iecommon.logError("Invalid format in register: %s. Bool format available only on SIEMENS controllers" %designRegister.name, False,logTopics)
sys.exit(2)
else:
isBooleanRegister = False
bitNumber = 0
# Set length attribute only for string registers
if designRegister.format == 'string': # TODO: Port this constraint to java
if controller.brand == 'DIGI':
......@@ -164,12 +202,25 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
sys.exit(2)
regAddress = controller.alignRegAddress(designBlock, designRegister, regAddress)
controller.regCounter += 1 # used for NI register address generation
# Set register mem-size
paramRegister = ParamRegister()
paramRegister.initWithDesignRegister(designRegister,regAddress,controller.msize)
# Compute address for the next register
regAddress = controller.computeNextRegAddress(designBlock, designRegister, regAddress)
if isBooleanRegister:
paramRegister.initWithDesignRegister(designRegister,regAddress,controller.msize, bitNumber)
else:
paramRegister.initWithDesignRegister(designRegister,regAddress,controller.msize)
if isBooleanRegister and nextRegister and nextRegister.format == "bool":
bitNumber = (bitNumber + 1) % MAX_BITS_IN_ADDRESS
if bitNumber == 0:
# Compute address for the next register if max bits in address achieved
regAddress = controller.computeNextRegAddress(designBlock, designRegister, regAddress)
else:
# Compute address for the next register
regAddress = controller.computeNextRegAddress(designBlock, designRegister, regAddress)
paramBlock.xmlNode.addChild(paramRegister.xmlNode)
#paramRegister.xmlNode.shellPrintNode()
#iterativelly compute the block size (accumulator initialized outside the loop)
......@@ -190,6 +241,7 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
for device in devices:
instance = libxml2.newNode("Instance")
instance.setProp("label", device.silecsDeviceLabel)
instance.setProp("fesa-label", device.fesaDeviceName)
instance.setProp("address", str(int(controller.computeInstAddress(mappings[MEM_TYPE]))))
instance.setProp("DI-address", str(int(controller.computeInstAddress(mappings[DI_TYPE]))))
instance.setProp("DO-address", str(int(controller.computeInstAddress(mappings[DO_TYPE]))))
......
......@@ -18,6 +18,8 @@ import sys
import time
import zlib
import libxml2
import datetime
import string
import iecommon
import iefiles
......@@ -62,7 +64,8 @@ whichUnityFormat = {
'int' : 'INT',
'dint' : 'DINT',
'real' : 'REAL',
'dt' : 'DT'
'dt' : 'DT',
'dtl' : 'DTL'
}
whichTwincatFormat = {
......@@ -89,8 +92,8 @@ whichTwincatFormat = {
'string' : 'STRING'
}
schneiderRegArray = """ARRAY[0..%d] OF %s"""
schneiderRegArray2d = """ARRAY[0..%d, 0..%d] OF %s"""
schneiderRegArray = string.Template("""ARRAY[0..${value}] OF ${len}""")
schneiderRegArray2d = string.Template("""ARRAY[0..${value1}, 0..${value2}] OF ${len}""")
# Beckhoff templates (using newlines \r\n because TwinCAT compiler complains with line feed character)
beckhoffReg = """ %s_%04x_%s AT %%MW%s: %s;\r\n\r\n"""
......@@ -112,42 +115,35 @@ def xsyRegister(register):
if register.isString():
return strLen
elif register.isStringArray():
return schneiderRegArray %(register.dim1-1, strLen)
return schneiderRegArray.substitute(value=register.dim1-1, len=strLen)
else: #2D-Array
return schneiderRegArray2d %(register.dim1-1, register.dim2-1, strLen)
return schneiderRegArray2d.substitute(value1=register.dim1-1, value2=register.dim2-1, len=strLen)
else:
if register.isScalar():
return whichUnityFormat[register.format]
elif register.isArray():
return schneiderRegArray %(register.dim1-1, whichUnityFormat[register.format])
return schneiderRegArray.substitute(value=register.dim1-1, len=whichUnityFormat[register.format])
else: #2D-Array
return schneiderRegArray2d %(register.dim1-1, register.dim2-1, whichUnityFormat[register.format])
return schneiderRegArray2d.substitute(value1=register.dim1-1, value2=register.dim2-1, len=whichUnityFormat[register.format])
def decimalToBCD(value):
return ((value//10)*16)+(value%10)
# convert date to DATE_AND_TIME string format (Siemens SIMATIC PLC)
# convert date to DATE_TIME_LONG or DATE_AND_TIME string format (Siemens SIMATIC PLC)
def getDateTime(controller):
dt = time.localtime(time.time())
if controller.model == 'SIMATIC_S7-1200':
# convert date to BCD byte-array (SIMATIC S7-12xx CPU does not support DATE_AND_TIME type)
return "%s,%s,%s,%s,%s,%s" %(decimalToBCD(dt[0]-2000),
decimalToBCD(dt[1]),
decimalToBCD(dt[2]),
decimalToBCD(dt[3]),
decimalToBCD(dt[4]),
decimalToBCD(dt[5]))
else:
return "DT#%s-%s-%s-%s:%s:%s" %(dt[0],dt[1],dt[2],dt[3],dt[4],dt[5])
dt = datetime.datetime.now()
if iecommon.supportsDateTimeLong(controller):
return "DTL#%s-%s-%s-%s:%s:%s.%03d" %(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond // 1000)
else:
return "DT#%s-%s-%s-%s:%s:%s" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
#-------------------------------------------------------------------------
# SIEMENS PLC code generation
#-------------------------------------------------------------------------
def generateSiemensSources(param, sourceFolderPath ,logTopics):
stlString = ''
stlString = s7template.head.substitute()
symString = '' # for .sdf Symbol file
# Prepare the Simatic Symbols (<.sdf> file)
......@@ -187,7 +183,8 @@ def generateSiemensSources(param, sourceFolderPath ,logTopics):
for block in paramClass.getParamMemoryBlocks():
blockList += s7template.stlBlock(paramClass.name, block.name)
deviceLabel = deviceDOM.prop('label')
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, deviceLabel, blockList, (deviceIndex == 0),param.controller.protocol)
fesaLabel = deviceDOM.prop('fesa-label')
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, deviceLabel, blockList, (deviceIndex == 0), param.controller.protocol, fesaLabel)
symString += s7template.symDeviceDB(paramClass.name, paramClass.version, deviceLabel, DBnumber, (deviceIndex == 0))
DBnumber += 1
......@@ -197,9 +194,10 @@ def generateSiemensSources(param, sourceFolderPath ,logTopics):
deviceList = ''
for deviceDOM in deviceDOMList:
deviceLabel = deviceDOM.prop('label')
deviceList += s7template.stlDevice(deviceLabel, paramClass.name, block.name)
fesaLabel = deviceDOM.prop('fesa-label')
deviceList += s7template.stlDevice(deviceLabel, paramClass.name, block.name, fesaLabel)
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, block.name, deviceList, (blockIndex == 0),param.controller.protocol)
stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, block.name, deviceList, (blockIndex == 0),param.controller.protocol, "")
symString += s7template.symBlockDB(paramClass.name, paramClass.version, block.name, DBnumber, (blockIndex == 0))
DBnumber += 1
......@@ -525,6 +523,8 @@ def generateBeckhoffSources(param, sourceFolderPath, logTopics):
source += """* | C.E.R.N Geneva, Switzerland\r\n"""
source += """* | SILECS - BE/CO-FE\r\n"""
source += """* | April 2015\r\n"""
source += """* | This file is auto generated by the SILECS framework tools.\r\n"""
source += """* | Code regeneration will overwrite it.\r\n"""
source += """* +-------------------------------------------------------------------\r\n"""
source += """*\r\n"""
source += """* Release : SILECS_%s\r\n"""%(param.silecsVersion)
......@@ -543,7 +543,7 @@ def generateBeckhoffSources(param, sourceFolderPath, logTopics):
source += 'END_VAR'
# Write the source into the EXP source file
generateControllerFiles(sourceFolderPath,param.controller.hostName,".exp",source,logTopics);
generateControllerFiles(sourceFolderPath,param.controller.hostName,".exp",source,logTopics)
#-------------------------------------------------------------------------
# NI code generation
......@@ -556,7 +556,7 @@ def generateControllerFiles(sourceFolderPath,hostName,fileExtention,source,logTo
fileName = hostName + fileExtention
fullFilePath = os.path.normpath(sourceFolderPath + "/" + fileName )
iecommon.logInfo("Generate PLC sources: %s" %fullFilePath,logTopics);
iecommon.logInfo("Generate PLC sources: %s" %fullFilePath,logTopics)
fdesc = open(fullFilePath, "w")
fdesc.write(source)
fdesc.close()
......
......@@ -172,4 +172,9 @@ def getPatchSilecsVersion(silecsVersionString):
secondDot = silecsVersionString.find('.',firstDot)
return silecsVersionString[secondDot:]
def supportsDateTimeLong(controller):
if controller.brand != "SIEMENS":
return False
if controller.model in ['SIMATIC_S7-300', 'SIMATIC_S7-400']:
return False
return True
......@@ -26,9 +26,9 @@ designFormat = '.silecsdesign'
deployFormat = '.silecsdeploy'
paramFormat = '.silecsparam'
def loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath):
def loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath, datetime_format=xmltemplate.DATE_AND_TIME):
if silecsDesign.name == "SilecsHeader":
silecsHeader = xmltemplate.getSilecsHeader(silecsVersion)
silecsHeader = xmltemplate.getSilecsHeader(silecsVersion, datetime_format)
return libxml2.parseDoc(silecsHeader)
else:
designPath = funcGetSilecsDesignFilePath(workspacePath, silecsDesign.name)
......
......@@ -27,8 +27,8 @@ import FileUtils
import shutil
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
def migrateClass(self, context, projectDir ):
modified = designGenerateFesaPropValueItemMigrator(context)
......@@ -43,9 +43,7 @@ class Migration(MigrationBase):
return modified
def migrateFESAInstanceFile(self):
results = self.parser.parse_args()
silecsDocument = results.silecsDocument
projectDir = FileUtils.getProjectDir(silecsDocument)
projectDir = FileUtils.getProjectDir(self.silecsDocument)
testFolder = projectDir + "/src/test"
if not os.path.isdir(testFolder):
return
......@@ -66,12 +64,13 @@ def main_parse():
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew)
arguments.versionNew,
arguments.createBackup)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
migration.backupOldFESAMakeSpecific()
if __name__ == "__main__":
main_parse()
\ No newline at end of file
main_parse()
......@@ -26,8 +26,8 @@ import libxml2
import sys
class Migration(MigrationBase):
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew)
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
self._deployDomainMigrator = DeployDomainMigrator()
self._migrateDeployDeviceNumber = DeployDeviceNumberMigrator()
......@@ -45,10 +45,11 @@ def main_parse():
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew)
arguments.versionNew,
arguments.createBackup)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
if __name__ == "__main__":
......
......@@ -27,10 +27,10 @@ import FileUtils
import shutil
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
def migrateClass(self, context, projectDir ):
def migrateClass(self, context, projectDir):
modified = designValueTypeMigrator(context)
modified |= designBlockRegisterMigrator(context)
return modified
......@@ -40,10 +40,11 @@ def main_parse():
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew)
arguments.versionNew,
arguments.createBackup)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
migration.backupOldFESAMakeSpecific()
......
......@@ -27,8 +27,8 @@ import FileUtils
import shutil
class Migration(MigrationBase):
def __init__(self, arguments):
super(Migration, self).__init__()
def __init__(self, silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
super(Migration, self).__init__(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
def migrateClass(self, context, projectDir ):
modified = False
......@@ -53,20 +53,17 @@ class Migration(MigrationBase):
self.updateFESAMakeSpecific()
return modified
migration = Migration(sys.argv)
migration.migrate()
def main_parse():
arguments = ParseMigrationArgs.parse_arguments()
run_migrate(arguments.silecsDocument,
arguments.xmlSchema,
arguments.versionOld,
arguments.versionNew)
arguments.versionNew,
arguments.createBackup)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew)
def run_migrate(silecsDocument, xmlSchema, versionOld, versionNew, createBackup):
migration = Migration(silecsDocument, xmlSchema, versionOld, versionNew, createBackup)
migration.migrate()
if __name__ == "__main__":
main_parse()
\ No newline at end of file
main_parse()