Add support for custom block declaration
authorlbessard
Mon, 17 Sep 2007 17:50:41 +0200
changeset 93 c3c24b979a4d
parent 92 76d5001393df
child 94 e7f5a251f251
Add support for custom block declaration
PLCGenerator.py
plcopen/structures.py
--- a/PLCGenerator.py	Mon Sep 17 10:13:56 2007 +0200
+++ b/PLCGenerator.py	Mon Sep 17 17:50:41 2007 +0200
@@ -198,16 +198,22 @@
                 if not isinstance(type, (StringType, UnicodeType)):
                     type = type.getName()
                     GeneratePouProgram(type)
-                initial = var.getInitialValue()
-                if initial:
-                    initial_value = initial.getValue()
+                    blocktype = GetBlockType(type)
+                    if blocktype:
+                        variables.extend(blocktype["initialise"](type, var.getName()))
+                        located = False
                 else:
-                    initial_value = None
-                address = var.getAddress()
-                if address:
-                    located = True
-                variables.append((type, var.getName(), address, initial_value))
-            self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), 
+                    initial = var.getInitialValue()
+                    if initial:
+                        initial_value = initial.getValue()
+                    else:
+                        initial_value = None
+                    address = var.getAddress()
+                    if address:
+                        located = True
+                    variables.append((type, var.getName(), address, initial_value))
+            if len(variables) > 0:
+                self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), 
                             varlist["value"].getConstant(), located, variables))
     
     def GenerateProgram(self, pou):
@@ -622,7 +628,9 @@
                 program += " CONSTANT"
             program += "\n"
             for var_type, var_name, var_address, var_initial in variables:
-                program += "    %s "%var_name
+                program += "    "
+                if var_name:
+                    program += "%s "%var_name
                 if var_address != None:
                     program += "AT %s "%var_address
                 program += ": %s"%var_type
--- a/plcopen/structures.py	Mon Sep 17 10:13:56 2007 +0200
+++ b/plcopen/structures.py	Mon Sep 17 17:50:41 2007 +0200
@@ -62,6 +62,9 @@
                 return generator.ExtractModifier(variable, "%s.%s"%(name, variable.getFormalParameter()))
         raise ValueError, "No output variable found"
 
+def initialise_block(type, name):
+    return [(type, name, None, None)]
+
 #-------------------------------------------------------------------------------
 #                        Function Block Types definitions
 #-------------------------------------------------------------------------------
@@ -88,92 +91,92 @@
                     "inputs" : [("S1","BOOL","none"),("R","BOOL","none")], 
                     "outputs" : [("Q1","BOOL","none")],
                     "comment" : "SR bistable\nThe SR bistable is a latch where the Set dominates.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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 ans down on the other.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"name" : "TOF", "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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"name" : "TON", "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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"name" : "RTC", "type" : "functionBlock", "extensible" : False, 
                     "inputs" : [("EN","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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"name" : "RAMP", "type" : "functionBlock", "extensible" : False, 
                     "inputs" : [("RUN","BOOL","none"),("X0","REAL","none"),("X1","REAL","none"),("TR","TIME","none"),("CYCLE","TIME","none"),("HOLDBACK","BOOL","none"),("ERROR","REAL","none"),("PV","REAL","none")], 
                     "outputs" : [("RAMP","BOOL","none"),("XOUT","REAL","none")],
                     "comment" : "Ramp\nThe RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block},
+                    "generate" : generate_block, "initialise" : initialise_block},
                 {"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.",
-                    "generate" : generate_block}
+                    "generate" : generate_block, "initialise" : initialise_block}
                 ]},
              ]
              
@@ -495,6 +498,7 @@
             if Current_section:
                 Function_decl = dict([(champ, val) for champ, val in zip(fonctions, fields[1:]) if champ])
                 Function_decl["generate"] = generate_block
+                Function_decl["initialise"] = lambda x,y:[]
                 baseinputnumber = int(Function_decl.get("baseinputnumber",1))
                 Function_decl["baseinputnumber"] = baseinputnumber
                 for param, value in Function_decl.iteritems():