author | Laurent Bessard |
Tue, 10 Sep 2013 23:10:58 +0200 | |
changeset 1313 | 85c167bfff93 |
parent 1312 | 250c3ae0787c |
child 1314 | 822d483197ad |
--- a/PLCControler.py Tue Sep 10 10:37:42 2013 +0200 +++ b/PLCControler.py Tue Sep 10 23:10:58 2013 +0200 @@ -30,7 +30,7 @@ import datetime from time import localtime -from plcopen import* +from plcopen import * from graphics.GraphicCommons import * from PLCGenerator import * @@ -1297,14 +1297,16 @@ return variables # Add a global var to configuration to configuration - def AddConfigurationGlobalVar(self, config_name, type, var_name, + def AddConfigurationGlobalVar(self, config_name, var_type, var_name, location="", description=""): if self.Project is not None: # Found the configuration corresponding to name configuration = self.Project.getconfiguration(config_name) if configuration is not None: # Set configuration global vars - configuration.addglobalVar(type, var_name, location, description) + configuration.addglobalVar( + self.GetVarTypeObject(var_type), + var_name, location, description) # Replace the configuration globalvars by those given def SetConfigurationGlobalVars(self, name, vars): @@ -1635,6 +1637,10 @@ result = project.getpou(typename) if result is not None: return result + for standardlibrary in [StdBlockLibrary, AddnlBlockLibrary]: + result = standardlibrary.getpou(typename) + if result is not None: + return result for confnodetype in self.ConfNodeTypes: result = confnodetype["types"].getpou(typename) if result is not None: @@ -2410,21 +2416,36 @@ connection.setconnectionParameter(idx, None) idx += 1 - def AddEditedElementPouVar(self, tagname, type, name, location="", description=""): + def GetVarTypeObject(self, var_type): + var_type_obj = PLCOpenParser.CreateElement("type", "variable") + if not var_type.startswith("ANY") and TypeHierarchy.get(var_type): + var_type_obj.setcontent(PLCOpenParser.CreateElement( + var_type.lower() if var_type in ["STRING", "WSTRING"] + else var_type, "dataType")) + else: + derived_type = PLCOpenParser.CreateElement("derived", "dataType") + derived_type.setname(var_type) + var_type_obj.setcontent(derived_type) + return var_type_obj + + def AddEditedElementPouVar(self, tagname, var_type, name, location="", description=""): if self.Project is not None: words = tagname.split("::") if words[0] in ['P', 'T', 'A']: pou = self.Project.getpou(words[1]) if pou is not None: - pou.addpouLocalVar(type, name, location, description) - - def AddEditedElementPouExternalVar(self, tagname, type, name): + pou.addpouLocalVar( + self.GetVarTypeObject(var_type), + name, location, description) + + def AddEditedElementPouExternalVar(self, tagname, var_type, name): if self.Project is not None: words = tagname.split("::") if words[0] in ['P', 'T', 'A']: pou = self.Project.getpou(words[1]) if pou is not None: - pou.addpouExternalVar(type, name) + pou.addpouExternalVar( + self.GetVarTypeObject(var_type), name) def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name): if self.Project is not None:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/Additional_Function_Blocks.xml Tue Sep 10 23:10:58 2013 +0200 @@ -0,0 +1,522 @@ +<?xml version='1.0' encoding='utf-8'?> +<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201"> + <fileHeader companyName="Beremiz" productName="Additional Function Blocks Library" productVersion="1.0" creationDateTime="2013-09-09T09:56:11"/> + <contentHeader name="Standard Funtion Blocks" author="Laurent Bessard" modificationDateTime="2013-09-10T22:45:31"> + <coordinateInfo> + <fbd> + <scaling x="0" y="0"/> + </fbd> + <ld> + <scaling x="0" y="0"/> + </ld> + <sfc> + <scaling x="0" y="0"/> + </sfc> + </coordinateInfo> + </contentHeader> + <types> + <dataTypes/> + <pous> + <pou name="RTC" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="IN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[0 - current time, 1 - load time from PDT]]></xhtml:p> + </documentation> + </variable> + <variable name="PDT"> + <type> + <DT/> + </type> + <documentation> + <xhtml:p><![CDATA[Preset datetime]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[Copy of IN]]></xhtml:p> + </documentation> + </variable> + <variable name="CDT"> + <type> + <DT/> + </type> + <documentation> + <xhtml:p><![CDATA[Datetime, current or relative to PDT]]></xhtml:p> + </documentation> + </variable> + </outputVars> + <localVars> + <variable name="PREV_IN"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + </variable> + <variable name="OFFSET"> + <type> + <TIME/> + </type> + </variable> + <variable name="CURRENT_TIME"> + <type> + <DT/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[{__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)} + + IF IN + THEN + IF NOT PREV_IN + THEN + OFFSET := PDT - CURRENT_TIME; + END_IF; + + (* PDT + time since PDT was loaded *) + CDT := CURRENT_TIME + OFFSET; + ELSE + CDT := CURRENT_TIME; + END_IF; + + Q := IN; + PREV_IN := IN; +]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on.]]></xhtml:p> + </documentation> + </pou> + <pou name="INTEGRAL" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="RUN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[1 = integrate, 0 = hold]]></xhtml:p> + </documentation> + </variable> + <variable name="R1"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[Overriding reset]]></xhtml:p> + </documentation> + </variable> + <variable name="XIN"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Input variable]]></xhtml:p> + </documentation> + </variable> + <variable name="X0"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Initial value]]></xhtml:p> + </documentation> + </variable> + <variable name="CYCLE"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[Sampling period]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[NOT R1]]></xhtml:p> + </documentation> + </variable> + <variable name="XOUT"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Integrated output]]></xhtml:p> + </documentation> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[Q := NOT R1 ; +IF R1 THEN XOUT := X0; +ELSIF RUN THEN XOUT := XOUT + XIN * TIME_TO_REAL(CYCLE); +END_IF;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The integral function block integrates the value of input XIN over time.]]></xhtml:p> + </documentation> + </pou> + <pou name="DERIVATIVE" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="RUN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[0 = reset]]></xhtml:p> + </documentation> + </variable> + <variable name="XIN"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Input to be differentiated]]></xhtml:p> + </documentation> + </variable> + <variable name="CYCLE"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[Sampling period]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="XOUT"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Differentiated output]]></xhtml:p> + </documentation> + </variable> + </outputVars> + <localVars> + <variable name="X1"> + <type> + <REAL/> + </type> + </variable> + <variable name="X2"> + <type> + <REAL/> + </type> + </variable> + <variable name="X3"> + <type> + <REAL/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[IF RUN THEN + XOUT := (3.0 * (XIN - X3) + X1 - X2) + / (10.0 * TIME_TO_REAL(CYCLE)); + X3 := X2; + X2 := X1; + X1 := XIN; +ELSE + XOUT := 0.0; + X1 := XIN; + X2 := XIN; + X3 := XIN; +END_IF;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The derivative function block produces an output XOUT proportional to the rate of change of the input XIN.]]></xhtml:p> + </documentation> + </pou> + <pou name="PID" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="AUTO"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[0 - manual , 1 - automatic]]></xhtml:p> + </documentation> + </variable> + <variable name="PV"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Process variable]]></xhtml:p> + </documentation> + </variable> + <variable name="SP"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Set point]]></xhtml:p> + </documentation> + </variable> + <variable name="X0"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Manual output adjustment - Typically from transfer station]]></xhtml:p> + </documentation> + </variable> + <variable name="KP"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Proportionality constant]]></xhtml:p> + </documentation> + </variable> + <variable name="TR"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Reset time]]></xhtml:p> + </documentation> + </variable> + <variable name="TD"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Derivative time constant]]></xhtml:p> + </documentation> + </variable> + <variable name="CYCLE"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[Sampling period]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="XOUT"> + <type> + <REAL/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="ERROR"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[PV - SP]]></xhtml:p> + </documentation> + </variable> + <variable name="ITERM"> + <type> + <derived name="INTEGRAL"/> + </type> + <documentation> + <xhtml:p><![CDATA[FB for integral term]]></xhtml:p> + </documentation> + </variable> + <variable name="DTERM"> + <type> + <derived name="DERIVATIVE"/> + </type> + <documentation> + <xhtml:p><![CDATA[FB for derivative term]]></xhtml:p> + </documentation> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[ERROR := PV - SP ; +(*** Adjust ITERM so that XOUT := X0 when AUTO = 0 ***) +ITERM(RUN := AUTO, R1 := NOT AUTO, XIN := ERROR, + X0 := TR * (X0 - ERROR), CYCLE := CYCLE); +DTERM(RUN := AUTO, XIN := ERROR, CYCLE := CYCLE); +XOUT := KP * (ERROR + ITERM.XOUT/TR + DTERM.XOUT*TD);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control.]]></xhtml:p> + </documentation> + </pou> + <pou name="RAMP" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="RUN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[0 - track X0, 1 - ramp to/track X1]]></xhtml:p> + </documentation> + </variable> + <variable name="X0"> + <type> + <REAL/> + </type> + </variable> + <variable name="X1"> + <type> + <REAL/> + </type> + </variable> + <variable name="TR"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[Ramp duration]]></xhtml:p> + </documentation> + </variable> + <variable name="CYCLE"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[Sampling period]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="BUSY"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[BUSY = 1 during ramping period]]></xhtml:p> + </documentation> + </variable> + <variable name="XOUT"> + <type> + <REAL/> + </type> + <initialValue> + <simpleValue value="0.0"/> + </initialValue> + </variable> + </outputVars> + <localVars> + <variable name="XI"> + <type> + <REAL/> + </type> + <documentation> + <xhtml:p><![CDATA[Initial value]]></xhtml:p> + </documentation> + </variable> + <variable name="T0"> + <type> + <TIME/> + </type> + <initialValue> + <simpleValue value="T#0s"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[Elapsed time of ramp]]></xhtml:p> + </documentation> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[BUSY := RUN ; +IF RUN THEN + IF T >= TR THEN + BUSY := 0; + XOUT := X1; + ELSE XOUT := XI + (X1-XI) * TIME_TO_REAL(T) + / TIME_TO_REAL(TR); + T := T + CYCLE; + END_IF; +ELSE + XOUT := X0; + XI := X0; + T := T#0s; +END_IF;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The RAMP function block is modelled on example given in the standard.]]></xhtml:p> + </documentation> + </pou> + <pou name="HYSTERESIS" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="XIN1"> + <type> + <REAL/> + </type> + </variable> + <variable name="XIN2"> + <type> + <REAL/> + </type> + </variable> + <variable name="EPS"> + <type> + <REAL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[IF Q THEN + IF XIN1 < (XIN2 - EPS) THEN + Q := 0; + END_IF; +ELSIF XIN1 > (XIN2 + EPS) THEN + Q := 1; +END_IF;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2.]]></xhtml:p> + </documentation> + </pou> + </pous> + </types> + <instances> + <configurations/> + </instances> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/Standard_Function_Blocks.xml Tue Sep 10 23:10:58 2013 +0200 @@ -0,0 +1,1469 @@ +<?xml version='1.0' encoding='utf-8'?> +<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201"> + <fileHeader companyName="Beremiz" productName="Standard Function Blocks Library" productVersion="1.0" creationDateTime="2013-09-09T09:56:11"/> + <contentHeader name="Standard Funtion Blocks" author="Laurent Bessard" modificationDateTime="2013-09-09T10:58:13"> + <coordinateInfo> + <fbd> + <scaling x="0" y="0"/> + </fbd> + <ld> + <scaling x="0" y="0"/> + </ld> + <sfc> + <scaling x="0" y="0"/> + </sfc> + </coordinateInfo> + </contentHeader> + <types> + <dataTypes/> + <pous> + <pou name="SR" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="S1"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q1"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[Q1 := S1 OR ((NOT R) AND Q1);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The SR bistable is a latch where the Set dominates.]]></xhtml:p> + </documentation> + </pou> + <pou name="RS" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="S"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R1"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q1"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[Q1 := (NOT R1) AND (S OR Q1);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The RS bistable is a latch where the Reset dominates.]]></xhtml:p> + </documentation> + </pou> + <pou name="SEMA" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CLAIM"> + <type> + <BOOL/> + </type> + </variable> + <variable name="RELEASE"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="BUSY"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="Q_INTERNAL"> + <type> + <BOOL/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[Q_INTERNAL := CLAIM OR ( Q_INTERNAL AND (NOT RELEASE)); +BUSY := Q_INTERNAL;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources.]]></xhtml:p> + </documentation> + </pou> + <pou name="R_TRIG" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CLK"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + <localVars retain="true"> + <variable name="M"> + <type> + <BOOL/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[Q := CLK AND NOT M; +M := CLK;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The output produces a single pulse when a rising edge is detected.]]></xhtml:p> + </documentation> + </pou> + <pou name="F_TRIG" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CLK"> + <type> + <BOOL/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + </outputVars> + <localVars retain="true"> + <variable name="M"> + <type> + <BOOL/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[Q := NOT CLK AND NOT M; +M := NOT CLK;]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The output produces a single pulse when a falling edge is detected.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTU" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <INT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <INT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CU_T(CU); +IF R THEN CV := 0; +ELSIF CU_T.Q AND (CV < PV) + THEN CV := CV+1; +END_IF; +Q := (CV >= PV);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-counter can be used to signal when a count has reached a maximum value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTU_DINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <DINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <DINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CU_T(CU); +IF R THEN CV := 0; +ELSIF CU_T.Q AND (CV < PV) + THEN CV := CV+1; +END_IF; +Q := (CV >= PV);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-counter can be used to signal when a count has reached a maximum value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTU_LINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <LINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <LINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CU_T(CU); +IF R THEN CV := 0; +ELSIF CU_T.Q AND (CV < PV) + THEN CV := CV+1; +END_IF; +Q := (CV >= PV);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-counter can be used to signal when a count has reached a maximum value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTU_UDINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <UDINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <UDINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CU_T(CU); +IF R THEN CV := 0; +ELSIF CU_T.Q AND (CV < PV) + THEN CV := CV+1; +END_IF; +Q := (CV >= PV);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-counter can be used to signal when a count has reached a maximum value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTU_ULINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <ULINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <ULINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CU_T(CU); +IF R THEN CV := 0; +ELSIF CU_T.Q AND (CV < PV) + THEN CV := CV+1; +END_IF; +Q := (CV >= PV);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-counter can be used to signal when a count has reached a maximum value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTD" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <INT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <INT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +IF LD THEN CV := PV; +ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; +END_IF; +Q := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The down-counter can be used to signal when a count has reached zero, on counting down from a preset value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTD_DINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <DINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <DINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +IF LD THEN CV := PV; +ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; +END_IF; +Q := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The down-counter can be used to signal when a count has reached zero, on counting down from a preset value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTD_LINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <LINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <LINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +IF LD THEN CV := PV; +ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; +END_IF; +Q := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The down-counter can be used to signal when a count has reached zero, on counting down from a preset value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTD_UDINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <UDINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <UDINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +IF LD THEN CV := PV; +ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; +END_IF; +Q := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The down-counter can be used to signal when a count has reached zero, on counting down from a preset value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTD_ULINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <ULINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <ULINT/> + </type> + </variable> + </outputVars> + <localVars> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +IF LD THEN CV := PV; +ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; +END_IF; +Q := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The down-counter can be used to signal when a count has reached zero, on counting down from a preset value.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTUD" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <INT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="QU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="QD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <INT/> + </type> + </variable> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +CU_T(CU); +IF R THEN CV := 0; +ELSIF LD THEN CV := PV; +ELSE + IF NOT (CU_T.Q AND CD_T.Q) THEN + IF CU_T.Q AND (CV < PV) + THEN CV := CV+1; + ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; + END_IF; + END_IF; +END_IF; +QU := (CV >= PV); +QD := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTUD_DINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <DINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="QU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="QD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <DINT/> + </type> + </variable> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +CU_T(CU); +IF R THEN CV := 0; +ELSIF LD THEN CV := PV; +ELSE + IF NOT (CU_T.Q AND CD_T.Q) THEN + IF CU_T.Q AND (CV < PV) + THEN CV := CV+1; + ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; + END_IF; + END_IF; +END_IF; +QU := (CV >= PV); +QD := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTUD_LINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <LINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="QU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="QD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <LINT/> + </type> + </variable> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +CU_T(CU); +IF R THEN CV := 0; +ELSIF LD THEN CV := PV; +ELSE + IF NOT (CU_T.Q AND CD_T.Q) THEN + IF CU_T.Q AND (CV < PV) + THEN CV := CV+1; + ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; + END_IF; + END_IF; +END_IF; +QU := (CV >= PV); +QD := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTUD_UDINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <UDINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="QU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="QD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <UDINT/> + </type> + </variable> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +CU_T(CU); +IF R THEN CV := 0; +ELSIF LD THEN CV := PV; +ELSE + IF NOT (CU_T.Q AND CD_T.Q) THEN + IF CU_T.Q AND (CV < PV) + THEN CV := CV+1; + ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; + END_IF; + END_IF; +END_IF; +QU := (CV >= PV); +QD := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other.]]></xhtml:p> + </documentation> + </pou> + <pou name="CTUD_ULINT" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="CU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="R"> + <type> + <BOOL/> + </type> + </variable> + <variable name="LD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="PV"> + <type> + <ULINT/> + </type> + </variable> + </inputVars> + <outputVars> + <variable name="QU"> + <type> + <BOOL/> + </type> + </variable> + <variable name="QD"> + <type> + <BOOL/> + </type> + </variable> + <variable name="CV"> + <type> + <ULINT/> + </type> + </variable> + <variable name="CD_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + <variable name="CU_T"> + <type> + <derived name="R_TRIG"/> + </type> + </variable> + </outputVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[CD_T(CD); +CU_T(CU); +IF R THEN CV := 0; +ELSIF LD THEN CV := PV; +ELSE + IF NOT (CU_T.Q AND CD_T.Q) THEN + IF CU_T.Q AND (CV < PV) + THEN CV := CV+1; + ELSIF CD_T.Q AND (CV > 0) + THEN CV := CV-1; + END_IF; + END_IF; +END_IF; +QU := (CV >= PV); +QD := (CV <= 0);]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other.]]></xhtml:p> + </documentation> + </pou> + <pou name="TP" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="IN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[first input parameter]]></xhtml:p> + </documentation> + </variable> + <variable name="PT"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[second input parameter]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[first output parameter]]></xhtml:p> + </documentation> + </variable> + <variable name="ET"> + <type> + <TIME/> + </type> + <initialValue> + <simpleValue value="T#0s"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[second output parameter]]></xhtml:p> + </documentation> + </variable> + </outputVars> + <localVars> + <variable name="STATE"> + <type> + <SINT/> + </type> + <initialValue> + <simpleValue value="0"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[internal state: 0-reset, 1-counting, 2-set]]></xhtml:p> + </documentation> + </variable> + <variable name="PREV_IN"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + </variable> + <variable name="CURRENT_TIME"> + <type> + <TIME/> + </type> + </variable> + <variable name="START_TIME"> + <type> + <TIME/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[{__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)} + +IF ((STATE = 0) AND NOT(PREV_IN) AND IN) (* found rising edge on IN *) +THEN + (* start timer... *) + STATE := 1; + Q := TRUE; + START_TIME := CURRENT_TIME; + +ELSIF (STATE = 1) +THEN + IF ((START_TIME + PT) <= CURRENT_TIME) + THEN + STATE := 2; + Q := FALSE; + ET := PT; + ELSE + ET := CURRENT_TIME - START_TIME; + END_IF; +END_IF; + +IF ((STATE = 2) AND NOT(IN)) +THEN + ET := T#0s; + STATE := 0; +END_IF; + +PREV_IN := IN; +]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The pulse timer can be used to generate output pulses of a given time duration.]]></xhtml:p> + </documentation> + </pou> + <pou name="TON" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="IN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[first input parameter]]></xhtml:p> + </documentation> + </variable> + <variable name="PT"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[second input parameter]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[first output parameter]]></xhtml:p> + </documentation> + </variable> + <variable name="ET"> + <type> + <TIME/> + </type> + <initialValue> + <simpleValue value="T#0s"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[second output parameter]]></xhtml:p> + </documentation> + </variable> + </outputVars> + <localVars> + <variable name="STATE"> + <type> + <SINT/> + </type> + <initialValue> + <simpleValue value="0"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[internal state: 0-reset, 1-counting, 2-set]]></xhtml:p> + </documentation> + </variable> + <variable name="PREV_IN"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + </variable> + <variable name="CURRENT_TIME"> + <type> + <TIME/> + </type> + </variable> + <variable name="START_TIME"> + <type> + <TIME/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[{__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)} + +IF ((STATE = 0) AND NOT(PREV_IN) AND IN) (* found rising edge on IN *) +THEN + (* start timer... *) + STATE := 1; + Q := FALSE; + START_TIME := CURRENT_TIME; + +ELSE + (* STATE is 1 or 2 !! *) + IF (NOT(IN)) + THEN + ET := T#0s; + Q := FALSE; + STATE := 0; + + ELSIF (STATE = 1) + THEN + IF ((START_TIME + PT) <= CURRENT_TIME) + THEN + STATE := 2; + Q := TRUE; + ET := PT; + ELSE + ET := CURRENT_TIME - START_TIME; + END_IF; + END_IF; + +END_IF; + +PREV_IN := IN; +]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true.]]></xhtml:p> + </documentation> + </pou> + <pou name="TOF" pouType="functionBlock"> + <interface> + <inputVars> + <variable name="IN"> + <type> + <BOOL/> + </type> + <documentation> + <xhtml:p><![CDATA[first input parameter]]></xhtml:p> + </documentation> + </variable> + <variable name="PT"> + <type> + <TIME/> + </type> + <documentation> + <xhtml:p><![CDATA[second input parameter]]></xhtml:p> + </documentation> + </variable> + </inputVars> + <outputVars> + <variable name="Q"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[first output parameter]]></xhtml:p> + </documentation> + </variable> + <variable name="ET"> + <type> + <TIME/> + </type> + <initialValue> + <simpleValue value="T#0s"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[second output parameter]]></xhtml:p> + </documentation> + </variable> + </outputVars> + <localVars> + <variable name="STATE"> + <type> + <SINT/> + </type> + <initialValue> + <simpleValue value="0"/> + </initialValue> + <documentation> + <xhtml:p><![CDATA[internal state: 0-reset, 1-counting, 2-set]]></xhtml:p> + </documentation> + </variable> + <variable name="PREV_IN"> + <type> + <BOOL/> + </type> + <initialValue> + <simpleValue value="FALSE"/> + </initialValue> + </variable> + <variable name="CURRENT_TIME"> + <type> + <TIME/> + </type> + </variable> + <variable name="START_TIME"> + <type> + <TIME/> + </type> + </variable> + </localVars> + </interface> + <body> + <ST> + <xhtml:p><![CDATA[{__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)} + +IF ((STATE = 0) AND PREV_IN AND NOT(IN)) (* found falling edge on IN *) +THEN + (* start timer... *) + STATE := 1; + START_TIME := CURRENT_TIME; + +ELSE + (* STATE is 1 or 2 !! *) + IF (IN) + THEN + ET := T#0s; + STATE := 0; + + ELSIF (STATE = 1) + THEN + IF ((START_TIME + PT) <= CURRENT_TIME) + THEN + STATE := 2; + ET := PT; + ELSE + ET := CURRENT_TIME - START_TIME; + END_IF; + END_IF; + +END_IF; + +Q := IN OR (STATE = 1); +PREV_IN := IN; +]]></xhtml:p> + </ST> + </body> + <documentation> + <xhtml:p><![CDATA[The off-delay timer can be used to delay setting an output false, for fixed period after input goes false.]]></xhtml:p> + </documentation> + </pou> + </pous> + </types> + <instances> + <configurations/> + </instances> +</project>
--- a/plcopen/plcopen.py Tue Sep 10 10:37:42 2013 +0200 +++ b/plcopen/plcopen.py Tue Sep 10 23:10:58 2013 +0200 @@ -23,7 +23,6 @@ #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from xmlclass import * -from structures import * from types import * import os, re from lxml import etree @@ -296,16 +295,13 @@ def setcontentHeader(self, contentheader): contentheader_obj = self.contentHeader for attr, value in contentheader.iteritems(): - if attr == "projectName": - contentheader_obj.setname(value) - elif attr == "projectVersion": - contentheader_obj.setversion(value) - elif attr == "authorName": - contentheader_obj.setauthor(value) - elif attr == "pageSize": - contentheader_obj.setpageSize(*contentheader["pageSize"]) - elif attr == "scaling": - contentheader_obj.setscaling(contentheader["scaling"]) + func = {"projectName": contentheader_obj.setname, + "projectVersion": contentheader_obj.setversion, + "authorName": contentheader_obj.setauthor, + "pageSize": lambda v: contentheader_obj.setpageSize(*v), + "scaling": contentheader_obj.setscaling}.get(attr) + if func is not None: + func(value) elif attr in ["modificationDateTime", "organization", "language"]: setattr(contentheader_obj, attr, value) setattr(cls, "setcontentHeader", setcontentHeader) @@ -607,16 +603,7 @@ globalvars.append(PLCOpenParser.CreateElement("varList")) var = PLCOpenParser.CreateElement("variable", "varListPlain") var.setname(name) - var_type_obj = PLCOpenParser.CreateElement("dataType") - if not var_type.startswith("ANY") and TypeHierarchy.get(var_type): - var_type_obj.setcontent(PLCOpenParser.CreateElement( - var_type.lower() if var_type in ["STRING", "WSTRING"] - else vartype, "dataType")) - else: - derived_type = PLCOpenParser.CreateElement("derived", "dataType") - derived_type.setname(var_type) - var_type_obj.setcontent(derived_type) - var.settype(var_type_obj) + var.settype(var_type) if location != "": var.setaddress(location) if description != "": @@ -1164,16 +1151,7 @@ content[-1].addnext(varlist) var = PLCOpenParser.CreateElement("variable", "varListPlain") var.setname(name) - var_type_obj = PLCOpenParser.CreateElement("type", "variable") - if not var_type.startswith("ANY") and TypeHierarchy.get(var_type): - var_type_obj.setcontent(PLCOpenParser.CreateElement( - var_type.lower() if var_type in ["STRING", "WSTRING"] - else var_type, "dataType")) - else: - derived_type = PLCOpenParser.CreateElement("derived", "dataType") - derived_type.setname(var_type) - var_type_obj.setcontent(derived_type) - var.settype(var_type_obj) + var.settype(var_type) if location != "": var.setaddress(location) if description != "":
--- a/plcopen/structures.py Tue Sep 10 10:37:42 2013 +0200 +++ b/plcopen/structures.py Tue Sep 10 23:10:58 2013 +0200 @@ -23,6 +23,7 @@ #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import string, os, sys, re +from plcopen import LoadProject LANGUAGES = ["IL","ST","FBD","LD","SFC"] @@ -38,6 +39,44 @@ # Function Block Types definitions #------------------------------------------------------------------------------- +ScriptDirectory = os.path.split(os.path.realpath(__file__))[0] + +StdBlockLibrary = LoadProject(os.path.join(ScriptDirectory, "Standard_Function_Blocks.xml")) +AddnlBlockLibrary = LoadProject(os.path.join(ScriptDirectory, "Additional_Function_Blocks.xml")) + +StdBlockComments = { + "SR": _("SR bistable\nThe SR bistable is a latch where the Set dominates."), + "RS": _("RS bistable\nThe RS bistable is a latch where the Reset dominates."), + "SEMA": _("Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources."), + "R_TRIG": _("Rising edge detector\nThe output produces a single pulse when a rising edge is detected."), + "F_TRIG": _("Falling edge detector\nThe output produces a single pulse when a falling edge is detected."), + "CTU": _("Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value."), + "CTD": _("Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value."), + "CTUD": _("Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other."), + "TP": _("Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration."), + "TON": _("On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true."), + "TOF": _("Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false."), + "RTC": _("Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on."), + "INTEGRAL": _("Integral\nThe integral function block integrates the value of input XIN over time."), + "DERIVATIVE": _("Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN."), + "PID": _("PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control."), + "RAMP": _("Ramp\nThe RAMP function block is modelled on example given in the standard."), + "HYSTERESIS": _("Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2."), +} + +for block_type in ["CTU", "CTD", "CTUD"]: + for return_type in ["DINT", "LINT", "UDINT", "ULINT"]: + StdBlockComments["%s_%s" % (block_type, return_type)] = StdBlockComments[block_type] + +def GetBlockInfos(pou): + infos = pou.getblockInfos() + infos["comment"] = StdBlockComments[infos["name"]] + infos["inputs"] = [ + (var_name, var_type, "rising") + if var_name in ["CU", "CD"] + else (var_name, var_type, var_modifier) + for var_name, var_type, var_modifier in infos["inputs"]] + return infos """ Ordored list of common Function Blocks defined in the IEC 61131-3 @@ -56,81 +95,9 @@ """ StdBlckLst = [{"name" : _("Standard function blocks"), "list": - [{"name" : "SR", "type" : "functionBlock", "extensible" : False, - "inputs" : [("S1","BOOL","none"),("R","BOOL","none")], - "outputs" : [("Q1","BOOL","none")], - "comment" : _("SR bistable\nThe SR bistable is a latch where the Set dominates.")}, - {"name" : "RS", "type" : "functionBlock", "extensible" : False, - "inputs" : [("S","BOOL","none"),("R1","BOOL","none")], - "outputs" : [("Q1","BOOL","none")], - "comment" : _("RS bistable\nThe RS bistable is a latch where the Reset dominates.")}, - {"name" : "SEMA", "type" : "functionBlock", "extensible" : False, - "inputs" : [("CLAIM","BOOL","none"),("RELEASE","BOOL","none")], - "outputs" : [("BUSY","BOOL","none")], - "comment" : _("Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources.")}, - {"name" : "R_TRIG", "type" : "functionBlock", "extensible" : False, - "inputs" : [("CLK","BOOL","none")], - "outputs" : [("Q","BOOL","none")], - "comment" : _("Rising edge detector\nThe output produces a single pulse when a rising edge is detected.")}, - {"name" : "F_TRIG", "type" : "functionBlock", "extensible" : False, - "inputs" : [("CLK","BOOL","none")], - "outputs" : [("Q","BOOL","none")], - "comment" : _("Falling edge detector\nThe output produces a single pulse when a falling edge is detected.")}, - {"name" : "CTU", "type" : "functionBlock", "extensible" : False, - "inputs" : [("CU","BOOL","rising"),("R","BOOL","none"),("PV","INT","none")], - "outputs" : [("Q","BOOL","none"),("CV","INT","none")], - "comment" : _("Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value.")}, - {"name" : "CTD", "type" : "functionBlock", "extensible" : False, - "inputs" : [("CD","BOOL","rising"),("LD","BOOL","none"),("PV","INT","none")], - "outputs" : [("Q","BOOL","none"),("CV","INT","none")], - "comment" : _("Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value.")}, - {"name" : "CTUD", "type" : "functionBlock", "extensible" : False, - "inputs" : [("CU","BOOL","rising"),("CD","BOOL","rising"),("R","BOOL","none"),("LD","BOOL","none"),("PV","INT","none")], - "outputs" : [("QU","BOOL","none"),("QD","BOOL","none"),("CV","INT","none")], - "comment" : _("Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other.")}, - {"name" : "TP", "type" : "functionBlock", "extensible" : False, - "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], - "outputs" : [("Q","BOOL","none"),("ET","TIME","none")], - "comment" : _("Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration.")}, - {"name" : "TON", "type" : "functionBlock", "extensible" : False, - "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], - "outputs" : [("Q","BOOL","none"),("ET","TIME","none")], - "comment" : _("On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true.")}, - {"name" : "TOF", "type" : "functionBlock", "extensible" : False, - "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], - "outputs" : [("Q","BOOL","none"),("ET","TIME","none")], - "comment" : _("Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false.")}, - ]}, + [GetBlockInfos(pou) for pou in StdBlockLibrary.getpous()]}, {"name" : _("Additional function blocks"), "list": - [{"name" : "RTC", "type" : "functionBlock", "extensible" : False, - "inputs" : [("IN","BOOL","none"),("PDT","DATE_AND_TIME","none")], - "outputs" : [("Q","BOOL","none"),("CDT","DATE_AND_TIME","none")], - "comment" : _("Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on.")}, - {"name" : "INTEGRAL", "type" : "functionBlock", "extensible" : False, - "inputs" : [("RUN","BOOL","none"),("R1","BOOL","none"),("XIN","REAL","none"),("X0","REAL","none"),("CYCLE","TIME","none")], - "outputs" : [("Q","BOOL","none"),("XOUT","REAL","none")], - "comment" : _("Integral\nThe integral function block integrates the value of input XIN over time.")}, - {"name" : "DERIVATIVE", "type" : "functionBlock", "extensible" : False, - "inputs" : [("RUN","BOOL","none"),("XIN","REAL","none"),("CYCLE","TIME","none")], - "outputs" : [("XOUT","REAL","none")], - "comment" : _("Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN.")}, - {"name" : "PID", "type" : "functionBlock", "extensible" : False, - "inputs" : [("AUTO","BOOL","none"),("PV","REAL","none"),("SP","REAL","none"),("X0","REAL","none"),("KP","REAL","none"),("TR","REAL","none"),("TD","REAL","none"),("CYCLE","TIME","none")], - "outputs" : [("XOUT","REAL","none")], - "comment" : _("PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control.")}, - {"name" : "RAMP", "type" : "functionBlock", "extensible" : False, - "inputs" : [("RUN","BOOL","none"),("X0","REAL","none"),("X1","REAL","none"),("TR","TIME","none"),("CYCLE","TIME","none")], - "outputs" : [("BUSY","BOOL","none"),("XOUT","REAL","none")], - "comment" : _("Ramp\nThe RAMP function block is modelled on example given in the standard.")}, - {"name" : "HYSTERESIS", "type" : "functionBlock", "extensible" : False, - "inputs" : [("XIN1","REAL","none"),("XIN2","REAL","none"),("EPS","REAL","none")], - "outputs" : [("Q","BOOL","none")], - "comment" : _("Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2.")}, -## {"name" : "RATIO_MONITOR", "type" : "functionBlock", "extensible" : False, -## "inputs" : [("PV1","REAL","none"),("PV2","REAL","none"),("RATIO","REAL","none"),("TIMON","TIME","none"),("TIMOFF","TIME","none"),("TOLERANCE","BOOL","none"),("RESET","BOOL","none"),("CYCLE","TIME","none")], -## "outputs" : [("ALARM","BOOL","none"),("TOTAL_ERR","BOOL","none")], -## "comment" : _("Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2.")} - ]}, + [GetBlockInfos(pou) for pou in AddnlBlockLibrary.getpous()]}, ] @@ -446,7 +413,7 @@ return Standard_Functions_Decl -std_decl = get_standard_funtions(csv_file_to_table(open(os.path.join(os.path.split(__file__)[0],"iec_std.csv"))))#, True) +std_decl = get_standard_funtions(csv_file_to_table(open(os.path.join(ScriptDirectory,"iec_std.csv"))))#, True) StdBlckLst.extend(std_decl) @@ -458,12 +425,11 @@ words = desc["comment"].split('"') if len(words) > 1: desc["comment"] = words[1] - desc["usage"] = ( - "\n (" + - str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in desc["inputs"]]).strip("[]").replace("'",'') + - " ) => (" + - str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in desc["outputs"]]).strip("[]").replace("'",'') + - " )") + desc["usage"] = ("\n (%s) => (%s)" % + (", ".join(["%s:%s" % (input[1], input[0]) + for input in desc["inputs"]]), + ", ".join(["%s:%s" % (output[1], output[0]) + for output in desc["outputs"]]))) BlkLst = StdBlckDct.setdefault(desc["name"],[]) BlkLst.append((section["name"], desc))