# HG changeset patch # User lbessard # Date 1221229420 -7200 # Node ID 34eff05909b039876edcd62e86218f910eedfa87 # Parent 5508af39d1f7a297e3b7ec7e46e92789000344f8 Adding support for EN/ENO variables (temporarily disabled, waiting for matiec support) Adding support for rising and falling edge in coil and fixing coil ST generation diff -r 5508af39d1f7 -r 34eff05909b0 Dialogs.py --- a/Dialogs.py Thu Sep 11 14:55:49 2008 +0200 +++ b/Dialogs.py Fri Sep 12 16:23:40 2008 +0200 @@ -34,10 +34,11 @@ [ID_BLOCKPROPERTIESDIALOG, ID_BLOCKPROPERTIESDIALOGNAME, ID_BLOCKPROPERTIESDIALOGTYPETREE, ID_BLOCKPROPERTIESDIALOGTYPEDESC, ID_BLOCKPROPERTIESDIALOGINPUTS, ID_BLOCKPROPERTIESDIALOGPREVIEW, - ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER, ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, - ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, ID_BLOCKPROPERTIESDIALOGSTATICTEXT3, - ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, -] = [wx.NewId() for _init_ctrls in range(12)] + ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER, ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL, + ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, + ID_BLOCKPROPERTIESDIALOGSTATICTEXT3, ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, + ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, ID_BLOCKPROPERTIESDIALOGSTATICTEXT6, +] = [wx.NewId() for _init_ctrls in range(14)] [CATEGORY, BLOCK] = range(2) @@ -68,7 +69,7 @@ def _init_coll_RightGridSizer_Items(self, parent): parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW) parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) def _init_coll_RightGridSizer_Growables(self, parent): @@ -82,13 +83,15 @@ parent.AddWindow(self.Inputs, 0, border=0, flag=wx.GROW) parent.AddWindow(self.staticText4, 0, border=4, flag=wx.GROW|wx.TOP) parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText5, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.ExecutionControl, 0, border=0, flag=wx.GROW) def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) self.LeftBoxSizer = wx.StaticBoxSizer(self.staticbox1, wx.VERTICAL) self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5) - self.RightUpGridSizer = wx.GridSizer(cols=2, hgap=5, rows=3, vgap=5) + self.RightUpGridSizer = wx.GridSizer(cols=2, hgap=5, rows=4, vgap=5) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) @@ -103,9 +106,9 @@ def _init_ctrls(self, prnt): wx.Dialog.__init__(self, id=ID_BLOCKPROPERTIESDIALOG, name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(600, 380), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, + size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, title='Block Properties') - self.SetClientSize(wx.Size(600, 380)) + self.SetClientSize(wx.Size(600, 400)) self.staticbox1 = wx.StaticBox(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, label='Type:', name='staticBox1', parent=self, @@ -124,7 +127,11 @@ pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText5 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, - label='Preview:', name='staticText5', parent=self, + label='Execution Control:', name='staticText5', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + + self.staticText6 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT6, + label='Preview:', name='staticText6', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) if wx.Platform == '__WXMSW__': @@ -156,6 +163,11 @@ size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0) self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER) + self.ExecutionControl = wx.CheckBox(id=ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL, + name='ExecutionControl', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_CHECKBOX, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONCONTROL) + self.Preview = wx.Panel(id=ID_BLOCKPROPERTIESDIALOGPREVIEW, name='Preview', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) @@ -185,6 +197,9 @@ self.MinBlockSize = None self.First = True + self.staticText5.Hide() + self.ExecutionControl.Hide() + self.PouNames = [] self.PouElementNames = [] @@ -283,6 +298,8 @@ self.Inputs.SetValue(value) elif name == "executionOrder": self.ExecutionOrder.SetValue(value) + elif name == "executionControl": + self.ExecutionControl.SetValue(value) self.RefreshPreview() def GetValues(self): @@ -295,6 +312,7 @@ values["width"], values["height"] = self.Block.GetSize() values["extension"] = self.Inputs.GetValue() values["executionOrder"] = self.ExecutionOrder.GetValue() + values["executionControl"] = self.ExecutionControl.GetValue() return values def OnTypeTreeItemSelected(self, event): @@ -337,6 +355,10 @@ self.RefreshPreview() event.Skip() + def OnExecutionControlChanged(self, event): + self.RefreshPreview() + event.Skip() + def ErasePreview(self): dc = wx.ClientDC(self.Preview) dc.Clear() @@ -354,7 +376,12 @@ else: blocktype = self.TypeTree.GetItemText(item) if blocktype: - self.Block = FBD_Block(self.Preview, blocktype, self.BlockName.GetValue(), extension = self.Inputs.GetValue(), inputs = pydata["inputs"], executionOrder = self.ExecutionOrder.GetValue()) + self.Block = FBD_Block(self.Preview, blocktype, + self.BlockName.GetValue(), + extension = self.Inputs.GetValue(), + inputs = pydata["inputs"], + executionControl = self.ExecutionControl.GetValue(), + executionOrder = self.ExecutionOrder.GetValue()) width, height = self.MinBlockSize min_width, min_height = self.Block.GetMinSize() width, height = max(min_width, width), max(min_height, height) @@ -867,10 +894,11 @@ [ID_LDELEMENTDIALOG, ID_LDELEMENTDIALOGSPACER, ID_LDELEMENTDIALOGNAME, ID_LDELEMENTDIALOGRADIOBUTTON1, ID_LDELEMENTDIALOGRADIOBUTTON2, ID_LDELEMENTDIALOGRADIOBUTTON3, - ID_LDELEMENTDIALOGRADIOBUTTON4, ID_LDELEMENTDIALOGPREVIEW, + ID_LDELEMENTDIALOGRADIOBUTTON4, ID_LDELEMENTDIALOGRADIOBUTTON5, + ID_LDELEMENTDIALOGRADIOBUTTON6, ID_LDELEMENTDIALOGPREVIEW, ID_LDELEMENTDIALOGSTATICTEXT1, ID_LDELEMENTDIALOGSTATICTEXT2, ID_LDELEMENTDIALOGSTATICTEXT3, -] = [wx.NewId() for _init_ctrls in range(11)] +] = [wx.NewId() for _init_ctrls in range(13)] class LDElementDialog(wx.Dialog): @@ -895,18 +923,23 @@ def _init_coll_LeftGridSizer_Items(self, parent): parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW) + parent.AddSizer(self.RadioButtonSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.ElementName, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) + + def _init_coll_LeftGridSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(7) + + def _init_coll_RadioButtonSizer_Items(self, parent): parent.AddWindow(self.radioButton1, 0, border=0, flag=wx.GROW) parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW) parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW) parent.AddWindow(self.radioButton4, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.ElementName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW) - - def _init_coll_LeftGridSizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(7) - + parent.AddWindow(self.radioButton5, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.radioButton6, 0, border=0, flag=wx.GROW) + def _init_coll_RightGridSizer_Items(self, parent): parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW) parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) @@ -918,7 +951,8 @@ def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) - self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=8, vgap=5) + self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) + self.RadioButtonSizer = wx.BoxSizer(wx.VERTICAL) self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) @@ -926,17 +960,18 @@ self._init_coll_MainSizer_Items(self.MainSizer) self._init_coll_LeftGridSizer_Items(self.LeftGridSizer) self._init_coll_LeftGridSizer_Growables(self.LeftGridSizer) + self._init_coll_RadioButtonSizer_Items(self.RadioButtonSizer) self._init_coll_RightGridSizer_Items(self.RightGridSizer) self._init_coll_RightGridSizer_Growables(self.RightGridSizer) self.SetSizer(self.flexGridSizer1) - def _init_ctrls(self, prnt, ctrler, title, labels): + def _init_ctrls(self, prnt, ctrler, title, extra_size = 0): wx.Dialog.__init__(self, id=ID_LDELEMENTDIALOG, name='LDElementDialog', parent=prnt, pos=wx.Point(376, 223), - size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE, + size=wx.Size(350, 260 + extra_size), style=wx.DEFAULT_DIALOG_STYLE, title=title) - self.SetClientSize(wx.Size(350, 260)) + self.SetClientSize(wx.Size(350, 260 + extra_size)) self.staticText1 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT1, label='Modifier:', name='staticText1', parent=self, @@ -951,26 +986,36 @@ pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.radioButton1 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON1, - label=labels[0], name='radioButton1', parent=self, + label="Normal", name='radioButton1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON1) self.radioButton1.SetValue(True) self.radioButton2 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON2, - label=labels[1], name='radioButton2', parent=self, + label="Negated", name='radioButton2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON2) self.radioButton3 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON3, - label=labels[2], name='radioButton3', parent=self, + label="Set", name='radioButton3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON3) self.radioButton4 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON4, - label=labels[3], name='radioButton4', parent=self, + label="Reset", name='radioButton4', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON4) + self.radioButton5 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON5, + label="Rising Edge", name='radioButton5', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON5) + + self.radioButton6 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON6, + label="Falling Edge", name='radioButton6', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) + self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON6) + self.ElementName = wx.Choice(id=ID_LDELEMENTDIALOGNAME, name='Name', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) @@ -1000,11 +1045,14 @@ def __init__(self, parent, controler, type): self.Type = type if type == "contact": - self._init_ctrls(parent, controler, "Edit Contact Values", ['Normal','Negate','Rising Edge','Falling Edge']) + self._init_ctrls(parent, controler, "Edit Contact Values") self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "") + self.radioButton3.Hide() + self.radioButton4.Hide() elif type == "coil": - self._init_ctrls(parent, controler, "Edit Coil Values", ['Normal','Negate','Set','Reset']) + self._init_ctrls(parent, controler, "Edit Coil Values", 50) self.Element = LD_Coil(self.Preview, COIL_NORMAL, "") + def SetPreviewFont(self, font): self.Preview.SetFont(font) @@ -1033,9 +1081,9 @@ elif value == CONTACT_REVERSE: self.radioButton2.SetValue(True) elif value == CONTACT_RISING: - self.radioButton3.SetValue(True) + self.radioButton5.SetValue(True) elif value == CONTACT_FALLING: - self.radioButton4.SetValue(True) + self.radioButton6.SetValue(True) elif self.Type == "coil": if value == COIL_NORMAL: self.radioButton1.SetValue(True) @@ -1045,6 +1093,10 @@ self.radioButton3.SetValue(True) elif value == COIL_RESET: self.radioButton4.SetValue(True) + elif value == COIL_RISING: + self.radioButton5.SetValue(True) + elif value == COIL_FALLING: + self.radioButton6.SetValue(True) def GetValues(self): values = {} @@ -1059,9 +1111,9 @@ self.Element.SetType(CONTACT_NORMAL) elif self.radioButton2.GetValue(): self.Element.SetType(CONTACT_REVERSE) - elif self.radioButton3.GetValue(): + elif self.radioButton5.GetValue(): self.Element.SetType(CONTACT_RISING) - elif self.radioButton4.GetValue(): + elif self.radioButton6.GetValue(): self.Element.SetType(CONTACT_FALLING) elif self.Type == "coil": if self.radioButton1.GetValue(): @@ -1072,6 +1124,10 @@ self.Element.SetType(COIL_SET) elif self.radioButton4.GetValue(): self.Element.SetType(COIL_RESET) + elif self.radioButton5.GetValue(): + self.Element.SetType(COIL_RISING) + elif self.radioButton6.GetValue(): + self.Element.SetType(COIL_FALLING) self.RefreshPreview() event.Skip() diff -r 5508af39d1f7 -r 34eff05909b0 PLCControler.py --- a/PLCControler.py Thu Sep 11 14:55:49 2008 +0200 +++ b/PLCControler.py Fri Sep 12 16:23:40 2008 +0200 @@ -1653,6 +1653,7 @@ else: infos["executionOrder"] = 0 infos["negated"] = instance.getnegated() + infos["edge"] = instance.getedge() infos["storage"] = instance.getstorage() infos["connectors"] = {"input":{},"output":{}} infos["connectors"]["input"]["position"] = instance.connectionPointIn.getrelPositionXY() @@ -2177,15 +2178,27 @@ if value == COIL_NORMAL: coil.setnegated(False) coil.setstorage("none") + coil.setedge("none") elif value == COIL_REVERSE: coil.setnegated(True) coil.setstorage("none") + coil.setedge("none") elif value == COIL_SET: coil.setnegated(False) coil.setstorage("set") + coil.setedge("none") elif value == COIL_RESET: coil.setnegated(False) coil.setstorage("reset") + coil.setedge("none") + elif value == COIL_RISING: + coil.setnegated(False) + coil.setstorage("none") + coil.setedge("rising") + elif value == COIL_FALLING: + coil.setnegated(False) + coil.setstorage("none") + coil.setedge("falling") elif param == "height": coil.setheight(value) elif param == "width": diff -r 5508af39d1f7 -r 34eff05909b0 PLCGenerator.py --- a/PLCGenerator.py Thu Sep 11 14:55:49 2008 +0200 +++ b/PLCGenerator.py Fri Sep 12 16:23:40 2008 +0200 @@ -61,6 +61,13 @@ compute += "\n" return compute +def SortInstances(a, b): + ax, ay = int(a.getx()), int(a.gety()) + bx, by = int(b.getx()), int(b.gety()) + if abs(ax - ay) < 10: + return ax.__cmp__(bx) + else: + return ay.__cmp__(by) #------------------------------------------------------------------------------- # Specific exception for PLC generating errors @@ -566,16 +573,19 @@ else: var_type = returntype_content["name"] elif var_type is None: - var_type = expression.split("#")[0] - if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)): - for connection in self.ExtractRelatedConnections(instance.connectionPointOut): - self.ConnectionTypes[connection] = var_type - if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): - self.ConnectionTypes[instance.connectionPointIn] = var_type - connected = self.GetConnectedConnector(instance.connectionPointIn, body) - if connected and connected not in self.ConnectionTypes: - for connection in self.ExtractRelatedConnections(connected): + parts = expression.split("#") + if len(parts) > 1: + var_type = parts[0] + if var_type is not None: + if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)): + for connection in self.ExtractRelatedConnections(instance.connectionPointOut): self.ConnectionTypes[connection] = var_type + if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): + self.ConnectionTypes[instance.connectionPointIn] = var_type + connected = self.GetConnectedConnector(instance.connectionPointIn, body) + if connected and connected not in self.ConnectionTypes: + for connection in self.ExtractRelatedConnections(connected): + self.ConnectionTypes[connection] = var_type elif isinstance(instance, (plcopen.ldObjects_contact, plcopen.ldObjects_coil)): for connection in self.ExtractRelatedConnections(instance.connectionPointOut): self.ConnectionTypes[connection] = "BOOL" @@ -607,17 +617,24 @@ undefined = {} for variable in instance.outputVariables.getvariable(): output_name = variable.getformalParameter() - for oname, otype, oqualifier in block_infos["outputs"]: - if output_name == oname and variable.connectionPointOut not in self.ConnectionTypes: - if otype.startswith("ANY"): - if otype not in undefined: - undefined[otype] = [] - undefined[otype].append(variable.connectionPointOut) - else: - for connection in self.ExtractRelatedConnections(variable.connectionPointOut): - self.ConnectionTypes[connection] = otype + if output_name == "ENO": + for connection in self.ExtractRelatedConnections(variable.connectionPointOut): + self.ConnectionTypes[connection] = "BOOL" + else: + for oname, otype, oqualifier in block_infos["outputs"]: + if output_name == oname and variable.connectionPointOut not in self.ConnectionTypes: + if otype.startswith("ANY"): + if otype not in undefined: + undefined[otype] = [] + undefined[otype].append(variable.connectionPointOut) + else: + for connection in self.ExtractRelatedConnections(variable.connectionPointOut): + self.ConnectionTypes[connection] = otype for variable in instance.inputVariables.getvariable(): input_name = variable.getformalParameter() + if input_name == "EN": + for connection in self.ExtractRelatedConnections(variable.connectionPointIn): + self.ConnectionTypes[connection] = "BOOL" for iname, itype, iqualifier in block_infos["inputs"]: if input_name == iname: connected = self.GetConnectedConnector(variable.connectionPointIn, body) @@ -673,24 +690,25 @@ for initialstep in self.InitialSteps: self.ComputeSFCStep(initialstep) else: + otherInstances = {"outVariables&coils" : [], "blocks" : [], "connectors" : []} orderedInstances = [] - otherInstances = {"outVariables" : [], "block" : [], "connector" : [], "coil" : []} for instance in body.getcontentInstances(): if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)): executionOrderId = instance.getexecutionOrderId() if executionOrderId > 0: orderedInstances.append((executionOrderId, instance)) elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): - otherInstances["outVariables"].append(instance) + otherInstances["outVariables&coils"].append(instance) elif isinstance(instance, plcopen.fbdObjects_block): - otherInstances["block"].append(instance) + otherInstances["blocks"].append(instance) elif isinstance(instance, plcopen.commonObjects_connector): - otherInstances["connector"].append(instance) + otherInstances["connectors"].append(instance) elif isinstance(instance, plcopen.ldObjects_coil): - otherInstances["coil"].append(instance) + otherInstances["outVariables&coils"].append(instance) orderedInstances.sort() + otherInstances["outVariables&coils"].sort(SortInstances) instances = [instance for (executionOrderId, instance) in orderedInstances] - instances.extend(otherInstances["connector"] + otherInstances["outVariables"] + otherInstances["coil"] + otherInstances["block"]) + instances.extend(otherInstances["connectors"] + otherInstances["outVariables&coils"] + otherInstances["blocks"]) for instance in instances: if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): connections = instance.connectionPointIn.getconnections() @@ -714,12 +732,12 @@ elif isinstance(instance, plcopen.ldObjects_coil): connections = instance.connectionPointIn.getconnections() if connections is not None: - expression = self.ComputeExpression(body, connections) coil_info = (self.TagName, "coil", instance.getlocalId()) - variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) - self.Program += [(self.CurrentIndent, ())] + variable + expression = self.ExtractModifier(instance, self.ComputeExpression(body, connections), coil_info) + self.Program += [(self.CurrentIndent, ())] + self.Program += [(instance.getvariable(), coil_info + ("reference",))] self.Program += [(" := ", ())] + expression + [(";\n", ())] - + def FactorizePaths(self, paths): same_paths = {} uncomputed_index = range(len(paths)) @@ -829,6 +847,14 @@ if variable.getnegated(): return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] else: + storage = variable.getstorage() + if storage in ["set", "reset"]: + self.Program += [(self.CurrentIndent + "IF ", var_info + (storage,))] + expression + self.Program += [(" THEN\n ", ())] + if storage == "set": + return [("TRUE;\n" + self.CurrentIndent + "END_IF", ())] + else: + return [("FALSE;\n" + self.CurrentIndent + "END_IF", ())] edge = variable.getedge() if edge == "rising": return self.AddTrigger("R_TRIG", expression, var_info + ("rising",)) diff -r 5508af39d1f7 -r 34eff05909b0 Viewer.py --- a/Viewer.py Thu Sep 11 14:55:49 2008 +0200 +++ b/Viewer.py Fri Sep 12 16:23:40 2008 +0200 @@ -781,12 +781,20 @@ storage = instance["storage"] else: storage = "none" - if negated and storage == "none": + if instance["edge"]: + edge = instance["edge"] + else: + edge = "none" + if negated and storage == "none" and edge == "none": coil_type = COIL_REVERSE - elif not negated and storage == "set": + elif not negated and edge == "none" and storage == "set": coil_type = COIL_SET - elif not negated and storage == "reset": + elif not negated and edge == "none" and storage == "reset": coil_type = COIL_RESET + elif not negated and storage == "none" and edge == "rising": + coil_type = COIL_RISING + elif not negated and storage == "none" and edge == "falling": + coil_type = COIL_FALLING else: coil_type = COIL_NORMAL coil = LD_Coil(self, coil_type, instance["name"], instance["id"]) @@ -871,6 +879,7 @@ self.CreateWires(connector, instance["connector"]["links"], ids) else: connectors = {"inputs" : [], "outputs" : []} + executionControl = False for input in instance["connectors"]["inputs"]: if input["negated"]: connectors["inputs"].append((input["name"], None, "negated")) @@ -885,10 +894,16 @@ connectors["outputs"].append((output["name"], None, output["edge"])) else: connectors["outputs"].append((output["name"], None, "none")) - if instance["name"] != None: - block = FBD_Block(self, instance["type"], instance["name"], instance["id"], len(instance["connectors"]["inputs"]), connectors=connectors, executionOrder=instance["executionOrder"]) - else: - block = FBD_Block(self, instance["type"], "", instance["id"], len(instance["connectors"]["inputs"]), connectors=connectors, executionOrder=instance["executionOrder"]) + if connectors["inputs"][0][0] == "EN" and connectors["outputs"][0][0] == "ENO": + connectors["inputs"].pop(0) + connectors["outputs"].pop(0) + executionControl = True + if instance["name"] is None: + instance["name"] = "" + block = FBD_Block(self, instance["type"], instance["name"], + instance["id"], len(connectors["inputs"]), + connectors=connectors, executionControl=executionControl, + executionOrder=instance["executionOrder"]) block.SetPosition(instance["x"], instance["y"]) block.SetSize(instance["width"], instance["height"]) self.AddBlock(block) @@ -1563,10 +1578,11 @@ if dialog.ShowModal() == wx.ID_OK: id = self.GetNewId() values = dialog.GetValues() - if "name" in values: - block = FBD_Block(self, values["type"], values["name"], id, values["extension"], values["inputs"]) - else: - block = FBD_Block(self, values["type"], "", id, values["extension"], values["inputs"]) + values.setdefault("name", "") + block = FBD_Block(self, values["type"], values["name"], id, + values["extension"], values["inputs"], + executionControl = values["executionControl"], + executionOrder = values["executionOrder"]) block.SetPosition(bbox.x, bbox.y) block.SetSize(*self.GetScaledSize(values["width"], values["height"])) self.AddBlock(block) @@ -1861,8 +1877,12 @@ variable_names.remove(block.GetName()) dialog.SetPouElementNames(variable_names) dialog.SetMinBlockSize(block.GetSize()) - old_values = {"name" : block.GetName(), "type" : block.GetType(), "inputs" : block.GetInputTypes(), - "executionOrder" : block.GetExecutionOrder(), "extension" : block.GetExtension()} + old_values = {"name" : block.GetName(), + "type" : block.GetType(), + "extension" : block.GetExtension(), + "inputs" : block.GetInputTypes(), + "executionControl" : block.GetExecutionControl(), + "executionOrder" : block.GetExecutionOrder()} dialog.SetValues(old_values) if dialog.ShowModal() == wx.ID_OK: new_values = dialog.GetValues() @@ -1872,18 +1892,19 @@ else: block.SetName("") block.SetSize(*self.GetScaledSize(new_values["width"], new_values["height"])) - block.SetType(new_values["type"], new_values["extension"]) + block.SetType(new_values["type"], new_values["extension"], executionControl = new_values["executionControl"]) block.SetExecutionOrder(new_values["executionOrder"]) rect = rect.Union(block.GetRedrawRect()) self.RefreshBlockModel(block) - if old_values["executionOrder"] != new_values["executionOrder"]: - self.RefreshView() self.RefreshBuffer() self.RefreshScrollBars() self.RefreshVisibleElements() self.ParentWindow.RefreshVariablePanel(self.TagName) self.ParentWindow.RefreshInstancesTree() - block.Refresh(rect) + if old_values["executionOrder"] != new_values["executionOrder"]: + self.RefreshView() + else: + block.Refresh(rect) dialog.Destroy() def EditVariableContent(self, variable): diff -r 5508af39d1f7 -r 34eff05909b0 graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Thu Sep 11 14:55:49 2008 +0200 +++ b/graphics/FBD_Objects.py Fri Sep 12 16:23:40 2008 +0200 @@ -38,10 +38,11 @@ class FBD_Block(Graphic_Element): # Create a new block - def __init__(self, parent, type, name, id = None, extension = 0, inputs = None, connectors = {}, executionOrder = 0): + def __init__(self, parent, type, name, id = None, extension = 0, inputs = None, connectors = {}, executionControl = False, executionOrder = 0): Graphic_Element.__init__(self, parent) self.Type = None self.Extension = None + self.ExecutionControl = False self.Id = id self.SetName(name) self.SetExecutionOrder(executionOrder) @@ -49,7 +50,7 @@ self.Outputs = [] self.Colour = wx.BLACK self.Pen = wx.BLACK_PEN - self.SetType(type, extension, inputs, connectors) + self.SetType(type, extension, inputs, connectors, executionControl) self.Errors = {} # Make a clone of this FBD_Block @@ -174,7 +175,7 @@ return None def GetInputTypes(self): - return tuple([input.GetType(True) for input in self.Inputs]) + return tuple([input.GetType(True) for input in self.Inputs if input.GetName() != "EN"]) def SetOutputValues(self, values): for output in self.Outputs: @@ -213,12 +214,13 @@ return None # Changes the block type - def SetType(self, type, extension, inputs = None, connectors = {}): - if type != self.Type or self.Extension != extension: + def SetType(self, type, extension, inputs = None, connectors = {}, executionControl = False): + if type != self.Type or self.Extension != extension or executionControl != self.ExecutionControl: if type != self.Type: self.Type = type self.TypeSize = self.Parent.GetTextExtent(self.Type) self.Extension = extension + self.ExecutionControl = executionControl # Find the block definition from type given and create the corresponding # inputs and outputs blocktype = self.Parent.GetBlockType(type, inputs) @@ -241,6 +243,9 @@ outputs = connectors["outputs"] else: outputs = [] + if self.ExecutionControl: + inputs.insert(0, ("EN","BOOL","none")) + outputs.insert(0, ("ENO","BOOL","none")) self.Pen = wx.Pen(self.Colour) self.Clean() # Extract the inputs properties and create the corresponding connector @@ -295,6 +300,10 @@ def GetExecutionOrder(self): return self.ExecutionOrder + # Returs the execution order + def GetExecutionControl(self): + return self.ExecutionControl + # Refresh the block minimum size def RefreshMinSize(self): # Calculate the inputs maximum width diff -r 5508af39d1f7 -r 34eff05909b0 graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Thu Sep 11 14:55:49 2008 +0200 +++ b/graphics/GraphicCommons.py Fri Sep 12 16:23:40 2008 +0200 @@ -66,7 +66,7 @@ [CONNECTOR, CONTINUATION] = range(2) [LEFTRAIL, RIGHTRAIL] = range(2) [CONTACT_NORMAL, CONTACT_REVERSE, CONTACT_RISING, CONTACT_FALLING] = range(4) -[COIL_NORMAL, COIL_REVERSE, COIL_SET, COIL_RESET] = range(4) +[COIL_NORMAL, COIL_REVERSE, COIL_SET, COIL_RESET, COIL_RISING, COIL_FALLING] = range(6) [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE, SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE] = range(4) # Constants for defining the type of dragging that has been selected diff -r 5508af39d1f7 -r 34eff05909b0 graphics/LD_Objects.py --- a/graphics/LD_Objects.py Thu Sep 11 14:55:49 2008 +0200 +++ b/graphics/LD_Objects.py Fri Sep 12 16:23:40 2008 +0200 @@ -764,6 +764,10 @@ typetext = "S" elif self.Type == COIL_RESET: typetext = "R" + elif self.Type == COIL_RISING: + typetext = "P" + elif self.Type == COIL_FALLING: + typetext = "N" if typetext != "": self.TypeSize = self.Parent.GetTextExtent(typetext) else: @@ -903,6 +907,10 @@ typetext = "S" elif self.Type == COIL_RESET: typetext = "R" + elif self.Type == COIL_RISING: + typetext = "P" + elif self.Type == COIL_FALLING: + typetext = "N" if getattr(dc, "printing", False) and not isinstance(dc, wx.PostScriptDC): # Draw an clipped ellipse for representing the coil