# HG changeset patch # User lbessard # Date 1170870212 -3600 # Node ID 93bc4c2cf376523a5826e1ed402c439d3e29996d # Parent e9d01d824086dfdf3a2c81edcf1248cfd6e68151 PLCGenerator finished Code for generated classes from xsd and specific code for plcopen separated Bug in SFC corrected diff -r e9d01d824086 -r 93bc4c2cf376 FBDViewer.py --- a/FBDViewer.py Thu Feb 01 18:09:34 2007 +0100 +++ b/FBDViewer.py Wed Feb 07 18:43:32 2007 +0100 @@ -293,8 +293,8 @@ connector = variable.GetConnector() wires.extend([wire[0] for wire in connector.GetWires()]) variable.Clean() - self.Blocks.remove(self.SelectedElement) - self.Elements.remove(self.SelectedElement) + self.Blocks.remove(variable) + self.Elements.remove(variable) self.Controler.RemoveCurrentElementEditingInstance(variable.GetId()) for wire in wires: wire.RefreshModel() @@ -306,26 +306,47 @@ connector = connection.GetConnector() wires.extend([wire[0] for wire in connector.GetWires()]) connection.Clean() - self.Blocks.remove(self.SelectedElement) - self.Elements.remove(self.SelectedElement) + self.Blocks.remove(connection) + self.Elements.remove(connection) self.Controler.RemoveCurrentElementEditingInstance(connection.GetId()) for wire in wires: wire.RefreshModel() self.Parent.RefreshProjectTree() def DeleteComment(self, comment): - self.Elements.remove(self.SelectedElement) + self.Elements.remove(comment) self.Controler.RemoveCurrentElementEditingInstance(comment.GetId()) def DeleteWire(self, wire): connected = wire.GetConnected() self.SelectedElement.Clean() - self.Wires.remove(self.SelectedElement) - self.Elements.remove(self.SelectedElement) + self.Wires.remove(wire) + self.Elements.remove(wire) for connector in connected: connector.RefreshParentBlock() #------------------------------------------------------------------------------- +# Edit element content functions +#------------------------------------------------------------------------------- + + def EditBlockContent(self, block): + dialog = BlockPropertiesDialog(self.Parent) + dialog.SetBlockList(self.Controler.GetBlockTypes()) + dialog.SetMinBlockSize(block.GetSize()) + values = {"name" : block.GetName(), "type" : block.GetType()} + values["extension"] = block.GetExtension() + dialog.SetValues(values) + if dialog.ShowModal() == wxID_OK: + values = dialog.GetValues() + if "name" in values: + block.SetName(values["name"]) + block.SetExtension(values["extension"]) + block.SetSize(values["width"], values["height"]) + block.SetType(values["type"]) + self.Refresh() + dialog.Destroy() + +#------------------------------------------------------------------------------- # Create New Block Dialog #------------------------------------------------------------------------------- @@ -419,6 +440,19 @@ EVT_PAINT(self, self.OnPaint) EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK) + def FindTreeItem(self, root, name): + if root.IsOk(): + if self.TypeTree.GetItemText(root) == name: + return root + else: + item, root_cookie = self.TypeTree.GetFirstChild(root) + while item.IsOk(): + result = self.FindTreeItem(item, name) + if result: + return result + item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie) + return None + def OnOK(self, event): error = [] selected = self.TypeTree.GetSelection() @@ -443,6 +477,18 @@ def SetMinBlockSize(self, size): self.MinBlockSize = size + def SetValues(self, values): + for name, value in values.items(): + if name == "type": + item = self.FindTreeItem(self.TypeTree.GetRootItem(), value) + if item: + self.TypeTree.SelectItem(item) + elif name == "name": + self.Name.SetValue(value) + elif name == "extension": + self.Inputs.SetValue(value) + self.RefreshPreview() + def GetValues(self): values = {} values["type"] = self.TypeTree.GetItemText(self.TypeTree.GetSelection()) @@ -561,7 +607,7 @@ self.staticText3 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, label='Preview:', name='staticText3', parent=self.MainPanel, - pos=wx.Point(24, 72), size=wx.Size(100, 17), style=0) + pos=wx.Point(24, 78), size=wx.Size(100, 17), style=0) self.Class = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGCLASS, name='Class', parent=self.MainPanel, pos=wx.Point(24, 48), diff -r e9d01d824086 -r 93bc4c2cf376 LDViewer.py --- a/LDViewer.py Thu Feb 01 18:09:34 2007 +0100 +++ b/LDViewer.py Wed Feb 07 18:43:32 2007 +0100 @@ -977,7 +977,7 @@ vars = self.Controler.GetCurrentElementEditingInterfaceVars() if vars: for var in vars: - if var["Type"] != "Output" and var["Value"] == "BOOL": + if var["Class"] != "Output" and var["Type"] == "BOOL": varlist.append(var["Name"]) dialog.SetVariables(varlist) dialog.SetValues({"name":contact.GetName(),"type":contact.GetType()}) @@ -995,7 +995,7 @@ vars = self.Controler.GetCurrentElementEditingInterfaceVars() if vars: for var in vars: - if var["Type"] != "Input" and var["Value"] == "BOOL": + if var["Class"] != "Input" and var["Type"] == "BOOL": varlist.append(var["Name"]) returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType() if returntype == "BOOL": @@ -1097,10 +1097,10 @@ def __init__(self, parent, type): self.Type = type if type == "contact": - self._init_ctrls(parent, "Edit Contact Values", ['Normal','Reverse','Rising Edge','Falling Edge']) + self._init_ctrls(parent, "Edit Contact Values", ['Normal','Negate','Rising Edge','Falling Edge']) self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "") elif type == "coil": - self._init_ctrls(parent, "Edit Coil Values", ['Normal','Reverse','Set','Reset']) + self._init_ctrls(parent, "Edit Coil Values", ['Normal','Negate','Set','Reset']) self.Element = LD_Coil(self.Preview, COIL_NORMAL, "") self.Element.SetPosition((150 - LD_ELEMENT_SIZE[0]) / 2, (150 - LD_ELEMENT_SIZE[1]) / 2) diff -r e9d01d824086 -r 93bc4c2cf376 PLCControler.py --- a/PLCControler.py Thu Feb 01 18:09:34 2007 +0100 +++ b/PLCControler.py Wed Feb 07 18:43:32 2007 +0100 @@ -34,6 +34,28 @@ [ITEM_UNEDITABLE, ITEM_PROJECT, ITEM_POU, ITEM_CLASS, ITEM_VARIABLE, ITEM_TRANSITION, ITEM_ACTION, ITEM_CONFIGURATION, ITEM_RESOURCE] = range(9) +""" +pyxsval is not complete and the parts that are not supported print some error +reports. This class is used for not displaying them +""" +class HolePseudoFile: + """ Base class for file like objects to facilitate StdOut for the Shell.""" + def __init__(self, output = None): + if output is None: output = [] + self.output = output + + def writelines(self, l): + map(self.write, l) + + def write(self, s): + pass + + def flush(self): + pass + + def isatty(self): + return false + #------------------------------------------------------------------------------- # Undo Buffer for PLCOpenEditor #------------------------------------------------------------------------------- @@ -1755,7 +1777,7 @@ def OpenXMLFile(self, filepath): if sys: - sys.stdout = plcopen.HolePseudoFile() + sys.stdout = HolePseudoFile() tree = pyxsval.parseAndValidate(filepath, "plcopen/TC6_XML_V10_B.xsd") if sys: sys.stdout = sys.__stdout__ @@ -1781,7 +1803,7 @@ text += self.Project.generateXMLText("project", 0, extras) if sys: - sys.stdout = plcopen.HolePseudoFile() + sys.stdout = HolePseudoFile() pyxsval.parseAndValidateString(text, open("plcopen/TC6_XML_V10_B.xsd","r").read()) if sys: sys.stdout = sys.__stdout__ diff -r e9d01d824086 -r 93bc4c2cf376 PLCGenerator.py --- a/PLCGenerator.py Thu Feb 01 18:09:34 2007 +0100 +++ b/PLCGenerator.py Wed Feb 07 18:43:32 2007 +0100 @@ -41,7 +41,10 @@ for i in xrange(spaces, nb_spaces): indent += " " for line in lines: - compute += "%s%s\n"%(indent, line) + if line != "": + compute += "%s%s\n"%(indent, line) + else: + compute += "\n" return compute """ @@ -175,6 +178,24 @@ else: return variable + def ExtractDivergenceInput(self, divergence, pou): + connectionPointIn = divergence.getConnectionPointIn() + if connectionPointIn: + connections = connectionPointIn.getConnections() + if len(connections) == 1: + instanceLocalId = connections[0].getRefLocalId() + return pou.body.getContentInstance(instanceLocalId) + return None + + def ExtractConvergenceInputs(self, convergence, pou): + instances = [] + for connectionPointIn in convergence.getConnectionPointIn(): + connections = connectionPointIn.getConnections() + if len(connections) == 1: + instanceLocalId = connections[0].getRefLocalId() + instances.append(pou.body.getContentInstance(instanceLocalId)) + return instances + def GenerateSFCStep(self, step, pou): step_name = step.getName() if step_name not in self.SFCNetworks["Steps"].keys(): @@ -188,26 +209,18 @@ instanceLocalId = connections[0].getRefLocalId() instance = pou.body.getContentInstance(instanceLocalId) if isinstance(instance, plcopen.transition): - self.GenerateSFCTransition(instance, pou) instances.append(instance) elif isinstance(instance, plcopen.selectionConvergence): - for connectionPointIn in instance.getConnectionPointIn(): - divergence_connections = connectionPointIn.getConnections() - if len(divergence_connections) == 1: - transitionLocalId = connections[0].getRefLocalId() - transition = pou.body.getContentInstance(transitionLocalId) - self.GenerateSFCTransition(transition, pou) + instances.extend(self.ExtractConvergenceInputs(instance, pou)) + elif isinstance(instance, plcopen.simultaneousDivergence): + transition = self.ExtractDivergenceInput(instance, pou) + if transition: + if isinstance(transition, plcopen.transition): instances.append(transition) - elif isinstance(instance, plcopen.simultaneousDivergence): - connectionPointIn = instance.getConnectionPointIn() - if connectionPointIn: - divergence_connections = connectionPointIn.getConnections() - if len(divergence_connections) == 1: - transitionLocalId = connections[0].getRefLocalId() - transition = pou.body.getContentInstance(transitionLocalId) - self.GenerateSFCTransition(transition, pou) - instances.append(transition) + elif isinstance(transition, plcopen.selectionConvergence): + instances.extend(self.ExtractConvergenceInputs(transition, pou)) for instance in instances: + self.GenerateSFCTransition(instance, pou) if instance in self.SFCNetworks["Transitions"].keys(): self.SFCNetworks["Transitions"][instance]["to"].append(step_name) self.SFCNetworks["Steps"][step_name] = step_infos @@ -221,26 +234,18 @@ instanceLocalId = connections[0].getRefLocalId() instance = pou.body.getContentInstance(instanceLocalId) if isinstance(instance, plcopen.transition): - self.GenerateSFCTransition(instance, pou) instances.append(instance) elif isinstance(instance, plcopen.selectionConvergence): - for connectionPointIn in instance.getConnectionPointIn(): - divergence_connections = connectionPointIn.getConnections() - if len(divergence_connections) == 1: - transitionLocalId = divergence_connections[0].getRefLocalId() - transition = pou.body.getContentInstance(transitionLocalId) - self.GenerateSFCTransition(transition, pou) + instances.extend(self.ExtractConvergenceInputs(instance, pou)) + elif isinstance(instance, plcopen.simultaneousDivergence): + transition = self.ExtractDivergenceInput(instance, pou) + if transition: + if isinstance(transition, plcopen.transition): instances.append(transition) - elif isinstance(instance, plcopen.simultaneousDivergence): - connectionPointIn = instance.getConnectionPointIn() - if connectionPointIn: - divergence_connections = connectionPointIn.getConnections() - if len(divergence_connections) == 1: - transitionLocalId = connections[0].getRefLocalId() - transition = pou.body.getContentInstance(transitionLocalId) - self.GenerateSFCTransition(transition, pou) - instances.append(transition) + elif isinstance(transition, plcopen.selectionConvergence): + instances.extend(self.ExtractConvergenceInputs(transition, pou)) for instance in instances: + self.GenerateSFCTransition(instance, pou) if instance in self.SFCNetworks["Transitions"].keys(): self.SFCNetworks["Transitions"][instance]["to"].append(jump_target) @@ -297,16 +302,16 @@ instanceLocalId = connections[0].getRefLocalId() instance = pou.body.getContentInstance(instanceLocalId) if isinstance(instance, plcopen.step): - self.GenerateSFCStep(instance, pou) - steps.append(instance.getName()) + steps.append(instance) elif isinstance(instance, plcopen.selectionDivergence): - divergence_connections = instance.connectionPointIn.getConnections() - if len(divergence_connections) == 1: - stepLocalId = divergence_connections[0].getRefLocalId() - divergence_instance = pou.body.getContentInstance(stepLocalId) - if isinstance(divergence_instance, plcopen.step): - self.GenerateSFCStep(divergence_instance, pou) - steps.append(divergence_instance.getName()) + step = self.ExtractDivergenceInput(instance, pou) + if step: + if isinstance(step, plcopen.step): + steps.append(step) + elif isinstance(step, plcopen.simultaneousConvergence): + steps.extend(self.ExtractConvergenceInputs(step, pou)) + elif isinstance(instance, plcopen.simultaneousConvergence): + steps.extend(self.ExtractConvergenceInputs(instance, pou)) transition_infos = {"from": [], "to" : []} transitionValues = transition.getConditionContent() if transitionValues["type"] == "inline": @@ -316,9 +321,9 @@ transitionType = transitionContent.getBodyType() transitionBody = transitionContent.getBody() if transitionType == "IL": - transition_infos["content"] = ":\n%s\n"%ReIndentText(transitionBody.getText(), 4) + transition_infos["content"] = ":\n%s"%ReIndentText(transitionBody.getText(), 4) elif transitionType == "ST": - transition_infos["content"] = "\n%s\n"%ReIndentText(transitionBody.getText(), 4) + transition_infos["content"] = "\n%s"%ReIndentText(transitionBody.getText(), 4) elif conditionType == "FBD": for instance in transitionBody.getContentInstances(): if isinstance(instance, plcopen.outVariable): @@ -332,7 +337,9 @@ paths = self.GenerateLDPaths(instance, conditionBody) expression = self.ComputeLDExpression(paths, True) transition_infos["content"] = "\n := %s;\n"%expression - for step_name in steps: + for step in steps: + self.GenerateSFCStep(step, pou) + step_name = step.getName() if step_name in self.SFCNetworks["Steps"].keys(): transition_infos["from"].append(step_name) self.SFCNetworks["Steps"][step_name]["transitions"].append(transition) diff -r e9d01d824086 -r 93bc4c2cf376 PLCOpenEditor.py --- a/PLCOpenEditor.py Thu Feb 01 18:09:34 2007 +0100 +++ b/PLCOpenEditor.py Wed Feb 07 18:43:32 2007 +0100 @@ -445,6 +445,8 @@ self.DefaultToolBar = wxToolBar(id=wxID_PLCOPENEDITORDEFAULTTOOLBAR, name='DefaultToolBar', parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0), style=wxTB_HORIZONTAL | wxNO_BORDER) + self.Bind(wx.EVT_LEFT_DCLICK, self.OnDefaultToolDCLick, + id=wxID_PLCOPENEDITORDEFAULTTOOLBAR) self.SFCToolBar = wxToolBar(id=wxID_PLCOPENEDITORSFCTOOLBAR, name='SFCToolBar', parent=parent, pos=wx.Point(0, 27), size=wx.Size(0, 0), @@ -477,6 +479,10 @@ self.RefreshEditMenu() self.RefreshToolBar() + def OnDefaultToolDCLick(self, event): + print "Default ToolBar DClick" + event.Skip() + def RefreshFileMenu(self): if self.Controler.HasOpenedProject(): if self.TabsOpened.GetPageCount() > 0: diff -r e9d01d824086 -r 93bc4c2cf376 SFCViewer.py --- a/SFCViewer.py Thu Feb 01 18:09:34 2007 +0100 +++ b/SFCViewer.py Wed Feb 07 18:43:32 2007 +0100 @@ -75,7 +75,7 @@ wire.SetPoints([wxPoint(pos.x, pos.y + SFC_WIRE_MIN_SIZE), wxPoint(pos.x, pos.y)]) if isinstance(next_block, SFC_Divergence): next_block.RefreshPosition() - next_block.RefreshModel() + transition.RefreshOutputModel(True) return transition def RemoveTransition(self, transition): @@ -133,7 +133,7 @@ wire.SetPoints([wxPoint(pos.x, pos.y + SFC_WIRE_MIN_SIZE), wxPoint(pos.x, pos.y)]) if isinstance(next_block, SFC_Divergence): next_block.RefreshPosition() - next_block.RefreshModel() + step.RefreshOutputModel(True) return step def RemoveStep(self, step): @@ -795,7 +795,7 @@ wire.SetPoints([wxPoint(pos.x, pos.y + wire_size), wxPoint(pos.x, pos.y)]) if isinstance(next_block, SFC_Divergence): next_block.RefreshPosition() - next_block.RefreshModel() + previous_block.RefreshOutputModel(True) else: if isinstance(previous_block, SFC_Step): previous_block.RemoveOutput() @@ -910,7 +910,7 @@ wxPoint(previous_pos.x, previous_pos.y)]) if isinstance(next_block, SFC_Divergence): next_block.RefreshPosition() - next_block.RefreshModel() + previous_block.RefreshOutputModel(True) elif divergence.GetBranchNumber() == 1: wires = connectors["inputs"][0].GetWires() if len(wires) != 1: @@ -943,7 +943,7 @@ wxPoint(previous_pos.x, previous_pos.y)]) if isinstance(next_block, SFC_Divergence): next_block.RefreshPosition() - next_block.RefreshModel() + previous_block.RefreshOutputModel(True) self.Parent.RefreshProjectTree() def DeleteJump(self, jump): diff -r e9d01d824086 -r 93bc4c2cf376 Viewer.py --- a/Viewer.py Thu Feb 01 18:09:34 2007 +0100 +++ b/Viewer.py Wed Feb 07 18:43:32 2007 +0100 @@ -873,6 +873,7 @@ # Indentation size self.SetTabWidth(2) + self.SetUseTabs(0) self.Keywords = [] self.Variables = [] diff -r e9d01d824086 -r 93bc4c2cf376 examples/example.xml --- a/examples/example.xml Thu Feb 01 18:09:34 2007 +0100 +++ b/examples/example.xml Wed Feb 07 18:43:32 2007 +0100 @@ -451,9 +451,9 @@ IF IN1 THEN - IN2 := 1; + IN2 := 1; ELSE - IN3 := 1; + IN3 := 1; END_IF; @@ -506,7 +506,7 @@ - + @@ -519,10 +519,10 @@ - - - - + + + + @@ -544,12 +544,12 @@ - + - - - + + + @@ -557,12 +557,12 @@ - + - - + + @@ -575,12 +575,12 @@ - + - - + + @@ -588,12 +588,12 @@ - + - - + + @@ -606,12 +606,12 @@ - + - - + + @@ -622,12 +622,12 @@ - + - - - + + + @@ -640,12 +640,12 @@ - + - - + + @@ -663,12 +663,12 @@ - + - - + + @@ -681,12 +681,12 @@ - + - - + + @@ -698,52 +698,101 @@ - - + + - - - - - - + + + + + + - - - - - - + + + + + + - + - - + + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -797,16 +846,16 @@ IF Collision THEN - Speed := 0; - Brakes := ON; + Speed := 0; + Brakes := ON; END_IF; IF (Gate = CLOSED) AND - (Pump = ON) AND (Temp > 200.0) THEN - Control_State := Active; + (Pump = ON) AND (Temp > 200.0) THEN + Control_State := Active; ELSE - Control_State := Hold; - PumpSpeed := 10.0; + Control_State := Hold; + PumpSpeed := 10.0; END_IF; diff -r e9d01d824086 -r 93bc4c2cf376 graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Thu Feb 01 18:09:34 2007 +0100 +++ b/graphics/FBD_Objects.py Wed Feb 07 18:43:32 2007 +0100 @@ -42,21 +42,12 @@ # Create a new block def __init__(self, parent, type, name, id = None, extension = 0, inputs = [], outputs = []): Graphic_Element.__init__(self, parent) - self.Type = type self.Name = name self.Id = id - # Find the block definition from type given and create the corresponding - # inputs and outputs - blocktype = GetBlockType(type) - if blocktype: - inputs = [input for input in blocktype["inputs"]] - outputs = [output for output in blocktype["outputs"]] - if blocktype["extensible"]: - start = int(inputs[-1][0].replace("IN", "")) - for i in xrange(extension - len(blocktype["inputs"])): - start += 1 - inputs.append(("IN%d"%start, inputs[-1][1], input[-1][2])) - self.SetConnectors(inputs, outputs) + self.Extension = extension + self.Inputs = [] + self.Outputs = [] + self.SetType(type) # Destructor def __del__(self): @@ -70,9 +61,9 @@ # Unconnect all inputs and outputs def Clean(self): for input in self.Inputs: - input.UnConnect() - for output in self.Outputs: - output.UnConnect() + input.UnConnect(delete = True) + for output in self.Outputs: + output.UnConnect(delete = True) # Refresh the block bounding box def RefreshBoundingBox(self): @@ -144,6 +135,22 @@ return output return None + # Changes the block type + def SetType(self, type): + self.Type = type + # Find the block definition from type given and create the corresponding + # inputs and outputs + blocktype = GetBlockType(type) + if blocktype: + inputs = [input for input in blocktype["inputs"]] + outputs = [output for output in blocktype["outputs"]] + if blocktype["extensible"]: + start = int(inputs[-1][0].replace("IN", "")) + for i in xrange(self.Extension - len(blocktype["inputs"])): + start += 1 + inputs.append(("IN%d"%start, inputs[-1][1], input[-1][2])) + self.SetConnectors(inputs, outputs) + # Returns the block type def GetType(self): return self.Type @@ -156,6 +163,14 @@ def GetName(self): return self.Name + # Changes the extension name + def SetExtension(self, extension): + self.Extension = extension + + # Returs the extension name + def GetExtension(self): + return self.Extension + # Returns the block minimum size def GetMinSize(self): dc = wxClientDC(self.Parent) @@ -176,6 +191,7 @@ # Changes the block connectors def SetConnectors(self, inputs, outputs): + self.Clean() # Extract the inputs properties and create the corresponding connector self.Inputs = [] for input_name, input_type, input_modifier in inputs: @@ -194,6 +210,7 @@ elif output_modifier != "none": connector.SetEdge(output_modifier) self.Outputs.append(connector) + self.RefreshConnectors() self.RefreshBoundingBox() # Changes the negated property of the connector handled @@ -210,6 +227,11 @@ handle.SetEdge(edge) self.RefreshModel(False) + # Method called when a LeftDClick event have been generated + def OnLeftDClick(self, event, scaling): + # Edit the step properties + self.Parent.EditBlockContent(self) + # Method called when a RightUp event have been generated def OnRightUp(self, event, scaling): pos = GetScaledEventPosition(event, scaling) diff -r e9d01d824086 -r 93bc4c2cf376 graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Thu Feb 01 18:09:34 2007 +0100 +++ b/graphics/GraphicCommons.py Wed Feb 07 18:43:32 2007 +0100 @@ -701,7 +701,7 @@ return None # Unconnect a wire or all wires connected to the connector - def UnConnect(self, wire = None, unconnect = True): + def UnConnect(self, wire = None, unconnect = True, delete = False): i = 0 found = False while i < len(self.Wires) and not found: @@ -709,9 +709,9 @@ # If Unconnect haven't been called from a wire, disconnect the connector in the wire if unconnect: if self.Wires[i][1] == 0: - self.Wires[i][0].UnConnectStartPoint() + self.Wires[i][0].UnConnectStartPoint(delete) else: - self.Wires[i][0].UnConnectEndPoint() + self.Wires[i][0].UnConnectEndPoint(delete) # Remove wire from connected if wire: self.Wires.pop(i) @@ -1336,9 +1336,12 @@ self.StartConnected = connector # Unconnects wire start point - def UnConnectStartPoint(self): + def UnConnectStartPoint(self, delete = False): self.StartConnected.UnConnect(self, False) - self.StartConnected = None + if delete: + self.Delete() + else: + self.StartConnected = None # Moves the wire end point and update the wire points def MoveEndPoint(self, point): @@ -1365,9 +1368,12 @@ self.EndConnected = connector # Unconnects wire end point - def UnConnectEndPoint(self): + def UnConnectEndPoint(self, delete = False): self.EndConnected.UnConnect(self, False) - self.EndConnected = None + if delete: + self.Delete() + else: + self.EndConnected = None # Moves the wire segment given by its index def MoveSegment(self, idx, movex, movey): diff -r e9d01d824086 -r 93bc4c2cf376 graphics/SFC_Objects.py --- a/graphics/SFC_Objects.py Thu Feb 01 18:09:34 2007 +0100 +++ b/graphics/SFC_Objects.py Wed Feb 07 18:43:32 2007 +0100 @@ -446,10 +446,10 @@ else: text_width, text_height = dc.GetTextExtent("Transition") # Calculate the bounding box size - bbx_width = self.Size[0] + CONNECTOR_SIZE + 2 + text_width - bbx_y = self.Pos.y - max(0, (text_height - self.Size[1]) / 2) + bbx_width = self.Size[0] + 5 + text_width + bbx_y = self.Pos.y - max(0, (text_height - 5 - self.Size[1]) / 2) bbx_height = max(self.Size[1], text_height) - self.BoundingBox = wxRect(self.Pos.x, bbx_y, bbx_width + 1, bbx_height + 1) + self.BoundingBox = wxRect(self.Pos.x, bbx_y, bbx_width + 1, bbx_height - 4) # Returns the connector connected to input def GetPreviousConnector(self): @@ -624,7 +624,7 @@ else: text_width, text_height = dc.GetTextExtent("Transition") condition = "Transition" - dc.DrawText(condition, self.Pos.x + self.Size[0] + CONNECTOR_SIZE + 2, + dc.DrawText(condition, self.Pos.x + self.Size[0] + 5, self.Pos.y + (self.Size[1] - text_height) / 2) # Draw input and output connectors self.Input.Draw(dc) @@ -734,11 +734,11 @@ # Refresh the divergence bounding box def RefreshBoundingBox(self): if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]: - self.BoundingBox = wxRect(self.Pos.x, self.Pos.y - CONNECTOR_SIZE, - self.Size[0] + 1, self.Size[1] + CONNECTOR_SIZE * 2 + 1) + self.BoundingBox = wxRect(self.Pos.x, self.Pos.y - 2, + self.Size[0] + 1, self.Size[1] + 5) elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]: - self.BoundingBox = wxRect(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y - CONNECTOR_SIZE, - self.Size[0] + 2 * SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Size[1] + CONNECTOR_SIZE * 2 + 1) + self.BoundingBox = wxRect(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y - 2, + self.Size[0] + 2 * SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Size[1] + 5) # Refresh the position of wires connected to divergence def RefreshConnected(self, exclude = []): @@ -1212,7 +1212,7 @@ width, height = dc.GetTextExtent(action["qualifier"]) self.ColSize[0] = max(self.ColSize[0], width + 10) if "duration" in action: - width, height = dc.GetTextExtent("T#%s"%action["duration"]) + width, height = dc.GetTextExtent(action["duration"]) self.ColSize[0] = max(self.ColSize[0], width + 10) width, height = dc.GetTextExtent(action["value"]) self.ColSize[1] = max(self.ColSize[1], width + 10) @@ -1220,7 +1220,7 @@ width, height = dc.GetTextExtent(action["indicator"]) self.ColSize[2] = max(self.ColSize[2], width + 10) self.Size = wxSize(max(self.ColSize[0] + self.ColSize[1] + self.ColSize[2], - self.Size[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1]) + SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1]) self.RefreshBoundingBox() if self.Input: wires = self.Input.GetWires() @@ -1235,7 +1235,8 @@ # Returns the action block minimum size def GetMinSize(self): - return SFC_ACTION_MIN_SIZE[0], len(self.Actions) * SFC_ACTION_MIN_SIZE[1] + return max(self.ColSize[0] + self.ColSize[1] + self.ColSize[2], + SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1] # Method called when a LeftDClick event have been generated def OnLeftDClick(self, event, scaling): diff -r e9d01d824086 -r 93bc4c2cf376 plcopen/__init__.py --- a/plcopen/__init__.py Thu Feb 01 18:09:34 2007 +0100 +++ b/plcopen/__init__.py Wed Feb 07 18:43:32 2007 +0100 @@ -9,7 +9,7 @@ #See COPYING file for copyrights details. # #This library is free software; you can redistribute it and/or -#modify it under the terms of the GNU Lesser General Public +#modify it under the terms of the GNU General Public #License as published by the Free Software Foundation; either #version 2.1 of the License, or (at your option) any later version. # @@ -18,7 +18,7 @@ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #Lesser General Public License for more details. # -#You should have received a copy of the GNU Lesser General Public +#You should have received a copy of the GNU General Public #License along with this library; if not, write to the Free Software #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -31,7 +31,6 @@ for typename, typ in plcopen.PLCOpenTypes.items(): plcopen.__dict__[typename] = typ from plcopen import VarOrder -from plcopen import HolePseudoFile from structures import * from docpdf import * \ No newline at end of file diff -r e9d01d824086 -r 93bc4c2cf376 plcopen/plcopen.py --- a/plcopen/plcopen.py Thu Feb 01 18:09:34 2007 +0100 +++ b/plcopen/plcopen.py Wed Feb 07 18:43:32 2007 +0100 @@ -9,7 +9,7 @@ #See COPYING file for copyrights details. # #This library is free software; you can redistribute it and/or -#modify it under the terms of the GNU Lesser General Public +#modify it under the terms of the GNU General Public #License as published by the Free Software Foundation; either #version 2.1 of the License, or (at your option) any later version. # @@ -18,23 +18,11 @@ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #Lesser General Public License for more details. # -#You should have received a copy of the GNU Lesser General Public +#You should have received a copy of the GNU General Public #License along with this library; if not, write to the Free Software #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -from xml.parsers import expat -from minixsv import pyxsval -from random import * - -from types import * -from datetime import * - -import sys,re - -classes = {} -TimeType = time(0,0,0).__class__ -DateType = date(1,1,1).__class__ -DateTimeType = datetime(1,1,1,0,0,0).__class__ +from xmlclass import * """ Dictionary that makes the relation between var names in plcopen and displayed values @@ -49,1742 +37,1010 @@ VarOrder = ["Local","Temp","Input","Output","InOut","External","Global","Access"] """ -Regular expression models for extracting dates and times from a string -""" -time_model = re.compile('([0-9]{2}):([0-9]{2}):([0-9]{2})') -date_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})') -datetime_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})[ T]([0-9]{2}):([0-9]{2}):([0-9]{2})') - -""" Define which action qualifier must be associated with a duration """ QualifierList = {"N" : False, "R" : False, "S" : False, "L" : True, "D" : True, "P" : False, "P0" : False, "P1" : False, "SD" : True, "DS" : True, "SL" : True} -""" -pyxsval is not complete and the parts that are not supported print some error -reports. This class is used for not displaying them -""" -class HolePseudoFile: - """ Base class for file like objects to facilitate StdOut for the Shell.""" - def __init__(self, output = None): - if output is None: output = [] - self.output = output - - def writelines(self, l): - map(self.write, l) - - def write(self, s): - pass - - def flush(self): - pass - - def isatty(self): - return false - -""" -This function calculates the number of whitespace for indentation -""" -def getIndent(indent, balise): - first = indent * 2 - second = first + len(balise) + 1 - return "\t".expandtabs(first), "\t".expandtabs(second) - -""" -This function recursively creates a definition of the classes and their attributes -for plcopen from the xsd file of plcopen opened in a DOM model -""" -def Generate_classes(tree, parent, sequence = False): - attributes = {} - inheritance = [] - if sequence: - order = [] - # The lists of attributes and inheritance of the node are generated from the childrens - for node in tree.childNodes: - # We make fun of #text elements and all other tags that don't are xsd tags - if node.nodeName != "#text" and node.nodeName.startswith("xsd:"): - recursion = False - name = node.nodeName[4:].encode() - - # This tags defines an attribute of the class - if name in ["element", "attribute"]: - nodename = GetAttributeValue(node._attrs["name"]) - if "type" in node._attrs: - nodetype = GetAttributeValue(node._attrs["type"]) - else: - # The type of attribute is defines in the child tree so we generate a new class - # No name is defined so we create one from nodename and parent class name - # (because some different nodes can have the same name) - if parent: - classname = "%s_%s"%(parent, nodename) - else: - classname = nodename - Generate_classes(node, classname) - nodetype = "ppx:%s"%classname - if name == "attribute": - if "use" in node._attrs: - use = GetAttributeValue(node._attrs["use"]) - else: - use = "optional" - if name == "element": - # If a tag can be written more than one time we define a list attribute - if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded": - nodetype = "%s[]"%nodetype - if "minOccurs" in node._attrs and GetAttributeValue(node._attrs["minOccurs"]) == "0": - use = "optional" - else: - use = "required" - attributes[nodename] = (nodetype, name, use) - if sequence: - order.append(nodename) - - # This tag defines a new class - elif name == "complexType" or name == "simpleType": - if "name" in node._attrs: - classname = GetAttributeValue(node._attrs["name"]) - super, attrs = Generate_classes(node, classname) - else: - classname = parent - super, attrs = Generate_classes(node, classname.split("_")[-1]) - # When all attributes and inheritances have been extracted, the - # values are added in the list of classes to create - if classname not in classes: - classes[classname] = (super, attrs) - elif classes[classname] != (super, attrs): - print "A different class has already got %s for name"%classname - - # This tag defines an attribute that can have different types - elif name == "choice": - super, attrs = Generate_classes(node, parent) - if "ref" in attrs.keys(): - choices = attrs - else: - choices = {} - for attr, (attr_type, xml_type, write_type) in attrs.items(): - choices[attr] = attr_type - if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded": - attributes["multichoice_content"] = choices - if sequence: - order.append("multichoice_content") - else: - attributes["choice_content"] = choices - if sequence: - order.append("choice_content") - - # This tag defines the order in which class attributes must be written - # in plcopen xml file. We have to store this order like an attribute - elif name in "sequence": - super, attrs, order = Generate_classes(node, parent, True) - if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded": - for attr, (attr_type, xml_type, write_type) in attrs.items(): - attrs[attr] = ("%s[]"%attr_type, xml_type, write_type) - if "minOccurs" in node._attrs and GetAttributeValue(node._attrs["minOccurs"]) == "0": - for attr, (attr_type, xml_type, write_type) in attrs.items(): - attrs[attr] = (attr_type, xml_type, "optional") - inheritance.extend(super) - attributes.update(attrs) - attributes["order"] = order - - # This tag defines of types - elif name == "group": - if "name" in node._attrs: - nodename = GetAttributeValue(node._attrs["name"]) - super, attrs = Generate_classes(node, None) - classes[nodename] = (super, {"group":attrs["choice_content"]}) - elif "ref" in node._attrs: - if "ref" not in attributes: - attributes["ref"] = [GetAttributeValue(node._attrs["ref"])] - else: - attributes["ref"].append(GetAttributeValue(node._attrs["ref"])) - - # This tag define a base class for the node - elif name == "extension": - super = GetAttributeValue(node._attrs["base"]) - inheritance.append(super[4:]) - recursion = True - - # This tag defines a restriction on the type of attribute - elif name == "restriction": - attributes["basetype"] = GetAttributeValue(node._attrs["base"]) - recursion = True - - # This tag defines an enumerated type - elif name == "enumeration": - if "enum" not in attributes: - attributes["enum"] = [GetAttributeValue(node._attrs["value"])] - else: - attributes["enum"].append(GetAttributeValue(node._attrs["value"])) - - # This tags defines a restriction on a numerical value - elif name in ["minInclusive","maxInclusive"]: - if "limit" not in attributes: - attributes["limit"] = {} - if name == "minInclusive": - attributes["limit"]["min"] = eval(GetAttributeValue(node._attrs["value"])) - elif name == "maxInclusive": - attributes["limit"]["max"] = eval(GetAttributeValue(node._attrs["value"])) - - # This tag are not important but their childrens are. The childrens are then parsed. - elif name in ["complexContent", "schema"]: - recursion = True - - # We make fun of xsd documentation - elif name in ["annotation"]: - pass - - else: - #print name - Generate_classes(node, parent) - - # Parse the childrens of node - if recursion: - super, attrs = Generate_classes(node, parent) - inheritance.extend(super) - attributes.update(attrs) - - # if sequence tag have been found, order is returned - if sequence: - return inheritance, attributes, order - else: - return inheritance, attributes -""" -Function that extracts data from a node -""" -def GetAttributeValue(attr): - if len(attr.childNodes) == 1: - return attr.childNodes[0].data.encode() - else: - return "" - -""" -Funtion that returns the Python type and default value for a given xsd type -""" -def GetTypeInitialValue(attr_type): - type_compute = attr_type[4:].replace("[]", "") - if attr_type.startswith("xsd:"): - if type_compute == "boolean": - return BooleanType, "False" - elif type_compute in ["decimal","unsignedLong","long","integer"]: - return IntType, "0" - elif type_compute in ["string","anyURI","NMTOKEN"]: - return StringType, "\"\"" - elif type_compute == "time": - return TimeType, "time(0,0,0)" - elif type_compute == "date": - return DateType, "date(1,1,1)" - elif type_compute == "dateTime": - return DateTimeType, "datetime(1,1,1,0,0,0)" - elif type_compute == "language": - return StringType, "\"en-US\"" - else: - print "Can't affect: %s"%type_compute - elif attr_type.startswith("ppx:"): - if type_compute in PLCOpenClasses: - return PLCOpenClasses[type_compute],"%s()"%type_compute - -""" -Function that computes value from a python type (Only Boolean are critical because -there is no uppercase in plcopen) -""" -def ComputeValue(value): - if type(value) == BooleanType: - if value: - return "true" - else: - return "false" - else: - return str(value) - -""" -Function that extracts a value from a string following the xsd type given -""" -def GetComputedValue(attr_type, value): - type_compute = attr_type[4:].replace("[]", "") - if type_compute == "boolean": - if value == "true": - return True - elif value == "false": - return False - else: - raise ValueError, "\"%s\" is not a valid boolean!"%value - elif type_compute in ["decimal","unsignedLong","long","integer"]: - return int(value) - elif type_compute in ["string","anyURI","NMTOKEN","language"]: - return value - elif type_compute == "time": - result = time_model.match(value) - if result: - time_values = [int(v) for v in result.groups()] - return time(*time_values) - else: - raise ValueError, "\"%s\" is not a valid time!"%value - elif type_compute == "date": - result = date_model.match(value) - if result: - date_values = [int(v) for v in result.groups()] - return date(*date_values) - else: - raise ValueError, "\"%s\" is not a valid date!"%value - elif type_compute == "dateTime": - result = datetime_model.match(value) - if result: - datetime_values = [int(v) for v in result.groups()] - return datetime(*datetime_values) - else: - raise ValueError, "\"%s\" is not a valid datetime!"%value - else: - print "Can't affect: %s"%type_compute - return None - -""" -This is the Metaclass for PLCOpen element classes. It generates automatically -the basic useful methods for manipulate the differents attributes of the classes -""" -class MetaClass(type): - - def __init__(cls, name, bases, dict): - super(MetaClass, cls).__init__(name, bases, {}) - #print name, bases, dict, "\n" - initialValues = {} - for attr, values in dict.items(): - if attr in ["order", "basetype"]: - pass - - # Class is a enumerated type - elif attr == "enum": - value_type, initial = GetTypeInitialValue(dict["basetype"]) - initialValues["value"] = "\"%s\""%values[0] - setattr(cls, "value", values[0]) - setattr(cls, "setValue", MetaClass.generateSetEnumMethod(cls, values, value_type)) - setattr(cls, "getValue", MetaClass.generateGetMethod(cls, "value")) - - # Class is a limited type - elif attr == "limit": - value_type, initial = GetTypeInitialValue(dict["basetype"]) - initial = 0 - if "min" in values: - initial = max(initial, values["min"]) - if "max" in values: - initial = min(initial, values["max"]) - initialValues["value"] = "%d"%initial - setattr(cls, "value", initial) - setattr(cls, "setValue", MetaClass.generateSetLimitMethod(cls, values, value_type)) - setattr(cls, "getValue", MetaClass.generateGetMethod(cls, "value")) - - # Class has an attribute that can have different value types - elif attr == "choice_content": - setattr(cls, "content", None) - initialValues["content"] = "None" - setattr(cls, "deleteContent", MetaClass.generateDeleteMethod(cls, "content")) - setattr(cls, "setContent", MetaClass.generateSetChoiceMethod(cls, values)) - setattr(cls, "getContent", MetaClass.generateGetMethod(cls, "content")) - elif attr == "multichoice_content": - setattr(cls, "content", []) - initialValues["content"] = "[]" - setattr(cls, "appendContent", MetaClass.generateAppendChoiceMethod(cls, values)) - setattr(cls, "insertContent", MetaClass.generateInsertChoiceMethod(cls, values)) - setattr(cls, "removeContent", MetaClass.generateRemoveMethod(cls, "content")) - setattr(cls, "countContent", MetaClass.generateCountMethod(cls, "content")) - setattr(cls, "setContent", MetaClass.generateSetMethod(cls, "content", ListType)) - setattr(cls, "getContent", MetaClass.generateGetMethod(cls, "content")) - - # It's an attribute of the class - else: - attrname = attr[0].upper()+attr[1:] - attr_type, xml_type, write_type = values - value_type, initial = GetTypeInitialValue(attr_type) - # Value of the attribute is a list - if attr_type.endswith("[]"): - setattr(cls, attr, []) - initialValues[attr] = "[]" - setattr(cls, "append"+attrname, MetaClass.generateAppendMethod(cls, attr, value_type)) - setattr(cls, "insert"+attrname, MetaClass.generateInsertMethod(cls, attr, value_type)) - setattr(cls, "remove"+attrname, MetaClass.generateRemoveMethod(cls, attr)) - setattr(cls, "count"+attrname, MetaClass.generateCountMethod(cls, attr)) - setattr(cls, "set"+attrname, MetaClass.generateSetMethod(cls, attr, ListType)) - else: - if write_type == "optional": - setattr(cls, attr, None) - initialValues[attr] = "None" - setattr(cls, "add"+attrname, MetaClass.generateAddMethod(cls, attr, initial)) - setattr(cls, "delete"+attrname, MetaClass.generateDeleteMethod(cls, attr)) - else: - setattr(cls, attr, initial) - initialValues[attr] = initial - setattr(cls, "set"+attrname, MetaClass.generateSetMethod(cls, attr, value_type)) - setattr(cls, "get"+attrname, MetaClass.generateGetMethod(cls, attr)) - setattr(cls, "__init__", MetaClass.generateInitMethod(cls, bases, initialValues)) - setattr(cls, "loadXMLTree", MetaClass.generateLoadXMLTree(cls, bases, dict)) - setattr(cls, "generateXMLText", MetaClass.generateGenerateXMLText(cls, bases, dict)) - setattr(cls, "singleLineAttributes", True) - - """ - Method that generate the method for loading an xml tree by following the - attributes list defined - """ - def generateLoadXMLTree(cls, bases, dict): - def loadXMLTreeMethod(self, tree): - # If class is derived, values of inheritance classes are loaded - for base in bases: - base.loadXMLTree(self, tree) - # Class is a enumerated or limited value - if "enum" in dict.keys() or "limit" in dict.keys(): - attr_value = GetAttributeValue(tree) - attr_type = dict["basetype"] - val = GetComputedValue(attr_type, attr_value) - self.setValue(val) - else: - - # Load the node attributes if they are defined in the list - for attrname, attr in tree._attrs.items(): - if attrname in dict.keys(): - attr_type, xml_type, write_type = dict[attrname] - attr_value = GetAttributeValue(attr) - if write_type != "optional" or attr_value != "": - # Extracts the value - if attr_type.startswith("xsd:"): - val = GetComputedValue(attr_type, attr_value) - elif attr_type.startswith("ppx:"): - val = eval("%s()"%attr_type[4:], globals().update(PLCOpenClasses)) - val.loadXMLTree(attr) - setattr(self, attrname, val) - - # Load the node childs if they are defined in the list - for node in tree.childNodes: - name = node.nodeName - # We make fun of #text elements - if name != "#text": - - # Class has an attribute that can have different value types - if "choice_content" in dict.keys() and name in dict["choice_content"].keys(): - attr_type = dict["choice_content"][name] - # Extracts the value - if attr_type.startswith("xsd:"): - attr_value = GetAttributeValue(node) - if write_type != "optional" or attr_value != "": - val = GetComputedValue(attr_type.replace("[]",""), attr_value) - else: - val = None - elif attr_type.startswith("ppx:"): - val = eval("%s()"%attr_type[4:].replace("[]",""), globals().update(PLCOpenClasses)) - val.loadXMLTree(node) - # Stock value in content attribute - if val: - if attr_type.endswith("[]"): - if self.content: - self.content["value"].append(val) - else: - self.content = {"name":name,"value":[val]} - else: - self.content = {"name":name,"value":val} - - # Class has a list of attributes that can have different value types - elif "multichoice_content" in dict.keys() and name in dict["multichoice_content"].keys(): - attr_type = dict["multichoice_content"][name] - # Extracts the value - if attr_type.startswith("xsd:"): - attr_value = GetAttributeValue(node) - if write_type != "optional" or attr_value != "": - val = GetComputedValue(attr_type, attr_value) - else: - val = None - elif attr_type.startswith("ppx:"): - val = eval("%s()"%attr_type[4:], globals().update(PLCOpenClasses)) - val.loadXMLTree(node) - # Add to content attribute list - if val: - self.content.append({"name":name,"value":val}) - - # The node child is defined in the list - elif name in dict.keys(): - attr_type, xml_type, write_type = dict[name] - # Extracts the value - if attr_type.startswith("xsd:"): - attr_value = GetAttributeValue(node) - if write_type != "optional" or attr_value != "": - val = GetComputedValue(attr_type.replace("[]",""), attr_value) - else: - val = None - elif attr_type.startswith("ppx:"): - val = eval("%s()"%attr_type[4:].replace("[]",""), globals().update(PLCOpenClasses)) - val.loadXMLTree(node) - # Stock value in attribute - if val: - if attr_type.endswith("[]"): - getattr(self, name).append(val) - else: - setattr(self, name, val) - return loadXMLTreeMethod - - """ - Method that generates the method for generating an xml text by following the - attributes list defined - """ - def generateGenerateXMLText(cls, bases, dict): - def generateXMLTextMethod(self, name, indent, extras = {}, derived = False): - ind1, ind2 = getIndent(indent, name) - if not derived: - text = ind1 + "<%s"%name - else: - text = "" - if len(bases) > 0: - base_extras = {} - if "order" in dict.keys(): - order = dict["order"] - else: - order = [] - if "choice_content" in dict.keys() and "choice_content" not in order: - order.append("choice_content") - if "multichoice_content" in dict.keys() and "multichoice_content" not in order: - order.append("multichoice_content") - size = 0 - first = True - for attr, value in extras.items(): - if not first and not self.singleLineAttributes: - text += "\n%s"%(ind2) - text += " %s=\"%s\""%(attr, ComputeValue(value)) - first = False - for attr, values in dict.items(): - if attr in ["order","choice_content","multichoice_content"]: - pass - elif attr in ["enum","limit"]: - if not derived: - text += ">%s\n"%(ComputeValue(self.value),name) - else: - text += ComputeValue(self.value) - return text - elif values[1] == "attribute": - value = getattr(self, attr, None) - if values[2] != "optional" or value != None: - if not first and not self.singleLineAttributes: - text += "\n%s"%(ind2) - if values[0].startswith("ppx"): - if len(bases) > 0: - base_extras[attr] = value.getValue() - else: - text += " %s=\"%s\""%(attr, ComputeValue(value.getValue())) - else: - if len(bases) > 0: - base_extras[attr] = value - else: - text += " %s=\"%s\""%(attr, ComputeValue(value)) - first = False - if len(bases) > 0: - first, new_text = bases[0].generateXMLText(self, name, indent, base_extras, True) - text += new_text - else: - first = True - ind3, ind4 = getIndent(indent + 1, name) - for attr in order: - value = getattr(self, attr, None) - if attr == "choice_content": - if self.content: - if first: - text += ">\n" - first = False - value_type = dict[attr][self.content["name"]] - if value_type.startswith("xsd:"): - if value_type.endswith("[]"): - for content in self.content["value"]: - text += ind1 + "<%s>%s\n"%(self.content["name"], ComputeValue(content), self.content["name"]) - else: - text += ind1 + "<%s>%s\n"%(self.content["name"], ComputeValue(self.content["value"]), self.content["name"]) - elif value_type.endswith("[]"): - for content in self.content["value"]: - text += content.generateXMLText(self.content["name"], indent + 1) - else: - text += self.content["value"].generateXMLText(self.content["name"], indent + 1) - elif attr == "multichoice_content": - if len(self.content) > 0: - for element in self.content: - if first: - text += ">\n" - first = False - value_type = dict[attr][element["name"]] - if value_type.startswith("xsd:"): - text += ind1 + "<%s>%s\n"%(element["name"], ComputeValue(element["value"]), element["name"]) - else: - text += element["value"].generateXMLText(element["name"], indent + 1) - elif dict[attr][2] != "optional" or value != None: - if dict[attr][0].endswith("[]"): - if first and len(value) > 0: - text += ">\n" - first = False - for element in value: - if dict[attr][0].startswith("xsd:"): - text += ind3 + "<%s>%s\n"%(attr, ComputeValue(element), attr) - else: - text += element.generateXMLText(attr, indent + 1) - else: - if first: - text += ">\n" - first = False - if dict[attr][0].startswith("xsd:"): - text += ind3 + "<%s>%s\n"%(attr, ComputeValue(value), attr) - else: - text += getattr(self, attr).generateXMLText(attr, indent + 1) - if not derived: - if first: - text += "/>\n" - else: - text += ind1 + "\n"%(name) - return text - else: - return first, text - return generateXMLTextMethod - - """ - Methods that generates the different methods for setting and getting the attributes - """ - - def generateInitMethod(cls, bases, dict): - def initMethod(self): - for base in bases: - base.__init__(self) - for attr, initial in dict.items(): - setattr(self, attr, eval(initial, globals().update(PLCOpenClasses))) - return initMethod - - def generateSetMethod(cls, attr, choice_type): - def setMethod(self, value): - setattr(self, attr, value) - return setMethod - - def generateSetChoiceMethod(cls, attr_type): - def setChoiceMethod(self, name, value): - self.content = {"name":name,"value":value} - return setChoiceMethod - - def generateSetEnumMethod(cls, enum, attr_type): - def setEnumMethod(self, value): - if value in enum: - self.value = value - else: - raise ValueError, "%s is not a valid value. Must be in %s"%(value, str(enum)) - return setEnumMethod - - def generateSetLimitMethod(cls, limit, attr_type): - def setMethod(self, value): - if "min" in limit and value < limit["min"]: - raise ValueError, "%s is not a valid value. Must be greater than %d"%(value, limit["min"]) - elif "max" in limit and value > limit["max"]: - raise ValueError, "%s is not a valid value. Must be smaller than %d"%(value, limit["max"]) - else: - self.value = value - return setMethod - - def generateGetMethod(cls, attr): - def getMethod(self): - return getattr(self, attr, None) - return getMethod - - def generateAddMethod(cls, attr, initial): - def addMethod(self): - setattr(self, attr, eval(initial, globals().update(PLCOpenClasses))) - return addMethod - - def generateDeleteMethod(cls, attr): - def deleteMethod(self): - setattr(self, attr, None) - return deleteMethod - - def generateAppendMethod(cls, attr, attr_type): - def appendMethod(self, value): - getattr(self, attr).append(value) - return appendMethod - - def generateInsertMethod(cls, attr, attr_type): - def insertMethod(self, index, value): - getattr(self, attr).insert(index, value) - return insertMethod - - def generateAppendChoiceMethod(cls, choice_types): - def appendMethod(self, name, value): - self.content.append({"name":name,"value":value}) - return appendMethod - - def generateInsertChoiceMethod(cls, choice_types): - def insertMethod(self, index, name, value): - self.content.insert(index, {"name":name,"value":value}) - return insertMethod - - def generateRemoveMethod(cls, attr): - def removeMethod(self, index): - getattr(self, attr).pop(index) - return removeMethod - - def generateCountMethod(cls, attr): - def countMethod(self): - return len(getattr(self, attr)) - return countMethod - -""" -Method that generate the classes -""" -def CreateClass(classe): - # Checks that classe haven't been generated yet - if classe not in PLCOpenClasses and classe not in PLCOpenTypes and classe in classes: - inheritance, attributes = classes[classe] - #print classe, inheritance, attributes - dict = {} - bases = [] - - # If inheritance classes haven't been generated - for base in inheritance: - if base not in PLCOpenClasses: - CreateClass(base) - bases.append(PLCOpenClasses[base]) - - # Checks that all attribute types are available - for attribute, type_attribute in attributes.items(): - if attribute == "group": - PLCOpenTypes[classe] = type_attribute - elif attribute == "ref": - PLCOpenTypes[classe] = {} - for attr in type_attribute: - if attr[4:] not in PLCOpenTypes: - CreateClass(attr[4:]) - PLCOpenTypes[classe].update(PLCOpenTypes[attr[4:]]) - elif attribute in ["choice_content","multichoice_content"]: - element_types = {} - for attr, value in type_attribute.items(): - if attr == "ref": - for ref in type_attribute["ref"]: - if ref[4:] not in PLCOpenTypes: - CreateClass(ref[4:]) - element_types.update(PLCOpenTypes[ref[4:]]) - else: - element_types[attr] = value - dict[attribute] = element_types - else: - dict[attribute] = type_attribute - if attribute == "enum": - PLCOpenTypes["%s_enum"%classe] = type_attribute - elif attribute not in ["limit", "order"]: - if type_attribute[0].startswith("ppx:"): - type_compute = type_attribute[0][4:].replace("[]","") - if type_compute not in PLCOpenClasses: - CreateClass(type_compute) - if "group" not in attributes.keys() and "ref" not in attributes.keys(): - cls = MetaClass.__new__(MetaClass, classe, tuple(bases), dict) - MetaClass.__init__(cls, classe, tuple(bases), dict) - PLCOpenClasses[classe] = cls - -def Generate_Methods(): - if "dataType" in PLCOpenClasses: - cls = PLCOpenClasses["dataType"] - cls.value = None - - def getValue(self): - return self.value - setattr(cls, "getValue", getValue) - - def setValue(self, value): - self.value = value - setattr(cls, "setValue", setValue) - - def loadXMLTree(self, tree): - self.value = tree.childNodes[1].nodeName - setattr(cls, "loadXMLTree", loadXMLTree) - - def generateXMLText(self, name, indent, extras = {}): - ind1, ind2 = getIndent(indent, name) +PLCOpenClasses = {} +PLCOpenTypes = {} +GenerateClassesFromXSD("plcopen/TC6_XML_V10_B.xsd") +CreateClasses(PLCOpenClasses, PLCOpenTypes) + +if "dataType" in PLCOpenClasses: + cls = PLCOpenClasses["dataType"] + cls.value = None + + def getValue(self): + return self.value + setattr(cls, "getValue", getValue) + + def setValue(self, value): + self.value = value + setattr(cls, "setValue", setValue) + + def loadXMLTree(self, tree): + self.value = tree.childNodes[1].nodeName + setattr(cls, "loadXMLTree", loadXMLTree) + + def generateXMLText(self, name, indent, extras = {}): + ind1, ind2 = getIndent(indent, name) + text = ind1 + "<%s>\n"%name + ind3, ind4 = getIndent(indent + 1, self.value) + text += ind3 + "<%s/>\n"%self.value + text += ind1 + "\n"%name + return text + setattr(cls, "generateXMLText", generateXMLText) + +if "formattedText" in PLCOpenClasses: + cls = PLCOpenClasses["formattedText"] + cls.text = "" + + def getText(self): + return self.text + setattr(cls, "getText", getText) + + def setText(self, text): + self.text = text + setattr(cls, "setText", setText) + + def loadXMLTree(self, tree): + self.text = GetAttributeValue(tree) + if len(self.text.splitlines()) > 1: + self.text = self.text[1:].rstrip() + setattr(cls, "loadXMLTree", loadXMLTree) + + def generateXMLText(self, name, indent, extras = {}): + ind1, ind2 = getIndent(indent, name) + if len(self.text.splitlines()) > 1: text = ind1 + "<%s>\n"%name - ind3, ind4 = getIndent(indent + 1, self.value) - text += ind3 + "<%s/>\n"%self.value + text += "%s\n"%self.text text += ind1 + "\n"%name return text - setattr(cls, "generateXMLText", generateXMLText) - - if "formattedText" in PLCOpenClasses: - cls = PLCOpenClasses["formattedText"] - cls.text = "" + else: + return ind1 + "<%s>%s\n"%(name, self.text, name) + setattr(cls, "generateXMLText", generateXMLText) + +if "project" in PLCOpenClasses: + cls = PLCOpenClasses["project"] + cls.singleLineAttributes = False + + def getFileHeader(self): + fileheader = {} + fileheader["companyName"] = self.fileHeader.getCompanyName() + if self.fileHeader.getCompanyURL(): + fileheader["companyURL"] = self.fileHeader.getCompanyURL() + fileheader["productName"] = self.fileHeader.getProductName() + fileheader["productVersion"] = self.fileHeader.getProductVersion() + if self.fileHeader.getProductRelease(): + fileheader["productRelease"] = self.fileHeader.getProductRelease() + fileheader["creationDateTime"] = self.fileHeader.getCreationDateTime() + if self.fileHeader.getContentDescription(): + fileheader["contentDescription"] = self.fileHeader.getContentDescription() + return fileheader + setattr(cls, "getFileHeader", getFileHeader) + + def setFileHeader(self, fileheader): + self.fileHeader.setCompanyName(fileheader["companyName"]) + if "companyURL" in fileheader: + self.fileHeader.setCompanyURL(fileheader["companyURL"]) + self.fileHeader.setProductName(fileheader["productName"]) + self.fileHeader.setProductVersion(fileheader["productVersion"]) + if "productRelease" in fileheader: + self.fileHeader.setProductRelease(fileheader["productRelease"]) + self.fileHeader.setCreationDateTime(fileheader["creationDateTime"]) + if "contentDescription" in fileheader: + self.fileHeader.setContentDescription(fileheader["contentDescription"]) + setattr(cls, "setFileHeader", setFileHeader) + + def setName(self, name): + self.contentHeader.setName(name) + setattr(cls, "setName", setName) - def getText(self): - return self.text - setattr(cls, "getText", getText) + def getName(self): + return self.contentHeader.getName() + setattr(cls, "getName", getName) + + def getPous(self): + return self.types.getPouElements() + setattr(cls, "getPous", getPous) + + def getPou(self, name): + return self.types.getPouElement(name) + setattr(cls, "getPou", getPou) + + def appendPou(self, name, pou_type, body_type): + self.types.appendPouElement(name, pou_type, body_type) + setattr(cls, "appendPou", appendPou) - def setText(self, text): - self.text = text - setattr(cls, "setText", setText) - - def loadXMLTree(self, tree): - self.text = GetAttributeValue(tree) - if len(self.text.splitlines()) > 1: - self.text = self.text[1:].rstrip() - setattr(cls, "loadXMLTree", loadXMLTree) - - def generateXMLText(self, name, indent, extras = {}): - ind1, ind2 = getIndent(indent, name) - if len(self.text.splitlines()) > 1: - text = ind1 + "<%s>\n"%name - text += "%s\n"%self.text - text += ind1 + "\n"%name - return text - else: - return ind1 + "<%s>%s\n"%(name, self.text, name) - setattr(cls, "generateXMLText", generateXMLText) - - if "project" in PLCOpenClasses: - cls = PLCOpenClasses["project"] - cls.singleLineAttributes = False - - def getFileHeader(self): - fileheader = {} - fileheader["companyName"] = self.fileHeader.getCompanyName() - if self.fileHeader.getCompanyURL(): - fileheader["companyURL"] = self.fileHeader.getCompanyURL() - fileheader["productName"] = self.fileHeader.getProductName() - fileheader["productVersion"] = self.fileHeader.getProductVersion() - if self.fileHeader.getProductRelease(): - fileheader["productRelease"] = self.fileHeader.getProductRelease() - fileheader["creationDateTime"] = self.fileHeader.getCreationDateTime() - if self.fileHeader.getContentDescription(): - fileheader["contentDescription"] = self.fileHeader.getContentDescription() - return fileheader - setattr(cls, "getFileHeader", getFileHeader) - - def setFileHeader(self, fileheader): - self.fileHeader.setCompanyName(fileheader["companyName"]) - if "companyURL" in fileheader: - self.fileHeader.setCompanyURL(fileheader["companyURL"]) - self.fileHeader.setProductName(fileheader["productName"]) - self.fileHeader.setProductVersion(fileheader["productVersion"]) - if "productRelease" in fileheader: - self.fileHeader.setProductRelease(fileheader["productRelease"]) - self.fileHeader.setCreationDateTime(fileheader["creationDateTime"]) - if "contentDescription" in fileheader: - self.fileHeader.setContentDescription(fileheader["contentDescription"]) - setattr(cls, "setFileHeader", setFileHeader) - - def setName(self, name): - self.contentHeader.setName(name) - setattr(cls, "setName", setName) - - def getName(self): - return self.contentHeader.getName() - setattr(cls, "getName", getName) - - def getPous(self): - return self.types.getPouElements() - setattr(cls, "getPous", getPous) - - def getPou(self, name): - return self.types.getPouElement(name) - setattr(cls, "getPou", getPou) - - def appendPou(self, name, pou_type, body_type): - self.types.appendPouElement(name, pou_type, body_type) - setattr(cls, "appendPou", appendPou) - - def insertPou(self, index, pou): - self.types.insertPouElement(index, pou) - setattr(cls, "insertPou", insertPou) - - def removePou(self, name): - self.types.removePouElement(name) - setattr(cls, "removePou", removePou) - - def getConfigurations(self): - configurations = self.instances.configurations.getConfiguration() - if configurations: - return configurations - return [] - setattr(cls, "getConfigurations", getConfigurations) - - def getConfiguration(self, name): - for configuration in self.instances.configurations.getConfiguration(): - if configuration.getName() == name: - return configuration - return None - setattr(cls, "getConfiguration", getConfiguration) - - def addConfiguration(self, name): - for configuration in self.instances.configurations.getConfiguration(): - if configuration.getName() == name: - raise ValueError, "\"%s\" configuration already exists !!!"%name - new_configuration = PLCOpenClasses["configurations_configuration"]() - new_configuration.setName(name) - self.instances.configurations.appendConfiguration(new_configuration) - setattr(cls, "addConfiguration", addConfiguration) - - def removeConfiguration(self, name): + def insertPou(self, index, pou): + self.types.insertPouElement(index, pou) + setattr(cls, "insertPou", insertPou) + + def removePou(self, name): + self.types.removePouElement(name) + setattr(cls, "removePou", removePou) + + def getConfigurations(self): + configurations = self.instances.configurations.getConfiguration() + if configurations: + return configurations + return [] + setattr(cls, "getConfigurations", getConfigurations) + + def getConfiguration(self, name): + for configuration in self.instances.configurations.getConfiguration(): + if configuration.getName() == name: + return configuration + return None + setattr(cls, "getConfiguration", getConfiguration) + + def addConfiguration(self, name): + for configuration in self.instances.configurations.getConfiguration(): + if configuration.getName() == name: + raise ValueError, "\"%s\" configuration already exists !!!"%name + new_configuration = PLCOpenClasses["configurations_configuration"]() + new_configuration.setName(name) + self.instances.configurations.appendConfiguration(new_configuration) + setattr(cls, "addConfiguration", addConfiguration) + + def removeConfiguration(self, name): + found = False + for idx, configuration in enumerate(self.instances.configurations.getConfiguration()): + if configuration.getName() == name: + self.instances.configurations.removeConfiguration(idx) + found = True + break + if not found: + raise ValueError, "\"%s\" configuration doesn't exist !!!"%name + setattr(cls, "removeConfiguration", removeConfiguration) + + def getConfigurationResource(self, config_name, name): + configuration = self.getConfiguration(config_name) + if configuration: + for resource in configuration.getResource(): + if resource.getName() == name: + return resource + return None + setattr(cls, "getConfigurationResource", getConfigurationResource) + + def addConfigurationResource(self, config_name, name): + configuration = self.getConfiguration(config_name) + if configuration: + for resource in configuration.getResource(): + if resource.getName() == name: + raise ValueError, "\"%s\" resource already exists in \"%s\" configuration !!!"%(name, config_name) + new_resource = PLCOpenClasses["configuration_resource"]() + new_resource.setName(name) + configuration.appendResource(new_resource) + setattr(cls, "addConfigurationResource", addConfigurationResource) + + def removeConfigurationResource(self, config_name, name): + configuration = self.getConfiguration(config_name) + if configuration: found = False - for idx, configuration in enumerate(self.instances.configurations.getConfiguration()): - if configuration.getName() == name: - self.instances.configurations.removeConfiguration(idx) + for idx, resource in enumerate(configuration.getResource()): + if resource.getName() == name: + configuration.removeResource(idx) found = True break if not found: - raise ValueError, "\"%s\" configuration doesn't exist !!!"%name - setattr(cls, "removeConfiguration", removeConfiguration) - - def getConfigurationResource(self, config_name, name): - configuration = self.getConfiguration(config_name) - if configuration: - for resource in configuration.getResource(): - if resource.getName() == name: - return resource + raise ValueError, "\"%s\" resource doesn't exist in \"%s\" configuration !!!"%(name, config_name) + setattr(cls, "removeConfigurationResource", removeConfigurationResource) + +PLCOpenClasses["project_fileHeader"].singleLineAttributes = False + +if "project_types" in PLCOpenClasses: + cls = PLCOpenClasses["project_types"] + + def getPouElements(self): + return self.pous.getPou() + setattr(cls, "getPouElements", getPouElements) + + def getPouElement(self, name): + elements = self.pous.getPou() + for element in elements: + if element.getName() == name: + return element + return None + setattr(cls, "getPouElement", getPouElement) + + def appendPouElement(self, name, pou_type, body_type): + for element in self.pous.getPou(): + if element.getName() == name: + raise ValueError, "\"%s\" POU already exists !!!"%name + new_pou = PLCOpenClasses["pous_pou"]() + new_pou.setName(name) + new_pou.pouType.setValue(pou_type) + new_pou.setBody(PLCOpenClasses["body"]()) + new_pou.setBodyType(body_type) + self.pous.appendPou(new_pou) + setattr(cls, "appendPouElement", appendPouElement) + + def insertPouElement(self, index, pou): + self.pous.insertPou(index, pou) + setattr(cls, "insertPouElement", insertPouElement) + + def removePouElement(self, name): + found = False + for idx, element in enumerate(self.pous.getPou()): + if element.getName() == name: + self.pous.removePou(idx) + found = True + break + if not found: + raise ValueError, "\"%s\" POU doesn't exist !!!"%name + setattr(cls, "removePouElement", removePouElement) + +def setBodyType(self, type): + if type == "IL": + self.body.setContent("IL", PLCOpenClasses["formattedText"]()) + elif type == "ST": + self.body.setContent("ST", PLCOpenClasses["formattedText"]()) + elif type == "LD": + self.body.setContent("LD", PLCOpenClasses["body_LD"]()) + elif type == "FBD": + self.body.setContent("FBD", PLCOpenClasses["body_FBD"]()) + elif type == "SFC": + self.body.setContent("SFC", PLCOpenClasses["body_SFC"]()) + else: + raise ValueError, "%s isn't a valid body type!"%type + +def getBodyType(self): + return self.body.getContent()["name"] + +def addInstance(self, name, instance): + self.body.appendContentInstance(name, instance) + +def getInstances(self): + return self.body.getContentInstances() + +def getInstance(self, id): + return self.body.getContentInstance(id) + +def getRandomInstance(self, exclude): + return self.body.getContentRandomInstance(exclude) + +def getInstanceByName(self, name): + return self.body.getContentInstanceByName(name) + +def removeInstance(self, id): + self.body.removeContentInstance(id) + +def setText(self, text): + self.body.setText(text) + +def getText(self): + return self.body.getText() +setattr(cls, "getText", getText) + +if "pous_pou" in PLCOpenClasses: + cls = PLCOpenClasses["pous_pou"] + + setattr(cls, "setBodyType", setBodyType) + setattr(cls, "getBodyType", getBodyType) + setattr(cls, "addInstance", addInstance) + setattr(cls, "getInstances", getInstances) + setattr(cls, "getInstance", getInstance) + setattr(cls, "getRandomInstance", getRandomInstance) + setattr(cls, "getInstanceByName", getInstanceByName) + setattr(cls, "removeInstance", removeInstance) + setattr(cls, "setText", setText) + setattr(cls, "getText", getText) + + def getVars(self): + vars = [] + reverse_types = {} + for name, value in VarTypes.items(): + reverse_types[value] = name + for varlist in self.interface.getContent(): + vars.append((reverse_types[varlist["name"]], varlist["value"])) + return vars + setattr(cls, "getVars", getVars) + + def setVars(self, vars): + self.interface.setContent([]) + for vartype, varlist in vars: + self.interface.appendContent(VarTypes[vartype], varlist) + setattr(cls, "setVars", setVars) + + def addTransition(self, name, type): + if not self.transitions: + self.addTransitions() + self.transitions.setTransition([]) + transition = PLCOpenClasses["transitions_transition"]() + transition.setName(name) + transition.setBodyType(type) + self.transitions.appendTransition(transition) + setattr(cls, "addTransition", addTransition) + + def getTransition(self, name): + if self.transitions: + for transition in self.transitions.getTransition(): + if transition.getName() == name: + return transition + return None + setattr(cls, "getTransition", getTransition) + + def getTransitionList(self): + if self.transitions: + return self.transitions.getTransition() + return [] + setattr(cls, "getTransitionList", getTransitionList) + + def removeTransition(self, name): + if self.transitions: + transitions = self.transitions.getTransition() + i = 0 + removed = False + while i < len(transitions) and not removed: + if transitions[i].getName() == name: + transitions.removeTransition(i) + removed = True + i += 1 + if not removed: + raise ValueError, "Transition with name %s doesn't exists!"%name + setattr(cls, "removeTransition", removeTransition) + + def addAction(self, name, type): + if not self.actions: + self.addActions() + self.actions.setAction([]) + action = PLCOpenClasses["actions_action"]() + action.setName(name) + action.setBodyType(type) + self.actions.appendAction(action) + setattr(cls, "addAction", addAction) + + def getAction(self, name): + if self.actions: + for action in self.actions.getAction(): + if action.getName() == name: + return action + return None + setattr(cls, "getAction", getAction) + + def getActionList(self): + if self.actions: + return self.actions.getAction() + return [] + setattr(cls, "getActionList", getActionList) + + def removeAction(self, name): + if self.actions: + actions = self.actions.getAction() + i = 0 + removed = False + while i < len(actions) and not removed: + if actions[i].getName() == name: + actions.removeAction(i) + removed = True + i += 1 + if not removed: + raise ValueError, "Action with name %s doesn't exists!"%name + setattr(cls, "removeAction", removeAction) + +if "transitions_transition" in PLCOpenClasses: + cls = PLCOpenClasses["transitions_transition"] + + setattr(cls, "setBodyType", setBodyType) + setattr(cls, "getBodyType", getBodyType) + setattr(cls, "addInstance", addInstance) + setattr(cls, "getInstances", getInstances) + setattr(cls, "getInstance", getInstance) + setattr(cls, "getRandomInstance", getRandomInstance) + setattr(cls, "getInstanceByName", getInstanceByName) + setattr(cls, "removeInstance", removeInstance) + setattr(cls, "setText", setText) + setattr(cls, "getText", getText) + +if "actions_action" in PLCOpenClasses: + cls = PLCOpenClasses["actions_action"] + + setattr(cls, "setBodyType", setBodyType) + setattr(cls, "getBodyType", getBodyType) + setattr(cls, "addInstance", addInstance) + setattr(cls, "getInstances", getInstances) + setattr(cls, "getInstance", getInstance) + setattr(cls, "getRandomInstance", getRandomInstance) + setattr(cls, "getInstanceByName", getInstanceByName) + setattr(cls, "removeInstance", removeInstance) + setattr(cls, "setText", setText) + setattr(cls, "getText", getText) + +if "body" in PLCOpenClasses: + cls = PLCOpenClasses["body"] + + def appendContentInstance(self, name, instance): + if self.content["name"] in ["LD","FBD","SFC"]: + self.content["value"].appendContent(name, instance) + else: + raise TypeError, "%s body don't have instances!"%self.content["name"] + setattr(cls, "appendContentInstance", appendContentInstance) + + def getContentInstances(self): + if self.content["name"] in ["LD","FBD","SFC"]: + instances = [] + for element in self.content["value"].getContent(): + instances.append(element["value"]) + return instances + else: + raise TypeError, "%s body don't have instances!"%self.content["name"] + setattr(cls, "getContentInstances", getContentInstances) + + def getContentInstance(self, id): + if self.content["name"] in ["LD","FBD","SFC"]: + for element in self.content["value"].getContent(): + if element["value"].getLocalId() == id: + return element["value"] return None - setattr(cls, "getConfigurationResource", getConfigurationResource) - - def addConfigurationResource(self, config_name, name): - configuration = self.getConfiguration(config_name) - if configuration: - for resource in configuration.getResource(): - if resource.getName() == name: - raise ValueError, "\"%s\" resource already exists in \"%s\" configuration !!!"%(name, config_name) - new_resource = PLCOpenClasses["configuration_resource"]() - new_resource.setName(name) - configuration.appendResource(new_resource) - setattr(cls, "addConfigurationResource", addConfigurationResource) - - def removeConfigurationResource(self, config_name, name): - configuration = self.getConfiguration(config_name) - if configuration: - found = False - for idx, resource in enumerate(configuration.getResource()): - if resource.getName() == name: - configuration.removeResource(idx) - found = True - break - if not found: - raise ValueError, "\"%s\" resource doesn't exist in \"%s\" configuration !!!"%(name, config_name) - setattr(cls, "removeConfigurationResource", removeConfigurationResource) - - PLCOpenClasses["project_fileHeader"].singleLineAttributes = False - - if "project_types" in PLCOpenClasses: - cls = PLCOpenClasses["project_types"] - - def getPouElements(self): - return self.pous.getPou() - setattr(cls, "getPouElements", getPouElements) + else: + raise TypeError, "%s body don't have instances!"%self.content["name"] + setattr(cls, "getContentInstance", getContentInstance) + + def getContentRandomInstance(self, exclude): + if self.content["name"] in ["LD","FBD","SFC"]: + for element in self.content["value"].getContent(): + if element["value"].getLocalId() not in exclude: + return element["value"] + return None + else: + raise TypeError, "%s body don't have instances!"%self.content["name"] + setattr(cls, "getContentRandomInstance", getContentRandomInstance) + + def getContentInstanceByName(self, name): + if self.content["name"] in ["LD","FBD","SFC"]: + for element in self.content["value"].getContent(): + if element["value"].getLocalId() == name: + return element["value"] + else: + raise TypeError, "%s body don't have instances!"%self.content["name"] + setattr(cls, "getContentInstanceByName", getContentInstanceByName) + + def removeContentInstance(self, id): + if self.content["name"] in ["LD","FBD","SFC"]: + i = 0 + removed = False + elements = self.content["value"].getContent() + while i < len(elements) and not removed: + if elements[i]["value"].getLocalId() == id: + self.content["value"].removeContent(i) + removed = True + i += 1 + if not removed: + raise ValueError, "Instance with id %d doesn't exists!"%id + else: + raise TypeError, "%s body don't have instances!"%self.content["name"] + setattr(cls, "removeContentInstance", removeContentInstance) + + def setText(self, text): + if self.content["name"] in ["IL","ST"]: + self.content["value"].setText(text) + else: + raise TypeError, "%s body don't have text!"%self.content["name"] + setattr(cls, "setText", setText) + + def getText(self): + if self.content["name"] in ["IL","ST"]: + return self.content["value"].getText() + else: + raise TypeError, "%s body don't have text!"%self.content["name"] + setattr(cls, "getText", getText) + +def getX(self): + return self.position.getX() + +def getY(self): + return self.position.getY() + +def setX(self, x): + self.position.setX(x) + +def setY(self, y): + self.position.setY(y) + +if "comment" in PLCOpenClasses: + cls = PLCOpenClasses["comment"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setContentText(self, text): + self.content.setText(text) + setattr(cls, "setContentText", setContentText) - def getPouElement(self, name): - elements = self.pous.getPou() - for element in elements: - if element.getName() == name: - return element - return None - setattr(cls, "getPouElement", getPouElement) - - def appendPouElement(self, name, pou_type, body_type): - for element in self.pous.getPou(): - if element.getName() == name: - raise ValueError, "\"%s\" POU already exists !!!"%name - new_pou = PLCOpenClasses["pous_pou"]() - new_pou.setName(name) - new_pou.pouType.setValue(pou_type) - new_pou.setBody(PLCOpenClasses["body"]()) - new_pou.setBodyType(body_type) - self.pous.appendPou(new_pou) - setattr(cls, "appendPouElement", appendPouElement) - - def insertPouElement(self, index, pou): - self.pous.insertPou(index, pou) - setattr(cls, "insertPouElement", insertPouElement) + def getContentText(self): + return self.content.getText() + setattr(cls, "getContentText", getContentText) + +if "block" in PLCOpenClasses: + cls = PLCOpenClasses["block"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "inputVariables_variable" in PLCOpenClasses: + cls = PLCOpenClasses["inputVariables_variable"] + + def setConnectorEdge(self, edge): + if not self.edge: + self.edge = PLCOpenClasses["edgeModifierType"]() + self.edge.setValue(edge) + setattr(cls, "setConnectorEdge", setConnectorEdge) + + def getConnectorEdge(self): + if self.edge: + return self.edge.getValue() + return None + setattr(cls, "getConnectorEdge", getConnectorEdge) + +if "outputVariables_variable" in PLCOpenClasses: + cls = PLCOpenClasses["outputVariables_variable"] + + def setConnectorEdge(self, edge): + if not self.edge: + self.edge = PLCOpenClasses["edgeModifierType"]() + self.edge.setValue(edge) + setattr(cls, "setConnectorEdge", setConnectorEdge) + + def getConnectorEdge(self): + if self.edge: + return self.edge.getValue() + return None + setattr(cls, "getConnectorEdge", getConnectorEdge) + +if "leftPowerRail" in PLCOpenClasses: + cls = PLCOpenClasses["leftPowerRail"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "contact" in PLCOpenClasses: + cls = PLCOpenClasses["contact"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setContactEdge(self, edge): + if not self.edge: + self.edge = PLCOpenClasses["edgeModifierType"]() + self.edge.setValue(edge) + setattr(cls, "setContactEdge", setContactEdge) + + def getContactEdge(self): + if self.edge: + return self.edge.getValue() + return None + setattr(cls, "getContactEdge", getContactEdge) + +if "coil" in PLCOpenClasses: + cls = PLCOpenClasses["coil"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setCoilStorage(self, edge): + if not self.storage: + self.storage = PLCOpenClasses["storageModifierType"]() + self.storage.setValue(edge) + setattr(cls, "setCoilStorage", setCoilStorage) + + def getCoilStorage(self): + if self.storage: + return self.storage.getValue() + return None + setattr(cls, "getCoilStorage", getCoilStorage) + +if "rightPowerRail" in PLCOpenClasses: + cls = PLCOpenClasses["rightPowerRail"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "step" in PLCOpenClasses: + cls = PLCOpenClasses["step"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "transition" in PLCOpenClasses: + cls = PLCOpenClasses["transition"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setConditionContent(self, type, value): + if not self.condition: + self.addCondition() + if type == "reference": + condition = PLCOpenClasses["condition_reference"]() + condition.setName(value) + elif type == "inline": + condition = PLCOpenClasses["condition_inline"]() + condition.setContent("ST", PLCOpenClasses["formattedText"]()) + condition.setText(value) + self.condition.setContent(type, condition) + setattr(cls, "setConditionContent", setConditionContent) - def removePouElement(self, name): - found = False - for idx, element in enumerate(self.pous.getPou()): - if element.getName() == name: - self.pous.removePou(idx) - found = True - break - if not found: - raise ValueError, "\"%s\" POU doesn't exist !!!"%name - setattr(cls, "removePouElement", removePouElement) - - def setBodyType(self, type): - if type == "IL": - self.body.setContent("IL", PLCOpenClasses["formattedText"]()) - elif type == "ST": - self.body.setContent("ST", PLCOpenClasses["formattedText"]()) - elif type == "LD": - self.body.setContent("LD", PLCOpenClasses["body_LD"]()) - elif type == "FBD": - self.body.setContent("FBD", PLCOpenClasses["body_FBD"]()) - elif type == "SFC": - self.body.setContent("SFC", PLCOpenClasses["body_SFC"]()) - else: - raise ValueError, "%s isn't a valid body type!"%type - - def getBodyType(self): - return self.body.getContent()["name"] - - def addInstance(self, name, instance): - self.body.appendContentInstance(name, instance) - - def getInstances(self): - return self.body.getContentInstances() - - def getInstance(self, id): - return self.body.getContentInstance(id) - - def getRandomInstance(self, exclude): - return self.body.getContentRandomInstance(exclude) - - def getInstanceByName(self, name): - return self.body.getContentInstanceByName(name) - - def removeInstance(self, id): - self.body.removeContentInstance(id) - - def setText(self, text): - self.body.setText(text) - - def getText(self): - return self.body.getText() - setattr(cls, "getText", getText) - - if "pous_pou" in PLCOpenClasses: - cls = PLCOpenClasses["pous_pou"] - - setattr(cls, "setBodyType", setBodyType) - setattr(cls, "getBodyType", getBodyType) - setattr(cls, "addInstance", addInstance) - setattr(cls, "getInstances", getInstances) - setattr(cls, "getInstance", getInstance) - setattr(cls, "getRandomInstance", getRandomInstance) - setattr(cls, "getInstanceByName", getInstanceByName) - setattr(cls, "removeInstance", removeInstance) - setattr(cls, "setText", setText) - setattr(cls, "getText", getText) - - def getVars(self): - vars = [] - reverse_types = {} - for name, value in VarTypes.items(): - reverse_types[value] = name - for varlist in self.interface.getContent(): - vars.append((reverse_types[varlist["name"]], varlist["value"])) - return vars - setattr(cls, "getVars", getVars) - - def setVars(self, vars): - self.interface.setContent([]) - for vartype, varlist in vars: - self.interface.appendContent(VarTypes[vartype], varlist) - setattr(cls, "setVars", setVars) - - def addTransition(self, name, type): - if not self.transitions: - self.addTransitions() - self.transitions.setTransition([]) - transition = PLCOpenClasses["transitions_transition"]() - transition.setName(name) - transition.setBodyType(type) - self.transitions.appendTransition(transition) - setattr(cls, "addTransition", addTransition) - - def getTransition(self, name): - if self.transitions: - for transition in self.transitions.getTransition(): - if transition.getName() == name: - return transition - return None - setattr(cls, "getTransition", getTransition) - - def getTransitionList(self): - if self.transitions: - return self.transitions.getTransition() - return [] - setattr(cls, "getTransitionList", getTransitionList) - - def removeTransition(self, name): - if self.transitions: - transitions = self.transitions.getTransition() - i = 0 - removed = False - while i < len(transitions) and not removed: - if transitions[i].getName() == name: - transitions.removeTransition(i) - removed = True - i += 1 - if not removed: - raise ValueError, "Transition with name %s doesn't exists!"%name - setattr(cls, "removeTransition", removeTransition) - - def addAction(self, name, type): - if not self.actions: - self.addActions() - self.actions.setAction([]) - action = PLCOpenClasses["actions_action"]() - action.setName(name) - action.setBodyType(type) - self.actions.appendAction(action) - setattr(cls, "addAction", addAction) - - def getAction(self, name): - if self.actions: - for action in self.actions.getAction(): - if action.getName() == name: - return action - return None - setattr(cls, "getAction", getAction) - - def getActionList(self): - if self.actions: - return self.actions.getAction() - return [] - setattr(cls, "getActionList", getActionList) - - def removeAction(self, name): - if self.actions: - actions = self.actions.getAction() - i = 0 - removed = False - while i < len(actions) and not removed: - if actions[i].getName() == name: - actions.removeAction(i) - removed = True - i += 1 - if not removed: - raise ValueError, "Action with name %s doesn't exists!"%name - setattr(cls, "removeAction", removeAction) - - if "transitions_transition" in PLCOpenClasses: - cls = PLCOpenClasses["transitions_transition"] - - setattr(cls, "setBodyType", setBodyType) - setattr(cls, "getBodyType", getBodyType) - setattr(cls, "addInstance", addInstance) - setattr(cls, "getInstances", getInstances) - setattr(cls, "getInstance", getInstance) - setattr(cls, "getRandomInstance", getRandomInstance) - setattr(cls, "getInstanceByName", getInstanceByName) - setattr(cls, "removeInstance", removeInstance) - setattr(cls, "setText", setText) - setattr(cls, "getText", getText) - - if "actions_action" in PLCOpenClasses: - cls = PLCOpenClasses["actions_action"] - - setattr(cls, "setBodyType", setBodyType) - setattr(cls, "getBodyType", getBodyType) - setattr(cls, "addInstance", addInstance) - setattr(cls, "getInstances", getInstances) - setattr(cls, "getInstance", getInstance) - setattr(cls, "getRandomInstance", getRandomInstance) - setattr(cls, "getInstanceByName", getInstanceByName) - setattr(cls, "removeInstance", removeInstance) - setattr(cls, "setText", setText) - setattr(cls, "getText", getText) - - if "body" in PLCOpenClasses: - cls = PLCOpenClasses["body"] - - def appendContentInstance(self, name, instance): - if self.content["name"] in ["LD","FBD","SFC"]: - self.content["value"].appendContent(name, instance) + def getConditionContent(self): + if self.condition: + content = self.condition.getContent() + values = {"type" : content["name"]} + if values["type"] == "reference": + values["value"] = content["value"].getName() + elif values["type"] == "inline": + values["value"] = content["value"].getText() + return values + return "" + setattr(cls, "getConditionContent", getConditionContent) + +if "selectionDivergence" in PLCOpenClasses: + cls = PLCOpenClasses["selectionDivergence"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "selectionConvergence" in PLCOpenClasses: + cls = PLCOpenClasses["selectionConvergence"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "simultaneousDivergence" in PLCOpenClasses: + cls = PLCOpenClasses["simultaneousDivergence"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "simultaneousDivergence" in PLCOpenClasses: + cls = PLCOpenClasses["simultaneousConvergence"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "jumpStep" in PLCOpenClasses: + cls = PLCOpenClasses["jumpStep"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "actionBlock_action" in PLCOpenClasses: + cls = PLCOpenClasses["actionBlock_action"] + + def setQualifierValue(self, value): + if self.qualifier: + self.qualifier.setValue(value) + setattr(cls, "setQualifierValue", setQualifierValue) + + def getQualifierValue(self): + if self.qualifier: + return self.qualifier.getValue() + return None + setattr(cls, "getQualifierValue", getQualifierValue) + + def setReferenceName(self, name): + if self.reference: + self.reference.setName(name) + setattr(cls, "setReferenceName", setReferenceName) + + def getReferenceName(self): + if self.reference: + return self.reference.getName() + return None + setattr(cls, "getReferenceName", getReferenceName) + + def setInlineContent(self, content): + if self.inline: + self.inline.setContent("ST", PLCOpenClasses["formattedText"]()) + self.inline.setText(content) + setattr(cls, "setInlineContent", setInlineContent) + + def getInlineContent(self): + if self.inline: + return self.inline.getText() + return None + setattr(cls, "getInlineContent", getInlineContent) + +if "actionBlock" in PLCOpenClasses: + cls = PLCOpenClasses["actionBlock"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setActions(self, actions): + self.action = [] + for params in actions: + action = PLCOpenClasses["actionBlock_action"]() + action.addQualifier() + action.setQualifierValue(params["qualifier"]) + if params["type"] == "reference": + action.addReference() + action.setReferenceName(params["value"]) else: - raise TypeError, "%s body don't have instances!"%self.content["name"] - setattr(cls, "appendContentInstance", appendContentInstance) - - def getContentInstances(self): - if self.content["name"] in ["LD","FBD","SFC"]: - instances = [] - for element in self.content["value"].getContent(): - instances.append(element["value"]) - return instances - else: - raise TypeError, "%s body don't have instances!"%self.content["name"] - setattr(cls, "getContentInstances", getContentInstances) - - def getContentInstance(self, id): - if self.content["name"] in ["LD","FBD","SFC"]: - for element in self.content["value"].getContent(): - if element["value"].getLocalId() == id: - return element["value"] - return None - else: - raise TypeError, "%s body don't have instances!"%self.content["name"] - setattr(cls, "getContentInstance", getContentInstance) - - def getContentRandomInstance(self, exclude): - if self.content["name"] in ["LD","FBD","SFC"]: - for element in self.content["value"].getContent(): - if element["value"].getLocalId() not in exclude: - return element["value"] - return None - else: - raise TypeError, "%s body don't have instances!"%self.content["name"] - setattr(cls, "getContentRandomInstance", getContentRandomInstance) - - def getContentInstanceByName(self, name): - if self.content["name"] in ["LD","FBD","SFC"]: - for element in self.content["value"].getContent(): - if element["value"].getLocalId() == name: - return element["value"] - else: - raise TypeError, "%s body don't have instances!"%self.content["name"] - setattr(cls, "getContentInstanceByName", getContentInstanceByName) - - def removeContentInstance(self, id): - if self.content["name"] in ["LD","FBD","SFC"]: - i = 0 - removed = False - elements = self.content["value"].getContent() - while i < len(elements) and not removed: - if elements[i]["value"].getLocalId() == id: - self.content["value"].removeContent(i) - removed = True - i += 1 - if not removed: - raise ValueError, "Instance with id %d doesn't exists!"%id - else: - raise TypeError, "%s body don't have instances!"%self.content["name"] - setattr(cls, "removeContentInstance", removeContentInstance) - - def setText(self, text): - if self.content["name"] in ["IL","ST"]: - self.content["value"].setText(text) - else: - raise TypeError, "%s body don't have text!"%self.content["name"] - setattr(cls, "setText", setText) - - def getText(self): - if self.content["name"] in ["IL","ST"]: - return self.content["value"].getText() - else: - raise TypeError, "%s body don't have text!"%self.content["name"] - setattr(cls, "getText", getText) - - def getX(self): - return self.position.getX() - - def getY(self): - return self.position.getY() - - def setX(self, x): - self.position.setX(x) - - def setY(self, y): - self.position.setY(y) - - if "comment" in PLCOpenClasses: - cls = PLCOpenClasses["comment"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setContentText(self, text): - self.content.setText(text) - setattr(cls, "setContentText", setContentText) - - def getContentText(self): - return self.content.getText() - setattr(cls, "getContentText", getContentText) - - if "block" in PLCOpenClasses: - cls = PLCOpenClasses["block"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "inputVariables_variable" in PLCOpenClasses: - cls = PLCOpenClasses["inputVariables_variable"] - - def setConnectorEdge(self, edge): - if not self.edge: - self.edge = PLCOpenClasses["edgeModifierType"]() - self.edge.setValue(edge) - setattr(cls, "setConnectorEdge", setConnectorEdge) - - def getConnectorEdge(self): - if self.edge: - return self.edge.getValue() - return None - setattr(cls, "getConnectorEdge", getConnectorEdge) - - if "outputVariables_variable" in PLCOpenClasses: - cls = PLCOpenClasses["outputVariables_variable"] - - def setConnectorEdge(self, edge): - if not self.edge: - self.edge = PLCOpenClasses["edgeModifierType"]() - self.edge.setValue(edge) - setattr(cls, "setConnectorEdge", setConnectorEdge) - - def getConnectorEdge(self): - if self.edge: - return self.edge.getValue() - return None - setattr(cls, "getConnectorEdge", getConnectorEdge) - - if "leftPowerRail" in PLCOpenClasses: - cls = PLCOpenClasses["leftPowerRail"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "contact" in PLCOpenClasses: - cls = PLCOpenClasses["contact"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setContactEdge(self, edge): - if not self.edge: - self.edge = PLCOpenClasses["edgeModifierType"]() - self.edge.setValue(edge) - setattr(cls, "setContactEdge", setContactEdge) - - def getContactEdge(self): - if self.edge: - return self.edge.getValue() - return None - setattr(cls, "getContactEdge", getContactEdge) - - if "coil" in PLCOpenClasses: - cls = PLCOpenClasses["coil"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setCoilStorage(self, edge): - if not self.storage: - self.storage = PLCOpenClasses["storageModifierType"]() - self.storage.setValue(edge) - setattr(cls, "setCoilStorage", setCoilStorage) - - def getCoilStorage(self): - if self.storage: - return self.storage.getValue() - return None - setattr(cls, "getCoilStorage", getCoilStorage) - - if "rightPowerRail" in PLCOpenClasses: - cls = PLCOpenClasses["rightPowerRail"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "step" in PLCOpenClasses: - cls = PLCOpenClasses["step"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "transition" in PLCOpenClasses: - cls = PLCOpenClasses["transition"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setConditionContent(self, type, value): - if not self.condition: - self.addCondition() - if type == "reference": - condition = PLCOpenClasses["condition_reference"]() - condition.setName(value) - elif type == "inline": - condition = PLCOpenClasses["condition_inline"]() - condition.setContent("ST", PLCOpenClasses["formattedText"]()) - condition.setText(value) - self.condition.setContent(type, condition) - setattr(cls, "setConditionContent", setConditionContent) - - def getConditionContent(self): - if self.condition: - content = self.condition.getContent() - values = {"type" : content["name"]} - if values["type"] == "reference": - values["value"] = content["value"].getName() - elif values["type"] == "inline": - values["value"] = content["value"].getText() - return values - return "" - setattr(cls, "getConditionContent", getConditionContent) - - if "selectionDivergence" in PLCOpenClasses: - cls = PLCOpenClasses["selectionDivergence"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "selectionConvergence" in PLCOpenClasses: - cls = PLCOpenClasses["selectionConvergence"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "simultaneousDivergence" in PLCOpenClasses: - cls = PLCOpenClasses["simultaneousDivergence"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "simultaneousDivergence" in PLCOpenClasses: - cls = PLCOpenClasses["simultaneousConvergence"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "jumpStep" in PLCOpenClasses: - cls = PLCOpenClasses["jumpStep"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "actionBlock_action" in PLCOpenClasses: - cls = PLCOpenClasses["actionBlock_action"] - - def setQualifierValue(self, value): - if self.qualifier: - self.qualifier.setValue(value) - setattr(cls, "setQualifierValue", setQualifierValue) - - def getQualifierValue(self): - if self.qualifier: - return self.qualifier.getValue() - return None - setattr(cls, "getQualifierValue", getQualifierValue) - - def setReferenceName(self, name): - if self.reference: - self.reference.setName(name) - setattr(cls, "setReferenceName", setReferenceName) - - def getReferenceName(self): - if self.reference: - return self.reference.getName() - return None - setattr(cls, "getReferenceName", getReferenceName) - - def setInlineContent(self, content): - if self.inline: - self.inline.setContent("ST", PLCOpenClasses["formattedText"]()) - self.inline.setText(content) - setattr(cls, "setInlineContent", setInlineContent) - - def getInlineContent(self): - if self.inline: - return self.inline.getText() - return None - setattr(cls, "getInlineContent", getInlineContent) - - if "actionBlock" in PLCOpenClasses: - cls = PLCOpenClasses["actionBlock"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setActions(self, actions): - self.action = [] - for params in actions: - action = PLCOpenClasses["actionBlock_action"]() - action.addQualifier() - action.setQualifierValue(params["qualifier"]) - if params["type"] == "reference": - action.addReference() - action.setReferenceName(params["value"]) - else: - action.addInline() - action.setInlineContent(params["value"]) - if "duration" in params: - action.setDuration(params["duration"]) - if "indicator" in params: - action.setIndicator(params["indicator"]) - self.action.append(action) - setattr(cls, "setActions", setActions) - - def getActions(self): - actions = [] - for action in self.action: - params = {} - params["qualifier"] = action.getQualifierValue() - if action.getReference(): - params["type"] = "reference" - params["value"] = action.getReferenceName() - elif action.getInline(): - params["type"] = "inline" - params["value"] = action.getInlineContent() - duration = action.getDuration() - if duration: - params["duration"] = duration - indicator = action.getIndicator() - if indicator: - params["indicator"] = indicator - actions.append(params) - return actions - setattr(cls, "getActions", getActions) - - if "inVariable" in PLCOpenClasses: - cls = PLCOpenClasses["inVariable"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setConnectorEdge(self, edge): - if not self.edge: - self.edge = PLCOpenClasses["edgeModifierType"]() - self.edge.setValue(edge) - setattr(cls, "setConnectorEdge", setConnectorEdge) - - def getConnectorEdge(self): - if self.edge: - return self.edge.getValue() - return None - setattr(cls, "getConnectorEdge", getConnectorEdge) - - if "outVariable" in PLCOpenClasses: - cls = PLCOpenClasses["outVariable"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setConnectorEdge(self, edge): - if not self.edge: - self.edge = PLCOpenClasses["edgeModifierType"]() - self.edge.setValue(edge) - setattr(cls, "setConnectorEdge", setConnectorEdge) - - def getConnectorEdge(self): - if self.edge: - return self.edge.getValue() - return None - setattr(cls, "getConnectorEdge", getConnectorEdge) - - if "inOutVariable" in PLCOpenClasses: - cls = PLCOpenClasses["inOutVariable"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - def setInputEdge(self, edge): - if not self.edgeIn: - self.edgeIn = PLCOpenClasses["edgeModifierType"]() - self.edgeIn.setValue(edge) - setattr(cls, "setInputEdge", setInputEdge) - - def getInputEdge(self): - if self.edgeIn: - return self.edgeIn.getValue() - return None - setattr(cls, "getInputEdge", getInputEdge) - - def setOutputEdge(self, edge): - if not self.edgeOut: - self.edgeOut = PLCOpenClasses["edgeModifierType"]() - self.edgeOut.setValue(edge) - setattr(cls, "setInputEdge", setInputEdge) - - def getOutputEdge(self): - if self.edgeOut: - return self.edgeOut.getValue() - return None - setattr(cls, "getOutputEdge", getOutputEdge) - - if "continuation" in PLCOpenClasses: - cls = PLCOpenClasses["continuation"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "connector" in PLCOpenClasses: - cls = PLCOpenClasses["connector"] - setattr(cls, "getX", getX) - setattr(cls, "getY", getY) - setattr(cls, "setX", setX) - setattr(cls, "setY", setY) - - if "connection" in PLCOpenClasses: - cls = PLCOpenClasses["connection"] - - def setPoints(self, points): - self.position = [] - for point in points: - position = PLCOpenClasses["position"]() - position.setX(point.x) - position.setY(point.y) - self.position.append(position) - setattr(cls, "setPoints", setPoints) - - def getPoints(self): - points = [] - for position in self.position: - points.append((position.getX(),position.getY())) - return points - setattr(cls, "getPoints", getPoints) - - if "connectionPointIn" in PLCOpenClasses: - cls = PLCOpenClasses["connectionPointIn"] - - def setRelPosition(self, x, y): - self.relPosition = PLCOpenClasses["position"]() - self.relPosition.setX(x) - self.relPosition.setY(y) - setattr(cls, "setRelPosition", setRelPosition) - - def getRelPosition(self): - if self.relPosition: - return self.relPosition.getX(), self.relPosition.getY() - else: - return self.relPosition - setattr(cls, "getRelPosition", getRelPosition) - - def addConnection(self): - if not self.content: - self.content = {"name":"connection","value":[PLCOpenClasses["connection"]()]} - else: - self.content["value"].append(PLCOpenClasses["connection"]()) - setattr(cls, "addConnection", addConnection) - - def removeConnection(self, idx): - if self.content: - self.content["value"].pop(idx) - if len(self.content["value"]) == 0: - self.content = None - setattr(cls, "removeConnection", removeConnection) - - def removeConnections(self): - if self.content: - self.content = None - setattr(cls, "removeConnections", removeConnections) - - def getConnections(self): - if self.content: - return self.content["value"] - setattr(cls, "getConnections", getConnections) - - def setConnectionId(self, idx, id): - if self.content: - self.content["value"][idx].setRefLocalId(id) - setattr(cls, "setConnectionId", setConnectionId) - - def getConnectionId(self, idx): - if self.content: - return self.content["value"][idx].getRefLocalId() - return None - setattr(cls, "getConnectionId", getConnectionId) - - def setConnectionPoints(self, idx, points): - if self.content: - self.content["value"][idx].setPoints(points) - setattr(cls, "setConnectionPoints", setConnectionPoints) - - def getConnectionPoints(self, idx): - if self.content: - return self.content["value"][idx].getPoints() - return None - setattr(cls, "getConnectionPoints", getConnectionPoints) - - if "connectionPointOut" in PLCOpenClasses: - cls = PLCOpenClasses["connectionPointOut"] - - def setRelPosition(self, x, y): - self.relPosition = PLCOpenClasses["position"]() - self.relPosition.setX(x) - self.relPosition.setY(y) - setattr(cls, "setRelPosition", setRelPosition) - - def getRelPosition(self): - if self.relPosition: - return self.relPosition.getX(), self.relPosition.getY() + action.addInline() + action.setInlineContent(params["value"]) + if "duration" in params: + action.setDuration(params["duration"]) + if "indicator" in params: + action.setIndicator(params["indicator"]) + self.action.append(action) + setattr(cls, "setActions", setActions) + + def getActions(self): + actions = [] + for action in self.action: + params = {} + params["qualifier"] = action.getQualifierValue() + if action.getReference(): + params["type"] = "reference" + params["value"] = action.getReferenceName() + elif action.getInline(): + params["type"] = "inline" + params["value"] = action.getInlineContent() + duration = action.getDuration() + if duration: + params["duration"] = duration + indicator = action.getIndicator() + if indicator: + params["indicator"] = indicator + actions.append(params) + return actions + setattr(cls, "getActions", getActions) + +if "inVariable" in PLCOpenClasses: + cls = PLCOpenClasses["inVariable"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setConnectorEdge(self, edge): + if not self.edge: + self.edge = PLCOpenClasses["edgeModifierType"]() + self.edge.setValue(edge) + setattr(cls, "setConnectorEdge", setConnectorEdge) + + def getConnectorEdge(self): + if self.edge: + return self.edge.getValue() + return None + setattr(cls, "getConnectorEdge", getConnectorEdge) + +if "outVariable" in PLCOpenClasses: + cls = PLCOpenClasses["outVariable"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setConnectorEdge(self, edge): + if not self.edge: + self.edge = PLCOpenClasses["edgeModifierType"]() + self.edge.setValue(edge) + setattr(cls, "setConnectorEdge", setConnectorEdge) + + def getConnectorEdge(self): + if self.edge: + return self.edge.getValue() + return None + setattr(cls, "getConnectorEdge", getConnectorEdge) + +if "inOutVariable" in PLCOpenClasses: + cls = PLCOpenClasses["inOutVariable"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + + def setInputEdge(self, edge): + if not self.edgeIn: + self.edgeIn = PLCOpenClasses["edgeModifierType"]() + self.edgeIn.setValue(edge) + setattr(cls, "setInputEdge", setInputEdge) + + def getInputEdge(self): + if self.edgeIn: + return self.edgeIn.getValue() + return None + setattr(cls, "getInputEdge", getInputEdge) + + def setOutputEdge(self, edge): + if not self.edgeOut: + self.edgeOut = PLCOpenClasses["edgeModifierType"]() + self.edgeOut.setValue(edge) + setattr(cls, "setInputEdge", setInputEdge) + + def getOutputEdge(self): + if self.edgeOut: + return self.edgeOut.getValue() + return None + setattr(cls, "getOutputEdge", getOutputEdge) + +if "continuation" in PLCOpenClasses: + cls = PLCOpenClasses["continuation"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "connector" in PLCOpenClasses: + cls = PLCOpenClasses["connector"] + setattr(cls, "getX", getX) + setattr(cls, "getY", getY) + setattr(cls, "setX", setX) + setattr(cls, "setY", setY) + +if "connection" in PLCOpenClasses: + cls = PLCOpenClasses["connection"] + + def setPoints(self, points): + self.position = [] + for point in points: + position = PLCOpenClasses["position"]() + position.setX(point.x) + position.setY(point.y) + self.position.append(position) + setattr(cls, "setPoints", setPoints) + + def getPoints(self): + points = [] + for position in self.position: + points.append((position.getX(),position.getY())) + return points + setattr(cls, "getPoints", getPoints) + +if "connectionPointIn" in PLCOpenClasses: + cls = PLCOpenClasses["connectionPointIn"] + + def setRelPosition(self, x, y): + self.relPosition = PLCOpenClasses["position"]() + self.relPosition.setX(x) + self.relPosition.setY(y) + setattr(cls, "setRelPosition", setRelPosition) + + def getRelPosition(self): + if self.relPosition: + return self.relPosition.getX(), self.relPosition.getY() + else: return self.relPosition - setattr(cls, "getRelPosition", getRelPosition) - - if "value" in PLCOpenClasses: - cls = PLCOpenClasses["value"] - - def setValue(self, value): - try: - value = eval(value) - except: - pass - if type(value) == ListType: - arrayValue = PLCOpenClasses["value_arrayValue"]() - arrayValue.setValue(value) - self.content = {"name":"arrayValue","value":arrayValue} - elif type(value) == DictType: - structValue = PLCOpenClasses["value_structValue"]() - structValue.setValue(value) - self.content = {"name":"structValue","value":structValue} - else: - simpleValue = PLCOpenClasses["value_simpleValue"]() - simpleValue.setValue(str(value)) - self.content = {"name":"simpleValue","value":simpleValue} - setattr(cls, "setValue", setValue) - - def getValue(self): - value = self.content["value"].getValue() - try: - value = eval(value) - except: - pass - return value - setattr(cls, "getValue", getValue) - - if "value_arrayValue" in PLCOpenClasses: - cls = PLCOpenClasses["value_arrayValue"] - - def setValue(self, array): - self.value = [] - for value in array: - element = PLCOpenClasses["arrayValue_value"]() - element.setValue(value) - self.value.append(element) - setattr(cls, "setValue", setValue) - - def getValue(self): - return [element.getValue() for element in self.value] - setattr(cls, "getValue", getValue) - - if "value_structValue" in PLCOpenClasses: - cls = PLCOpenClasses["value_structValue"] - - def setValue(self, dict): - self.value = [] - for name,value in dict.items(): - element = PLCOpenClasses["structValue_value"]() - element.setMember(name) - element.setValue(value) - self.value.append(element) - setattr(cls, "setValue", setValue) - - def getValue(self): - value = {} - for element in self.value: - value[element.getMember()] = element.getValue() - return value - setattr(cls, "getValue", getValue) - -if sys: - sys.stdout = HolePseudoFile() -xsdschema = pyxsval.parseAndValidateXmlSchema("plcopen/TC6_XML_V10_B.xsd") -if sys: - sys.stdout = sys.__stdout__ -Generate_classes(xsdschema.getTree(), None) - -PLCOpenClasses = {} -PLCOpenTypes = {} -#for classname, classe in classes.items(): -# print "%s : %s\n"%(classname, str(classe)) -"""classnames = classes.keys() -classnames.sort() -for classname in classnames: - print classname""" -for classe in classes.keys(): - CreateClass(classe) -Generate_Methods() + setattr(cls, "getRelPosition", getRelPosition) + + def addConnection(self): + if not self.content: + self.content = {"name":"connection","value":[PLCOpenClasses["connection"]()]} + else: + self.content["value"].append(PLCOpenClasses["connection"]()) + setattr(cls, "addConnection", addConnection) + + def removeConnection(self, idx): + if self.content: + self.content["value"].pop(idx) + if len(self.content["value"]) == 0: + self.content = None + setattr(cls, "removeConnection", removeConnection) + + def removeConnections(self): + if self.content: + self.content = None + setattr(cls, "removeConnections", removeConnections) + + def getConnections(self): + if self.content: + return self.content["value"] + setattr(cls, "getConnections", getConnections) + + def setConnectionId(self, idx, id): + if self.content: + self.content["value"][idx].setRefLocalId(id) + setattr(cls, "setConnectionId", setConnectionId) + + def getConnectionId(self, idx): + if self.content: + return self.content["value"][idx].getRefLocalId() + return None + setattr(cls, "getConnectionId", getConnectionId) + + def setConnectionPoints(self, idx, points): + if self.content: + self.content["value"][idx].setPoints(points) + setattr(cls, "setConnectionPoints", setConnectionPoints) + + def getConnectionPoints(self, idx): + if self.content: + return self.content["value"][idx].getPoints() + return None + setattr(cls, "getConnectionPoints", getConnectionPoints) + +if "connectionPointOut" in PLCOpenClasses: + cls = PLCOpenClasses["connectionPointOut"] + + def setRelPosition(self, x, y): + self.relPosition = PLCOpenClasses["position"]() + self.relPosition.setX(x) + self.relPosition.setY(y) + setattr(cls, "setRelPosition", setRelPosition) + + def getRelPosition(self): + if self.relPosition: + return self.relPosition.getX(), self.relPosition.getY() + return self.relPosition + setattr(cls, "getRelPosition", getRelPosition) + +if "value" in PLCOpenClasses: + cls = PLCOpenClasses["value"] + + def setValue(self, value): + try: + value = eval(value) + except: + pass + if type(value) == ListType: + arrayValue = PLCOpenClasses["value_arrayValue"]() + arrayValue.setValue(value) + self.content = {"name":"arrayValue","value":arrayValue} + elif type(value) == DictType: + structValue = PLCOpenClasses["value_structValue"]() + structValue.setValue(value) + self.content = {"name":"structValue","value":structValue} + else: + simpleValue = PLCOpenClasses["value_simpleValue"]() + simpleValue.setValue(str(value)) + self.content = {"name":"simpleValue","value":simpleValue} + setattr(cls, "setValue", setValue) + + def getValue(self): + value = self.content["value"].getValue() + try: + value = eval(value) + except: + pass + return value + setattr(cls, "getValue", getValue) + +if "value_arrayValue" in PLCOpenClasses: + cls = PLCOpenClasses["value_arrayValue"] + + def setValue(self, array): + self.value = [] + for value in array: + element = PLCOpenClasses["arrayValue_value"]() + element.setValue(value) + self.value.append(element) + setattr(cls, "setValue", setValue) + + def getValue(self): + return [element.getValue() for element in self.value] + setattr(cls, "getValue", getValue) + +if "value_structValue" in PLCOpenClasses: + cls = PLCOpenClasses["value_structValue"] + + def setValue(self, dict): + self.value = [] + for name,value in dict.items(): + element = PLCOpenClasses["structValue_value"]() + element.setMember(name) + element.setValue(value) + self.value.append(element) + setattr(cls, "setValue", setValue) + + def getValue(self): + value = {} + for element in self.value: + value[element.getMember()] = element.getValue() + return value + setattr(cls, "getValue", getValue) diff -r e9d01d824086 -r 93bc4c2cf376 xmlclass/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xmlclass/.cvsignore Wed Feb 07 18:43:32 2007 +0100 @@ -0,0 +1,1 @@ +*.pyc diff -r e9d01d824086 -r 93bc4c2cf376 xmlclass/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xmlclass/__init__.py Wed Feb 07 18:43:32 2007 +0100 @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C): Edouard TISSERANT and Laurent BESSARD +# +#See COPYING file for copyrights details. +# +#This library is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public +#License as published by the Free Software Foundation; either +#version 2.1 of the License, or (at your option) any later version. +# +#This library is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +#Lesser General Public License for more details. +# +#You should have received a copy of the GNU General Public +#License along with this library; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Package initialisation + +from xmlclass import * diff -r e9d01d824086 -r 93bc4c2cf376 xmlclass/xmlclass.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xmlclass/xmlclass.py Wed Feb 07 18:43:32 2007 +0100 @@ -0,0 +1,773 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor +#based on the plcopen standard. +# +#Copyright (C): Edouard TISSERANT and Laurent BESSARD +# +#See COPYING file for copyrights details. +# +#This library is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public +#License as published by the Free Software Foundation; either +#version 2.1 of the License, or (at your option) any later version. +# +#This library is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +#Lesser General Public License for more details. +# +#You should have received a copy of the GNU General Public +#License along with this library; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from xml.dom import minidom +import sys,re +from types import * +from datetime import * + +""" +Time and date definitions +""" +TimeType = time(0,0,0).__class__ +DateType = date(1,1,1).__class__ +DateTimeType = datetime(1,1,1,0,0,0).__class__ + +""" +Regular expression models for extracting dates and times from a string +""" +time_model = re.compile('([0-9]{2}):([0-9]{2}):([0-9]{2})') +date_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})') +datetime_model = re.compile('([0-9]{4})-([0-9]{2})-([0-9]{2})[ T]([0-9]{2}):([0-9]{2}):([0-9]{2})') + +""" +Dictionaries for stocking Classes and Types created from XML +""" +XMLClasses = {} + +""" +This function calculates the number of whitespace for indentation +""" +def getIndent(indent, balise): + first = indent * 2 + second = first + len(balise) + 1 + return "\t".expandtabs(first), "\t".expandtabs(second) + +""" +This function opens the xsd file and generate the classes from the xml tree +""" +def GenerateClassesFromXSD(filename): + xsdfile = open(filename, 'r') + Generate_xsd_classes(minidom.parse(xsdfile), None) + xsdfile.close() + +""" +This function recursively creates a definition of the classes and their attributes +for plcopen from the xsd file of plcopen opened in a DOM model +""" +def Generate_xsd_classes(tree, parent, sequence = False): + attributes = {} + inheritance = [] + if sequence: + order = [] + # The lists of attributes and inheritance of the node are generated from the childrens + for node in tree.childNodes: + # We make fun of #text elements and all other tags that don't are xsd tags + if node.nodeName != "#text" and node.nodeName.startswith("xsd:"): + recursion = False + name = node.nodeName[4:].encode() + + # This tags defines an attribute of the class + if name in ["element", "attribute"]: + nodename = GetAttributeValue(node._attrs["name"]) + if "type" in node._attrs: + nodetype = GetAttributeValue(node._attrs["type"]) + if nodetype.startswith("xsd"): + nodetype = nodetype.replace("xsd", "bse") + elif nodetype.startswith("ppx"): + nodetype = nodetype.replace("ppx", "cls") + else: + # The type of attribute is defines in the child tree so we generate a new class + # No name is defined so we create one from nodename and parent class name + # (because some different nodes can have the same name) + if parent: + classname = "%s_%s"%(parent, nodename) + else: + classname = nodename + Generate_xsd_classes(node, classname) + nodetype = "cls:%s"%classname + if name == "attribute": + if "use" in node._attrs: + use = GetAttributeValue(node._attrs["use"]) + else: + use = "optional" + if name == "element": + # If a tag can be written more than one time we define a list attribute + if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded": + nodetype = "%s[]"%nodetype + if "minOccurs" in node._attrs and GetAttributeValue(node._attrs["minOccurs"]) == "0": + use = "optional" + else: + use = "required" + attributes[nodename] = (nodetype, name, use) + if sequence: + order.append(nodename) + + # This tag defines a new class + elif name == "complexType" or name == "simpleType": + if "name" in node._attrs: + classname = GetAttributeValue(node._attrs["name"]) + super, attrs = Generate_xsd_classes(node, classname) + else: + classname = parent + super, attrs = Generate_xsd_classes(node, classname.split("_")[-1]) + # When all attributes and inheritances have been extracted, the + # values are added in the list of classes to create + if classname not in XMLClasses: + XMLClasses[classname] = (super, attrs) + elif XMLClasses[classname] != (super, attrs): + print "A different class has already got %s for name"%classname + + # This tag defines an attribute that can have different types + elif name == "choice": + super, attrs = Generate_xsd_classes(node, parent) + if "ref" in attrs.keys(): + choices = attrs + else: + choices = {} + for attr, (attr_type, xml_type, write_type) in attrs.items(): + choices[attr] = attr_type + if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded": + attributes["multichoice_content"] = choices + if sequence: + order.append("multichoice_content") + else: + attributes["choice_content"] = choices + if sequence: + order.append("choice_content") + + # This tag defines the order in which class attributes must be written + # in plcopen xml file. We have to store this order like an attribute + elif name in "sequence": + super, attrs, order = Generate_xsd_classes(node, parent, True) + if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded": + for attr, (attr_type, xml_type, write_type) in attrs.items(): + attrs[attr] = ("%s[]"%attr_type, xml_type, write_type) + if "minOccurs" in node._attrs and GetAttributeValue(node._attrs["minOccurs"]) == "0": + for attr, (attr_type, xml_type, write_type) in attrs.items(): + attrs[attr] = (attr_type, xml_type, "optional") + inheritance.extend(super) + attributes.update(attrs) + attributes["order"] = order + + # This tag defines of types + elif name == "group": + if "name" in node._attrs: + nodename = GetAttributeValue(node._attrs["name"]) + super, attrs = Generate_xsd_classes(node, None) + XMLClasses[nodename] = (super, {"group":attrs["choice_content"]}) + elif "ref" in node._attrs: + if "ref" not in attributes: + attributes["ref"] = [GetAttributeValue(node._attrs["ref"])] + else: + attributes["ref"].append(GetAttributeValue(node._attrs["ref"])) + + # This tag define a base class for the node + elif name == "extension": + super = GetAttributeValue(node._attrs["base"]) + if super.startswith("xsd"): + super = super.replace("xsd", "bse") + elif super.startswith("ppx"): + super = super.replace("ppx", "cls") + inheritance.append(super[4:]) + recursion = True + + # This tag defines a restriction on the type of attribute + elif name == "restriction": + basetype = GetAttributeValue(node._attrs["base"]) + if basetype.startswith("xsd"): + basetype = basetype.replace("xsd", "bse") + elif basetype.startswith("ppx"): + basetype = basetype.replace("ppx", "cls") + attributes["basetype"] = basetype + recursion = True + + # This tag defines an enumerated type + elif name == "enumeration": + if "enum" not in attributes: + attributes["enum"] = [GetAttributeValue(node._attrs["value"])] + else: + attributes["enum"].append(GetAttributeValue(node._attrs["value"])) + + # This tags defines a restriction on a numerical value + elif name in ["minInclusive","maxInclusive"]: + if "limit" not in attributes: + attributes["limit"] = {} + if name == "minInclusive": + attributes["limit"]["min"] = eval(GetAttributeValue(node._attrs["value"])) + elif name == "maxInclusive": + attributes["limit"]["max"] = eval(GetAttributeValue(node._attrs["value"])) + + # This tag are not important but their childrens are. The childrens are then parsed. + elif name in ["complexContent", "schema"]: + recursion = True + + # We make fun of xsd documentation + elif name in ["annotation"]: + pass + + else: + #print name + Generate_xsd_classes(node, parent) + + # Parse the childrens of node + if recursion: + super, attrs = Generate_xsd_classes(node, parent) + inheritance.extend(super) + attributes.update(attrs) + + # if sequence tag have been found, order is returned + if sequence: + return inheritance, attributes, order + else: + return inheritance, attributes +""" +Function that extracts data from a node +""" +def GetAttributeValue(attr): + if len(attr.childNodes) == 1: + return attr.childNodes[0].data.encode() + else: + return "" + +""" +Funtion that returns the Python type and default value for a given type +""" +def GetTypeInitialValue(attr_type): + type_compute = attr_type[4:].replace("[]", "") + if attr_type.startswith("bse:"): + if type_compute == "boolean": + return BooleanType, "False" + elif type_compute in ["decimal","unsignedLong","long","integer"]: + return IntType, "0" + elif type_compute in ["string","anyURI","NMTOKEN"]: + return StringType, "\"\"" + elif type_compute == "time": + return TimeType, "time(0,0,0)" + elif type_compute == "date": + return DateType, "date(1,1,1)" + elif type_compute == "dateTime": + return DateTimeType, "datetime(1,1,1,0,0,0)" + elif type_compute == "language": + return StringType, "\"en-US\"" + else: + print "Can't affect: %s"%type_compute + elif attr_type.startswith("cls:"): + if type_compute in XMLClasses: + return XMLClasses[type_compute],"%s()"%type_compute + +""" +Function that computes value from a python type (Only Boolean are critical because +there is no uppercase in plcopen) +""" +def ComputeValue(value): + if type(value) == BooleanType: + if value: + return "true" + else: + return "false" + else: + return str(value) + +""" +Function that extracts a value from a string following the xsd type given +""" +def GetComputedValue(attr_type, value): + type_compute = attr_type[4:].replace("[]", "") + if type_compute == "boolean": + if value == "true": + return True + elif value == "false": + return False + else: + raise ValueError, "\"%s\" is not a valid boolean!"%value + elif type_compute in ["decimal","unsignedLong","long","integer"]: + return int(value) + elif type_compute in ["string","anyURI","NMTOKEN","language"]: + return value + elif type_compute == "time": + result = time_model.match(value) + if result: + time_values = [int(v) for v in result.groups()] + return time(*time_values) + else: + raise ValueError, "\"%s\" is not a valid time!"%value + elif type_compute == "date": + result = date_model.match(value) + if result: + date_values = [int(v) for v in result.groups()] + return date(*date_values) + else: + raise ValueError, "\"%s\" is not a valid date!"%value + elif type_compute == "dateTime": + result = datetime_model.match(value) + if result: + datetime_values = [int(v) for v in result.groups()] + return datetime(*datetime_values) + else: + raise ValueError, "\"%s\" is not a valid datetime!"%value + else: + print "Can't affect: %s"%type_compute + return None + +""" +This is the Metaclass for PLCOpen element classes. It generates automatically +the basic useful methods for manipulate the differents attributes of the classes +""" +class MetaClass(type): + + def __init__(cls, name, bases, dict, user_classes): + super(MetaClass, cls).__init__(name, bases, {}) + #print name, bases, dict, "\n" + initialValues = {} + for attr, values in dict.items(): + if attr in ["order", "basetype"]: + pass + + # Class is a enumerated type + elif attr == "enum": + value_type, initial = GetTypeInitialValue(dict["basetype"]) + initialValues["value"] = "\"%s\""%values[0] + setattr(cls, "value", values[0]) + setattr(cls, "setValue", MetaClass.generateSetEnumMethod(cls, values, value_type)) + setattr(cls, "getValue", MetaClass.generateGetMethod(cls, "value")) + + # Class is a limited type + elif attr == "limit": + value_type, initial = GetTypeInitialValue(dict["basetype"]) + initial = 0 + if "min" in values: + initial = max(initial, values["min"]) + if "max" in values: + initial = min(initial, values["max"]) + initialValues["value"] = "%d"%initial + setattr(cls, "value", initial) + setattr(cls, "setValue", MetaClass.generateSetLimitMethod(cls, values, value_type)) + setattr(cls, "getValue", MetaClass.generateGetMethod(cls, "value")) + + # Class has an attribute that can have different value types + elif attr == "choice_content": + setattr(cls, "content", None) + initialValues["content"] = "None" + setattr(cls, "deleteContent", MetaClass.generateDeleteMethod(cls, "content")) + setattr(cls, "setContent", MetaClass.generateSetChoiceMethod(cls, values)) + setattr(cls, "getContent", MetaClass.generateGetMethod(cls, "content")) + elif attr == "multichoice_content": + setattr(cls, "content", []) + initialValues["content"] = "[]" + setattr(cls, "appendContent", MetaClass.generateAppendChoiceMethod(cls, values)) + setattr(cls, "insertContent", MetaClass.generateInsertChoiceMethod(cls, values)) + setattr(cls, "removeContent", MetaClass.generateRemoveMethod(cls, "content")) + setattr(cls, "countContent", MetaClass.generateCountMethod(cls, "content")) + setattr(cls, "setContent", MetaClass.generateSetMethod(cls, "content", ListType)) + setattr(cls, "getContent", MetaClass.generateGetMethod(cls, "content")) + + # It's an attribute of the class + else: + attrname = attr[0].upper()+attr[1:] + attr_type, xml_type, write_type = values + value_type, initial = GetTypeInitialValue(attr_type) + # Value of the attribute is a list + if attr_type.endswith("[]"): + setattr(cls, attr, []) + initialValues[attr] = "[]" + setattr(cls, "append"+attrname, MetaClass.generateAppendMethod(cls, attr, value_type)) + setattr(cls, "insert"+attrname, MetaClass.generateInsertMethod(cls, attr, value_type)) + setattr(cls, "remove"+attrname, MetaClass.generateRemoveMethod(cls, attr)) + setattr(cls, "count"+attrname, MetaClass.generateCountMethod(cls, attr)) + setattr(cls, "set"+attrname, MetaClass.generateSetMethod(cls, attr, ListType)) + else: + if write_type == "optional": + setattr(cls, attr, None) + initialValues[attr] = "None" + setattr(cls, "add"+attrname, MetaClass.generateAddMethod(cls, attr, initial, user_classes)) + setattr(cls, "delete"+attrname, MetaClass.generateDeleteMethod(cls, attr)) + else: + setattr(cls, attr, initial) + initialValues[attr] = initial + setattr(cls, "set"+attrname, MetaClass.generateSetMethod(cls, attr, value_type)) + setattr(cls, "get"+attrname, MetaClass.generateGetMethod(cls, attr)) + setattr(cls, "__init__", MetaClass.generateInitMethod(cls, bases, initialValues, user_classes)) + setattr(cls, "loadXMLTree", MetaClass.generateLoadXMLTree(cls, bases, dict, user_classes)) + setattr(cls, "generateXMLText", MetaClass.generateGenerateXMLText(cls, bases, dict)) + setattr(cls, "singleLineAttributes", True) + + """ + Method that generate the method for loading an xml tree by following the + attributes list defined + """ + def generateLoadXMLTree(cls, bases, dict, user_classes): + def loadXMLTreeMethod(self, tree): + # If class is derived, values of inheritance classes are loaded + for base in bases: + base.loadXMLTree(self, tree) + # Class is a enumerated or limited value + if "enum" in dict.keys() or "limit" in dict.keys(): + attr_value = GetAttributeValue(tree) + attr_type = dict["basetype"] + val = GetComputedValue(attr_type, attr_value) + self.setValue(val) + else: + + # Load the node attributes if they are defined in the list + for attrname, attr in tree._attrs.items(): + if attrname in dict.keys(): + attr_type, xml_type, write_type = dict[attrname] + attr_value = GetAttributeValue(attr) + if write_type != "optional" or attr_value != "": + # Extracts the value + if attr_type.startswith("bse:"): + val = GetComputedValue(attr_type, attr_value) + elif attr_type.startswith("cls:"): + val = eval("%s()"%attr_type[4:], globals().update(user_classes)) + val.loadXMLTree(attr) + setattr(self, attrname, val) + + # Load the node childs if they are defined in the list + for node in tree.childNodes: + name = node.nodeName + # We make fun of #text elements + if name != "#text": + + # Class has an attribute that can have different value types + if "choice_content" in dict.keys() and name in dict["choice_content"].keys(): + attr_type = dict["choice_content"][name] + # Extracts the value + if attr_type.startswith("bse:"): + attr_value = GetAttributeValue(node) + if write_type != "optional" or attr_value != "": + val = GetComputedValue(attr_type.replace("[]",""), attr_value) + else: + val = None + elif attr_type.startswith("cls:"): + val = eval("%s()"%attr_type[4:].replace("[]",""), globals().update(user_classes)) + val.loadXMLTree(node) + # Stock value in content attribute + if val: + if attr_type.endswith("[]"): + if self.content: + self.content["value"].append(val) + else: + self.content = {"name":name,"value":[val]} + else: + self.content = {"name":name,"value":val} + + # Class has a list of attributes that can have different value types + elif "multichoice_content" in dict.keys() and name in dict["multichoice_content"].keys(): + attr_type = dict["multichoice_content"][name] + # Extracts the value + if attr_type.startswith("bse:"): + attr_value = GetAttributeValue(node) + if write_type != "optional" or attr_value != "": + val = GetComputedValue(attr_type, attr_value) + else: + val = None + elif attr_type.startswith("cls:"): + val = eval("%s()"%attr_type[4:], globals().update(user_classes)) + val.loadXMLTree(node) + # Add to content attribute list + if val: + self.content.append({"name":name,"value":val}) + + # The node child is defined in the list + elif name in dict.keys(): + attr_type, xml_type, write_type = dict[name] + # Extracts the value + if attr_type.startswith("bse:"): + attr_value = GetAttributeValue(node) + if write_type != "optional" or attr_value != "": + val = GetComputedValue(attr_type.replace("[]",""), attr_value) + else: + val = None + elif attr_type.startswith("cls:"): + val = eval("%s()"%attr_type[4:].replace("[]",""), globals().update(user_classes)) + val.loadXMLTree(node) + # Stock value in attribute + if val: + if attr_type.endswith("[]"): + getattr(self, name).append(val) + else: + setattr(self, name, val) + return loadXMLTreeMethod + + """ + Method that generates the method for generating an xml text by following the + attributes list defined + """ + def generateGenerateXMLText(cls, bases, dict): + def generateXMLTextMethod(self, name, indent, extras = {}, derived = False): + ind1, ind2 = getIndent(indent, name) + if not derived: + text = ind1 + "<%s"%name + else: + text = "" + if len(bases) > 0: + base_extras = {} + if "order" in dict.keys(): + order = dict["order"] + else: + order = [] + if "choice_content" in dict.keys() and "choice_content" not in order: + order.append("choice_content") + if "multichoice_content" in dict.keys() and "multichoice_content" not in order: + order.append("multichoice_content") + size = 0 + first = True + for attr, value in extras.items(): + if not first and not self.singleLineAttributes: + text += "\n%s"%(ind2) + text += " %s=\"%s\""%(attr, ComputeValue(value)) + first = False + for attr, values in dict.items(): + if attr in ["order","choice_content","multichoice_content"]: + pass + elif attr in ["enum","limit"]: + if not derived: + text += ">%s\n"%(ComputeValue(self.value),name) + else: + text += ComputeValue(self.value) + return text + elif values[1] == "attribute": + value = getattr(self, attr, None) + if values[2] != "optional" or value != None: + if not first and not self.singleLineAttributes: + text += "\n%s"%(ind2) + if values[0].startswith("cls"): + if len(bases) > 0: + base_extras[attr] = value.getValue() + else: + text += " %s=\"%s\""%(attr, ComputeValue(value.getValue())) + else: + if len(bases) > 0: + base_extras[attr] = value + else: + text += " %s=\"%s\""%(attr, ComputeValue(value)) + first = False + if len(bases) > 0: + first, new_text = bases[0].generateXMLText(self, name, indent, base_extras, True) + text += new_text + else: + first = True + ind3, ind4 = getIndent(indent + 1, name) + for attr in order: + value = getattr(self, attr, None) + if attr == "choice_content": + if self.content: + if first: + text += ">\n" + first = False + value_type = dict[attr][self.content["name"]] + if value_type.startswith("bse:"): + if value_type.endswith("[]"): + for content in self.content["value"]: + text += ind1 + "<%s>%s\n"%(self.content["name"], ComputeValue(content), self.content["name"]) + else: + text += ind1 + "<%s>%s\n"%(self.content["name"], ComputeValue(self.content["value"]), self.content["name"]) + elif value_type.endswith("[]"): + for content in self.content["value"]: + text += content.generateXMLText(self.content["name"], indent + 1) + else: + text += self.content["value"].generateXMLText(self.content["name"], indent + 1) + elif attr == "multichoice_content": + if len(self.content) > 0: + for element in self.content: + if first: + text += ">\n" + first = False + value_type = dict[attr][element["name"]] + if value_type.startswith("bse:"): + text += ind1 + "<%s>%s\n"%(element["name"], ComputeValue(element["value"]), element["name"]) + else: + text += element["value"].generateXMLText(element["name"], indent + 1) + elif dict[attr][2] != "optional" or value != None: + if dict[attr][0].endswith("[]"): + if first and len(value) > 0: + text += ">\n" + first = False + for element in value: + if dict[attr][0].startswith("bse:"): + text += ind3 + "<%s>%s\n"%(attr, ComputeValue(element), attr) + else: + text += element.generateXMLText(attr, indent + 1) + else: + if first: + text += ">\n" + first = False + if dict[attr][0].startswith("bse:"): + text += ind3 + "<%s>%s\n"%(attr, ComputeValue(value), attr) + else: + text += getattr(self, attr).generateXMLText(attr, indent + 1) + if not derived: + if first: + text += "/>\n" + else: + text += ind1 + "\n"%(name) + return text + else: + return first, text + return generateXMLTextMethod + + """ + Methods that generates the different methods for setting and getting the attributes + """ + + def generateInitMethod(cls, bases, dict, user_classes): + def initMethod(self): + for base in bases: + base.__init__(self) + for attr, initial in dict.items(): + setattr(self, attr, eval(initial, globals().update(user_classes))) + return initMethod + + def generateSetMethod(cls, attr, choice_type): + def setMethod(self, value): + setattr(self, attr, value) + return setMethod + + def generateSetChoiceMethod(cls, attr_type): + def setChoiceMethod(self, name, value): + self.content = {"name":name,"value":value} + return setChoiceMethod + + def generateSetEnumMethod(cls, enum, attr_type): + def setEnumMethod(self, value): + if value in enum: + self.value = value + else: + raise ValueError, "%s is not a valid value. Must be in %s"%(value, str(enum)) + return setEnumMethod + + def generateSetLimitMethod(cls, limit, attr_type): + def setMethod(self, value): + if "min" in limit and value < limit["min"]: + raise ValueError, "%s is not a valid value. Must be greater than %d"%(value, limit["min"]) + elif "max" in limit and value > limit["max"]: + raise ValueError, "%s is not a valid value. Must be smaller than %d"%(value, limit["max"]) + else: + self.value = value + return setMethod + + def generateGetMethod(cls, attr): + def getMethod(self): + return getattr(self, attr, None) + return getMethod + + def generateAddMethod(cls, attr, initial, user_classes): + def addMethod(self): + setattr(self, attr, eval(initial, globals().update(user_classes))) + return addMethod + + def generateDeleteMethod(cls, attr): + def deleteMethod(self): + setattr(self, attr, None) + return deleteMethod + + def generateAppendMethod(cls, attr, attr_type): + def appendMethod(self, value): + getattr(self, attr).append(value) + return appendMethod + + def generateInsertMethod(cls, attr, attr_type): + def insertMethod(self, index, value): + getattr(self, attr).insert(index, value) + return insertMethod + + def generateAppendChoiceMethod(cls, choice_types): + def appendMethod(self, name, value): + self.content.append({"name":name,"value":value}) + return appendMethod + + def generateInsertChoiceMethod(cls, choice_types): + def insertMethod(self, index, name, value): + self.content.insert(index, {"name":name,"value":value}) + return insertMethod + + def generateRemoveMethod(cls, attr): + def removeMethod(self, index): + getattr(self, attr).pop(index) + return removeMethod + + def generateCountMethod(cls, attr): + def countMethod(self): + return len(getattr(self, attr)) + return countMethod + +""" +Methods that generate the classes +""" +def CreateClasses(user_classes, user_types): + for classname in XMLClasses.keys(): + CreateClass(classname, user_classes, user_types) + +def CreateClass(classname, user_classes, user_types): + # Checks that classe haven't been generated yet + if classname not in user_classes and classname not in user_types and classname in XMLClasses: + inheritance, attributes = XMLClasses[classname] + #print classe, inheritance, attributes + dict = {} + bases = [] + + # If inheritance classes haven't been generated + for base in inheritance: + if base not in user_classes: + CreateClass(base, user_classes, user_types) + bases.append(user_classes[base]) + + # Checks that all attribute types are available + for attribute, type_attribute in attributes.items(): + if attribute == "group": + user_types[classname] = type_attribute + elif attribute == "ref": + user_types[classname] = {} + for attr in type_attribute: + if attr[4:] not in user_types: + CreateClass(attr[4:], user_classes, user_types) + user_types[classname].update(user_types[attr[4:]]) + elif attribute in ["choice_content","multichoice_content"]: + element_types = {} + for attr, value in type_attribute.items(): + if attr == "ref": + for ref in type_attribute["ref"]: + if ref[4:] not in user_types: + CreateClass(ref[4:], user_classes, user_types) + element_types.update(user_types[ref[4:]]) + else: + element_types[attr] = value + dict[attribute] = element_types + else: + dict[attribute] = type_attribute + if attribute == "enum": + user_types["%s_enum"%classname] = type_attribute + elif attribute not in ["limit", "order"]: + if type_attribute[0].startswith("ppx:"): + type_compute = type_attribute[0][4:].replace("[]","") + if type_compute not in user_classes: + CreateClass(type_compute, user_classes, user_types) + if "group" not in attributes.keys() and "ref" not in attributes.keys(): + cls = MetaClass.__new__(MetaClass, classname, tuple(bases), dict) + MetaClass.__init__(cls, classname, tuple(bases), dict, user_classes) + user_classes[classname] = cls + +""" +Methods that print the classes generated +""" +def PrintClasses(): + for classname, xmlclass in XMLClasses.items(): + print "%s : %s\n"%(classname, str(xmlclass)) + +def PrintClassNames(): + classnames = XMLClasses.keys() + classnames.sort() + for classname in classnames: + print classname