etisserant@0: #!/usr/bin/env python etisserant@0: # -*- coding: utf-8 -*- etisserant@0: etisserant@0: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor etisserant@0: #based on the plcopen standard. etisserant@0: # etisserant@0: #Copyright (C): Edouard TISSERANT and Laurent BESSARD etisserant@0: # etisserant@0: #See COPYING file for copyrights details. etisserant@0: # etisserant@0: #This library is free software; you can redistribute it and/or etisserant@0: #modify it under the terms of the GNU Lesser General Public etisserant@0: #License as published by the Free Software Foundation; either etisserant@0: #version 2.1 of the License, or (at your option) any later version. etisserant@0: # etisserant@0: #This library is distributed in the hope that it will be useful, etisserant@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: #Lesser General Public License for more details. etisserant@0: # etisserant@0: #You should have received a copy of the GNU Lesser General Public etisserant@0: #License along with this library; if not, write to the Free Software etisserant@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: etisserant@0: from minixsv import pyxsval etisserant@0: import cPickle etisserant@0: import os,sys,re etisserant@0: etisserant@0: from plcopen import plcopen etisserant@0: from plcopen.structures import * etisserant@0: from graphics.GraphicCommons import * etisserant@0: from PLCGenerator import * etisserant@0: etisserant@0: [ITEM_UNEDITABLE, ITEM_PROJECT, ITEM_POU, ITEM_CLASS, ITEM_VARIABLE, etisserant@0: ITEM_TRANSITION, ITEM_ACTION, ITEM_CONFIGURATION, ITEM_RESOURCE] = range(9) etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Undo Buffer for PLCOpenEditor etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Length of the buffer etisserant@0: UNDO_BUFFER_LENGTH = 20 etisserant@0: etisserant@0: """ etisserant@0: Class implementing a buffer of changes made on the current editing Object Dictionary etisserant@0: """ etisserant@0: class UndoBuffer: etisserant@0: etisserant@0: # Constructor initialising buffer etisserant@0: def __init__(self, currentstate, issaved = False): etisserant@0: self.Buffer = [] etisserant@0: self.CurrentIndex = -1 etisserant@0: self.MinIndex = -1 etisserant@0: self.MaxIndex = -1 etisserant@0: # if current state is defined etisserant@0: if currentstate: etisserant@0: self.CurrentIndex = 0 etisserant@0: self.MinIndex = 0 etisserant@0: self.MaxIndex = 0 etisserant@0: # Initialising buffer with currentstate at the first place etisserant@0: for i in xrange(UNDO_BUFFER_LENGTH): etisserant@0: if i == 0: etisserant@0: self.Buffer.append(currentstate) etisserant@0: else: etisserant@0: self.Buffer.append(None) etisserant@0: # Initialising index of state saved etisserant@0: if issaved: etisserant@0: self.LastSave = 0 etisserant@0: else: etisserant@0: self.LastSave = -1 etisserant@0: etisserant@0: # Add a new state in buffer etisserant@0: def Buffering(self, currentstate): etisserant@0: self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH etisserant@0: self.Buffer[self.CurrentIndex] = currentstate etisserant@0: # Actualising buffer limits etisserant@0: self.MaxIndex = self.CurrentIndex etisserant@0: if self.MinIndex == self.CurrentIndex: etisserant@0: # If the removed state was the state saved, there is no state saved in the buffer etisserant@0: if self.LastSave == self.MinIndex: etisserant@0: self.LastSave = -1 etisserant@0: self.MinIndex = (self.MinIndex + 1) % UNDO_BUFFER_LENGTH etisserant@0: self.MinIndex = max(self.MinIndex, 0) etisserant@0: etisserant@0: # Return current state of buffer etisserant@0: def Current(self): etisserant@0: return self.Buffer[self.CurrentIndex] etisserant@0: etisserant@0: # Change current state to previous in buffer and return new current state etisserant@0: def Previous(self): etisserant@0: if self.CurrentIndex != self.MinIndex: etisserant@0: self.CurrentIndex = (self.CurrentIndex - 1) % UNDO_BUFFER_LENGTH etisserant@0: return self.Buffer[self.CurrentIndex] etisserant@0: return None etisserant@0: etisserant@0: # Change current state to next in buffer and return new current state etisserant@0: def Next(self): etisserant@0: if self.CurrentIndex != self.MaxIndex: etisserant@0: self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH etisserant@0: return self.Buffer[self.CurrentIndex] etisserant@0: return None etisserant@0: etisserant@0: # Return True if current state is the first in buffer etisserant@0: def IsFirst(self): etisserant@0: return self.CurrentIndex == self.MinIndex etisserant@0: etisserant@0: # Return True if current state is the last in buffer etisserant@0: def IsLast(self): etisserant@0: return self.CurrentIndex == self.MaxIndex etisserant@0: etisserant@0: # Note that current state is saved etisserant@0: def CurrentSaved(self): etisserant@0: self.LastSave = self.CurrentIndex etisserant@0: etisserant@0: # Return True if current state is saved etisserant@0: def IsCurrentSaved(self): etisserant@0: return self.LastSave == self.CurrentIndex etisserant@0: etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Controler for PLCOpenEditor etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: """ etisserant@0: Class which controls the operations made on the plcopen model and answers to view requests etisserant@0: """ etisserant@0: class PLCControler: etisserant@0: etisserant@0: # Create a new PLCControler etisserant@0: def __init__(self): etisserant@0: self.LastNewIndex = 0 etisserant@0: self.Reset() etisserant@0: etisserant@0: # Reset PLCControler internal variables etisserant@0: def Reset(self): etisserant@0: self.Project = None etisserant@0: self.ProjectBuffer = None etisserant@0: self.FilePath = "" etisserant@0: self.FileName = "" etisserant@0: self.ElementsOpened = [] etisserant@0: self.CurrentElementEditing = None etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: def GetQualifierTypes(self): etisserant@0: return plcopen.QualifierList etisserant@0: etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Project management functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Return if a project is opened etisserant@0: def HasOpenedProject(self): etisserant@0: return self.Project != None etisserant@0: etisserant@0: # Create a new project by replacing the current one etisserant@0: def CreateNewProject(self, name): etisserant@0: # Create the project etisserant@0: self.Project = plcopen.project() etisserant@0: self.Project.setName(name) etisserant@0: # Initialize the project buffer etisserant@0: self.ProjectBuffer = UndoBuffer(self.Copy(self.Project)) etisserant@0: etisserant@0: # Change project name etisserant@0: def SetProjectName(self, name): etisserant@0: self.Project.setName(name) etisserant@0: etisserant@0: # Return project name etisserant@0: def GetProjectName(self): etisserant@0: return self.Project.getName() etisserant@0: etisserant@0: # Return project pou names etisserant@0: def GetProjectPouNames(self): etisserant@0: return [pou.getName() for pou in self.Project.getPous()] etisserant@0: etisserant@0: # Return project pou names etisserant@0: def GetProjectConfigNames(self): etisserant@0: return [config.getName() for config in self.Project.getConfigurations()] etisserant@0: etisserant@0: # Return file path if project is an open file etisserant@0: def GetFilePath(self): etisserant@0: return self.FilePath etisserant@0: etisserant@0: # Return file name and point out if file is up to date etisserant@0: def GetFilename(self): etisserant@0: if self.ProjectBuffer.IsCurrentSaved(): etisserant@0: return self.FileName etisserant@0: else: etisserant@0: return "~%s~"%self.FileName etisserant@0: etisserant@0: # Change file path and save file name or create a default one if file path not defined etisserant@0: def SetFilePath(self, filepath): etisserant@0: self.FilePath = filepath etisserant@0: if filepath == "": etisserant@0: self.LastNewIndex += 1 etisserant@0: self.FileName = "Unnamed%d"%self.LastNewIndex etisserant@0: else: etisserant@0: self.FileName = os.path.splitext(os.path.basename(filepath))[0] etisserant@0: etisserant@0: # Change project properties etisserant@0: def SetProjectProperties(self, values): etisserant@0: self.Project.setFileHeader(values) etisserant@0: etisserant@0: # Return project properties etisserant@0: def GetProjectProperties(self): etisserant@0: return self.Project.getFileHeader() etisserant@0: etisserant@0: # Return project informations etisserant@0: def GetProjectInfos(self): etisserant@0: if self.Project: etisserant@0: infos = {"name": self.Project.getName(), "type": ITEM_PROJECT} etisserant@0: pou_types = {"function": {"name": "Functions", "type": ITEM_UNEDITABLE, "values":[]}, etisserant@0: "functionBlock": {"name": "Function Blocks", "type": ITEM_UNEDITABLE, "values":[]}, etisserant@0: "program": {"name": "Programs", "type": ITEM_UNEDITABLE, "values":[]}} etisserant@0: for pou in self.Project.getPous(): etisserant@0: pou_type = pou.getPouType().getValue() etisserant@0: pou_infos = {"name": pou.getName(), "type": ITEM_POU} etisserant@0: var_types = {"Input": {"name": "Input", "type": ITEM_CLASS, "values": []}, etisserant@0: "Output": {"name": "Output", "type": ITEM_CLASS, "values": []}, etisserant@0: "InOut": {"name": "InOut", "type": ITEM_CLASS, "values": []}, etisserant@0: "External": {"name": "External", "type": ITEM_CLASS, "values": []}, etisserant@0: "Local": {"name": "Local", "type": ITEM_CLASS, "values": []}, etisserant@0: "Temp": {"name": "Temp", "type": ITEM_CLASS, "values": []}, etisserant@0: "Global": {"name": "Global", "type": ITEM_CLASS, "values": []}} etisserant@0: for var in self.GetPouInterfaceVars(pou): etisserant@0: var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []} etisserant@0: if var["Class"] in var_types.keys(): etisserant@0: var_types[var["Class"]]["values"].append(var_values) etisserant@0: pou_values = [] etisserant@0: pou_values.append({"name": "Interface", "type": ITEM_CLASS, etisserant@0: "values": [var_types["Input"], var_types["Output"], var_types["InOut"], var_types["External"]]}) etisserant@0: pou_values.append({"name": "Variables", "type": ITEM_CLASS, etisserant@0: "values": [var_types["Local"], var_types["Temp"]]}) etisserant@0: if pou_type == "program": etisserant@0: pou_values.append(var_types["Global"]) etisserant@0: if pou.getBodyType() == "SFC": etisserant@0: transitions = [] etisserant@0: for transition in pou.getTransitionList(): etisserant@0: transitions.append({"name": transition.getName(), "type": ITEM_TRANSITION, "values": []}) etisserant@0: pou_values.append({"name": "Transitions", "type": ITEM_UNEDITABLE, "values": transitions}) etisserant@0: actions = [] etisserant@0: for action in pou.getActionList(): etisserant@0: actions.append({"name": action.getName(), "type": ITEM_ACTION, "values": []}) etisserant@0: pou_values.append({"name": "Actions", "type": ITEM_UNEDITABLE, "values": actions}) etisserant@0: if pou_type in pou_types: etisserant@0: pou_infos["values"] = pou_values etisserant@0: pou_types[pou_type]["values"].append(pou_infos) etisserant@0: configurations = {"name": "Configurations", "type": ITEM_UNEDITABLE, "values": []} etisserant@0: for config in self.Project.getConfigurations(): etisserant@0: config_name = config.getName() etisserant@0: config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, "values": []} etisserant@0: config_vars = {"name": "Global", "type": ITEM_CLASS, "values": []} etisserant@0: for var in self.GetConfigurationGlobalVars(config_name): etisserant@0: var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []} etisserant@0: config_vars["values"].append(var_values) etisserant@0: resources = {"name": "Resources", "type": ITEM_UNEDITABLE, "values": []} etisserant@0: for resource in config.getResource(): etisserant@0: resource_name = resource.getName() etisserant@0: resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []} etisserant@0: resource_vars = {"name": "Global", "type": ITEM_CLASS, "values": []} etisserant@0: for var in self.GetConfigurationResourceGlobalVars(config_name, resource_name): etisserant@0: var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []} etisserant@0: resource_vars["values"].append(var_values) etisserant@0: resource_infos["values"].append(resource_vars) etisserant@0: resources["values"].append(resource_infos) etisserant@0: config_infos["values"] = [config_vars, resources] etisserant@0: configurations["values"].append(config_infos) etisserant@0: infos["values"] = [{"name": "Properties", "type": ITEM_UNEDITABLE, "values": []}, etisserant@0: pou_types["function"], pou_types["functionBlock"], etisserant@0: pou_types["program"], configurations] etisserant@0: return infos etisserant@0: return None etisserant@0: etisserant@0: # Refresh the tree of user-defined pou cross-use etisserant@0: def RefreshPouUsingTree(self): etisserant@0: # Reset the tree of user-defined pou cross-use etisserant@0: self.PouUsingTree = {} etisserant@0: if self.Project: etisserant@0: pous = self.Project.getPous() etisserant@0: # Reference all the user-defined pou names and initialize the tree of etisserant@0: # user-defined pou cross-use etisserant@0: pounames = [pou.getName() for pou in pous] etisserant@0: for name in pounames: etisserant@0: self.PouUsingTree[name] = [] etisserant@0: # Analyze each pou etisserant@0: for pou in pous: etisserant@0: name = pou.getName() etisserant@0: bodytype = pou.getBodyType() etisserant@0: # If pou is written in a graphical language etisserant@0: if bodytype in ["FBD","LD","SFC"]: etisserant@0: # Analyze each instance of the pou etisserant@0: for instance in pou.getInstances(): etisserant@0: if isinstance(instance, plcopen.block): etisserant@0: typename = instance.getTypeName() etisserant@0: # Update tree if there is a cross-use etisserant@0: if typename in pounames and name not in self.PouUsingTree[typename]: etisserant@0: self.PouUsingTree[typename].append(name) etisserant@0: # If pou is written in a textual language etisserant@0: elif bodytype in ["IL", "ST"]: etisserant@0: text = pou.getText() etisserant@0: # Search if each pou is mentioned in the pou text etisserant@0: for typename in pounames: etisserant@0: typename_model = re.compile("[ \t\n]%s[ \t\n]"%typename) etisserant@0: # Update tree if there is a cross-use etisserant@0: if typename != name and typename_model.search(text): etisserant@0: self.PouUsingTree[typename].append(name) etisserant@0: etisserant@0: # Return if pou given by name is used by another pou etisserant@0: def PouIsUsed(self, name): etisserant@0: if name in self.PouUsingTree: etisserant@0: return len(self.PouUsingTree[name]) > 0 etisserant@0: return False etisserant@0: etisserant@0: # Return if pou given by name is directly or undirectly used by the reference pou etisserant@0: def PouIsUsedBy(self, name, reference): etisserant@0: if name in self.PouUsingTree: etisserant@0: list = self.PouUsingTree[name] etisserant@0: # Test if pou is directly used by reference etisserant@0: if reference in list: etisserant@0: return True etisserant@0: else: etisserant@0: # Test if pou is undirectly used by reference, by testing if pous etisserant@0: # that directly use pou is directly or undirectly used by reference etisserant@0: used = False etisserant@0: for element in list: etisserant@0: used |= self.PouIsUsedBy(element, reference) etisserant@0: return used etisserant@0: return False etisserant@0: etisserant@0: def GenerateProgram(self): etisserant@0: if self.Project: etisserant@0: program = GenerateCurrentProgram(self.Project) etisserant@0: programfile = open("test.st", "w") etisserant@0: programfile.write(program) etisserant@0: programfile.close() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Project Pous management functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Add a Pou to Project etisserant@0: def ProjectAddPou(self, name, pou_type, body_type): etisserant@0: # Add the pou to project etisserant@0: self.Project.appendPou(name, pou_type, body_type) etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Remove a pou from project etisserant@0: def ProjectRemovePou(self, name): etisserant@0: removed = None etisserant@0: # Search if the pou removed is currently opened etisserant@0: for i, pou in enumerate(self.ElementsOpened): etisserant@0: if pou == name: etisserant@0: removed = i etisserant@0: # If found, remove pou from list of opened pous and actualize current edited etisserant@0: if removed != None: etisserant@0: self.ElementsOpened.pop(removed) etisserant@0: if self.CurrentElementEditing > removed: etisserant@0: self.CurrentElementEditing -= 1 etisserant@0: if len(self.ElementsOpened) > 0: etisserant@0: self.CurrentElementEditing = max(0, min(self.CurrentElementEditing, len(self.ElementsOpened) - 1)) etisserant@0: else: etisserant@0: self.CurrentElementEditing = None etisserant@0: # Remove pou from project etisserant@0: self.Project.removePou(name) etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Add a configuration to Project etisserant@0: def ProjectAddConfiguration(self, name): etisserant@0: self.Project.addConfiguration(name) etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Remove a configuration from project etisserant@0: def ProjectRemoveConfiguration(self, name): etisserant@0: self.Project.removeConfiguration(name) etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Add a resource to a configuration of the Project etisserant@0: def ProjectAddConfigurationResource(self, config, name): etisserant@0: self.Project.addConfigurationResource(config, name) etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Remove a resource from a configuration of the project etisserant@0: def ProjectRemoveConfigurationResource(self, config, name): etisserant@0: self.Project.removeConfigurationResource(config, name) etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Add a Transition to a Project Pou etisserant@0: def ProjectAddPouTransition(self, pou_name, transition_name, transition_type): etisserant@0: pou = self.Project.getPou(pou_name) etisserant@0: pou.addTransition(transition_name, transition_type) etisserant@0: etisserant@0: # Add a Transition to a Project Pou etisserant@0: def ProjectAddPouAction(self, pou_name, action_name, action_type): etisserant@0: pou = self.Project.getPou(pou_name) etisserant@0: pou.addAction(action_name, action_type) etisserant@0: etisserant@0: # Change the name of a pou etisserant@0: def ChangePouName(self, old_name, new_name): etisserant@0: # Found the pou corresponding to old name and change its name to new name etisserant@0: pou = self.Project.getPou(old_name) etisserant@0: pou.setName(new_name) etisserant@0: # If pou is currently opened, change its name in the list of opened pous etisserant@0: if old_name in self.ElementsOpened: etisserant@0: idx = self.ElementsOpened.index(old_name) etisserant@0: self.ElementsOpened[idx] = new_name etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Change the name of a pou transition etisserant@0: def ChangePouTransitionName(self, pou_name, old_name, new_name): etisserant@0: # Found the pou transition corresponding to old name and change its name to new name etisserant@0: pou = self.Project.getPou(pou_name) etisserant@0: transition = pou.getTransition(old_name) etisserant@0: transition.setName(new_name) etisserant@0: # If pou transition is currently opened, change its name in the list of opened elements etisserant@0: old_computedname = self.ComputePouTransitionName(pou_name, old_name) etisserant@0: new_computedname = self.ComputePouTransitionName(pou_name, new_name) etisserant@0: if old_computedname in self.ElementsOpened: etisserant@0: idx = self.ElementsOpened.index(old_computedname) etisserant@0: self.ElementsOpened[idx] = new_computedname etisserant@0: etisserant@0: # Change the name of a pou action etisserant@0: def ChangePouActionName(self, pou_name, old_name, new_name): etisserant@0: # Found the pou action corresponding to old name and change its name to new name etisserant@0: pou = self.Project.getPou(pou_name) etisserant@0: action = pou.getAction(old_name) etisserant@0: action.setName(new_name) etisserant@0: # If pou action is currently opened, change its name in the list of opened elements etisserant@0: old_computedname = self.ComputePouActionName(pou_name, old_name) etisserant@0: new_computedname = self.ComputePouActionName(pou_name, new_name) etisserant@0: if old_computedname in self.ElementsOpened: etisserant@0: idx = self.ElementsOpened.index(old_computedname) etisserant@0: self.ElementsOpened[idx] = new_computedname etisserant@0: etisserant@0: # Change the name of a configuration etisserant@0: def ChangeConfigurationName(self, old_name, new_name): etisserant@0: # Found the configuration corresponding to old name and change its name to new name etisserant@0: configuration = self.Project.getConfiguration(old_name) etisserant@0: configuration.setName(new_name) etisserant@0: # If configuration is currently opened, change its name in the list of opened elements etisserant@0: for idx, element in enumerate(self.ElementsOpened): etisserant@0: self.ElementsOpened[idx] = element.replace(old_name, new_name) etisserant@0: etisserant@0: # Change the name of a configuration resource etisserant@0: def ChangeConfigurationResourceName(self, config_name, old_name, new_name): etisserant@0: # Found the resource corresponding to old name and change its name to new name etisserant@0: resource = self.Project.getConfigurationResource(config_name) etisserant@0: resource.setName(new_name) etisserant@0: # If resource is currently opened, change its name in the list of opened elements etisserant@0: old_computedname = self.ComputeConfigurationResourceName(config_name, old_name) etisserant@0: new_computedname = self.ComputeConfigurationResourceName(config_name, new_name) etisserant@0: if old_computedname in self.ElementsOpened: etisserant@0: idx = self.ElementsOpened.index(old_computedname) etisserant@0: self.ElementsOpened[idx] = new_computedname etisserant@0: etisserant@0: # Return the type of the pou given by its name etisserant@0: def GetPouType(self, name): etisserant@0: # Found the pou correponding to name and return its type etisserant@0: pou = self.Project.getPou(name) etisserant@0: return pou.pouType.getValue() etisserant@0: etisserant@0: # Return pous with SFC language etisserant@0: def GetSFCPous(self): etisserant@0: list = [] etisserant@0: if self.Project: etisserant@0: for pou in self.Project.getPous(): etisserant@0: if pou.getBodyType() == "SFC": etisserant@0: list.append(pou.getName()) etisserant@0: return list etisserant@0: etisserant@0: # Return the body language of the pou given by its name etisserant@0: def GetPouBodyType(self, name): etisserant@0: # Found the pou correponding to name and return its body language etisserant@0: pou = self.Project.getPou(name) etisserant@0: return pou.getBodyType() etisserant@0: etisserant@0: # Return the body language of the transition given by its name etisserant@0: def GetTransitionBodyType(self, pou_name, pou_transition): etisserant@0: # Found the pou correponding to name and return its body language etisserant@0: pou = self.Project.getPou(pou_name) etisserant@0: transition = pou.getTransition(pou_transition) etisserant@0: return transition.getBodyType() etisserant@0: etisserant@0: # Return the body language of the pou given by its name etisserant@0: def GetActionBodyType(self, pou_name, pou_action): etisserant@0: # Found the pou correponding to name and return its body language etisserant@0: pou = self.Project.getPou(pou_name) etisserant@0: action = pou.getAction(pou_action) etisserant@0: return action.getBodyType() etisserant@0: etisserant@0: # Extract varlists from a list of vars etisserant@0: def ExtractVarLists(self, vars): etisserant@0: varlist_list = [] etisserant@0: current_varlist = None etisserant@0: current_type = None etisserant@0: for var in vars: etisserant@0: if current_type != (var["Class"], var["Retain"], var["Constant"]): etisserant@0: current_type = (var["Class"], var["Retain"], var["Constant"]) etisserant@0: current_varlist = plcopen.varList() etisserant@0: varlist_list.append((var["Class"], current_varlist)) etisserant@0: if var["Retain"] == "Yes": etisserant@0: varlist.setRetain(True) etisserant@0: if var["Constant"] == "Yes": etisserant@0: varlist.setConstant(True) etisserant@0: # Create variable and change its properties etisserant@0: tempvar = plcopen.varListPlain_variable() etisserant@0: tempvar.setName(var["Name"]) etisserant@0: var_type = plcopen.dataType() etisserant@0: var_type.setValue(var["Type"]) etisserant@0: tempvar.setType(var_type) etisserant@0: if var["Initial Value"] != "": etisserant@0: value = plcopen.value() etisserant@0: value.setValue(var["Initial Value"]) etisserant@0: tempvar.setInitialValue(value) etisserant@0: if var["Location"] != "": etisserant@0: tempvar.setAddress(var["Location"]) etisserant@0: # Add variable to varList etisserant@0: current_varlist.appendVariable(tempvar) etisserant@0: return varlist_list etisserant@0: etisserant@0: # Replace the configuration globalvars by those given etisserant@0: def SetConfigurationGlobalVars(self, name, vars): etisserant@0: # Found the configuration corresponding to name etisserant@0: configuration = self.Project.getConfiguration(name) etisserant@0: if configuration: etisserant@0: # Set configuration global vars etisserant@0: configuration.setGlobalVars([]) etisserant@0: for vartype, varlist in self.ExtractVarLists(vars): etisserant@0: configuration.globalVars.append(varlist) etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Return the configuration globalvars etisserant@0: def GetConfigurationGlobalVars(self, name): etisserant@0: vars = [] etisserant@0: # Found the configuration corresponding to name etisserant@0: configuration = self.Project.getConfiguration(name) etisserant@0: if configuration: etisserant@0: # Extract variables from every varLists etisserant@0: for varlist in configuration.getGlobalVars(): etisserant@0: for var in varlist.getVariable(): etisserant@0: tempvar = {"Name":var.getName(),"Class":"Global","Type":var.getType().getValue(), etisserant@0: "Location":var.getAddress()} etisserant@0: initial = var.getInitialValue() etisserant@0: if initial: etisserant@0: tempvar["Initial Value"] = initial.getValue() etisserant@0: else: etisserant@0: tempvar["Initial Value"] = "" etisserant@0: if varlist.getRetain(): etisserant@0: tempvar["Retain"] = "Yes" etisserant@0: else: etisserant@0: tempvar["Retain"] = "No" etisserant@0: if varlist.getConstant(): etisserant@0: tempvar["Constant"] = "Yes" etisserant@0: else: etisserant@0: tempvar["Constant"] = "No" etisserant@0: vars.append(tempvar) etisserant@0: return vars etisserant@0: etisserant@0: # Replace the resource globalvars by those given etisserant@0: def SetConfigurationResourceGlobalVars(self, config_name, name, vars): etisserant@0: # Found the resource corresponding to name etisserant@0: resource = self.Project.getConfigurationResource(config_name, name) etisserant@0: # Set resource global vars etisserant@0: if resource: etisserant@0: resource.setGlobalVars([]) etisserant@0: for vartype, varlist in self.ExtractVarLists(vars): etisserant@0: resource.globalVars.append(varlist) etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Return the resource globalvars etisserant@0: def GetConfigurationResourceGlobalVars(self, config_name, name): etisserant@0: vars = [] etisserant@0: # Found the resource corresponding to name etisserant@0: resource = self.Project.getConfigurationResource(config_name, name) etisserant@0: if resource: etisserant@0: # Extract variables from every varLists etisserant@0: for varlist in resource.getGlobalVars(): etisserant@0: for var in varlist.getVariable(): etisserant@0: tempvar = {"Name":var.getName(),"Class":"Global","Type":var.getType().getValue(), etisserant@0: "Location":var.getAddress()} etisserant@0: initial = var.getInitialValue() etisserant@0: if initial: etisserant@0: tempvar["Initial Value"] = initial.getValue() etisserant@0: else: etisserant@0: tempvar["Initial Value"] = "" etisserant@0: if varlist.getRetain(): etisserant@0: tempvar["Retain"] = "Yes" etisserant@0: else: etisserant@0: tempvar["Retain"] = "No" etisserant@0: if varlist.getConstant(): etisserant@0: tempvar["Constant"] = "Yes" etisserant@0: else: etisserant@0: tempvar["Constant"] = "No" etisserant@0: vars.append(tempvar) etisserant@0: return vars etisserant@0: etisserant@0: # Return the interface of the pou given by its name etisserant@0: def GetPouInterfaceVarsByName(self, name): etisserant@0: # Found the pou correponding to name and return the interface etisserant@0: return self.GetPouInterfaceVars(self.Project.getPou(name)) etisserant@0: etisserant@0: # Return the interface for the given pou etisserant@0: def GetPouInterfaceVars(self, pou): etisserant@0: vars = [] etisserant@0: # Verify that the pou has an interface etisserant@0: if pou.interface: etisserant@0: # Extract variables from every varLists etisserant@0: for type, varlist in pou.getVars(): etisserant@0: for var in varlist.getVariable(): etisserant@0: tempvar = {"Name":var.getName(),"Class":type,"Type":var.getType().getValue(), etisserant@0: "Location":var.getAddress()} etisserant@0: initial = var.getInitialValue() etisserant@0: if initial: etisserant@0: tempvar["Initial Value"] = initial.getValue() etisserant@0: else: etisserant@0: tempvar["Initial Value"] = "" etisserant@0: if varlist.getRetain(): etisserant@0: tempvar["Retain"] = "Yes" etisserant@0: else: etisserant@0: tempvar["Retain"] = "No" etisserant@0: if varlist.getConstant(): etisserant@0: tempvar["Constant"] = "Yes" etisserant@0: else: etisserant@0: tempvar["Constant"] = "No" etisserant@0: vars.append(tempvar) etisserant@0: return vars etisserant@0: etisserant@0: # Replace the Pou interface by the one given etisserant@0: def SetPouInterfaceVars(self, name, vars): etisserant@0: # Found the pou corresponding to name and add interface if there isn't one yet etisserant@0: pou = self.Project.getPou(name) etisserant@0: if not pou.interface: etisserant@0: pou.interface = plcopen.pou_interface() etisserant@0: # Set Pou interface etisserant@0: pou.setVars(self.ExtractVarLists(vars)) etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Replace the return type of the pou given by its name (only for functions) etisserant@0: def SetPouInterfaceReturnType(self, name, type): etisserant@0: pou = self.Project.getPou(name) etisserant@0: if not pou.interface: etisserant@0: pou.interface = plcopen.pou_interface() etisserant@0: # If there isn't any return type yet, add it etisserant@0: return_type = pou.interface.getReturnType() etisserant@0: if not return_type: etisserant@0: return_type = plcopen.dataType() etisserant@0: pou.interface.setReturnType(return_type) etisserant@0: # Change return type etisserant@0: return_type.setValue(type) etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: # Return the return type of the pou given by its name etisserant@0: def GetPouInterfaceReturnTypeByName(self, name): etisserant@0: # Found the pou correponding to name and return the return type etisserant@0: return self.GetPouInterfaceReturnType(self.Project.getPou(name)) etisserant@0: etisserant@0: # Return the return type of the given pou etisserant@0: def GetPouInterfaceReturnType(self, pou): etisserant@0: # Verify that the pou has an interface etisserant@0: if pou.interface: etisserant@0: # Return the return type if there is one etisserant@0: return_type = pou.interface.getReturnType() etisserant@0: if return_type: etisserant@0: return return_type.getValue() etisserant@0: return None etisserant@0: etisserant@0: # Update Block types with user-defined pou added etisserant@0: def RefreshBlockTypes(self): etisserant@0: if BlockTypes[-1]["name"] == "User-defined POUs": etisserant@0: BlockTypes[-1]["list"] = [] etisserant@0: else: etisserant@0: BlockTypes.append({"name" : "User-defined POUs", "list": []}) etisserant@0: if self.Project: etisserant@0: for pou in self.Project.getPous(): etisserant@0: pou_name = pou.getName() etisserant@0: pou_type = pou.pouType.getValue() etisserant@0: if pou_type != "program": etisserant@0: block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False, etisserant@0: "inputs" : [], "outputs" : [], "comment" : ""} etisserant@0: if pou.getInterface(): etisserant@0: for type, varlist in pou.getVars(): etisserant@0: if type == "InOut": etisserant@0: for var in varlist.getVariable(): etisserant@0: block_infos["inputs"].append((var.getName(),var.getType().getValue(),"none")) etisserant@0: block_infos["outputs"].append((var.getName(),var.getType().getValue(),"none")) etisserant@0: elif type == "Input": etisserant@0: for var in varlist.getVariable(): etisserant@0: block_infos["inputs"].append((var.getName(),var.getType().getValue(),"none")) etisserant@0: elif type == "Output": etisserant@0: for var in varlist.getVariable(): etisserant@0: block_infos["outputs"].append((var.getName(),var.getType().getValue(),"none")) etisserant@0: return_type = pou.interface.getReturnType() etisserant@0: if return_type: etisserant@0: block_infos["outputs"].append(("",return_type.getValue(),"none")) etisserant@0: if pou.getBodyType() in ["FBD","LD","SFC"]: etisserant@0: for instance in pou.getInstances(): etisserant@0: if isinstance(instance, plcopen.comment): etisserant@0: block_infos["comment"] = instance.getContentText() etisserant@0: BlockTypes[-1]["list"].append(block_infos) etisserant@0: etisserant@0: # Return Block types checking for recursion etisserant@0: def GetBlockTypes(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: current_name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = current_name.split("::") etisserant@0: if len(words) == 1: etisserant@0: name = current_name etisserant@0: else: etisserant@0: name = words[1] etisserant@0: blocktypes = [category for category in BlockTypes[:-1]] etisserant@0: blocktypes.append({"name" : "User-defined POUs", "list": []}) etisserant@0: if self.Project: etisserant@0: pou = self.Project.getPou(name) etisserant@0: name = pou.getName() etisserant@0: type = pou.pouType.getValue() etisserant@0: for blocktype in BlockTypes[-1]["list"]: etisserant@0: if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] == "functionBlock"): etisserant@0: blocktypes[-1]["list"].append(blocktype) etisserant@0: return blocktypes etisserant@0: return [] etisserant@0: etisserant@0: # Return Block types checking for recursion etisserant@0: def GetBlockResource(self): etisserant@0: blocktypes = [] etisserant@0: for category in BlockTypes[:-1]: etisserant@0: for blocktype in category["list"]: etisserant@0: if blocktype["type"] != "function": etisserant@0: blocktypes.append(blocktype["name"]) etisserant@0: if self.Project: etisserant@0: for pou in self.Project.getPous(): etisserant@0: if pou.pouType.getValue() != "function": etisserant@0: blocktypes.append(pou.getName()) etisserant@0: return blocktypes etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Project opened Pous management functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Return the list of pou names etisserant@0: def GetElementsOpenedNames(self): etisserant@0: names = [] etisserant@0: for pou_name in self.ElementsOpened: etisserant@0: words = pou_name.split("::") etisserant@0: if len(words) == 1: etisserant@0: names.append(pou_name) etisserant@0: else: etisserant@0: names.append("%s-%s"%(words[1],words[2])) etisserant@0: return names etisserant@0: etisserant@0: # Compute a pou transition name etisserant@0: def ComputePouTransitionName(self, pou, transition): etisserant@0: return "T::%s::%s" % (pou, transition) etisserant@0: etisserant@0: # Compute a pou action name etisserant@0: def ComputePouActionName(self, pou, action): etisserant@0: return "A::%s::%s" % (pou, action) etisserant@0: etisserant@0: # Compute a pou name etisserant@0: def ComputeConfigurationResourceName(self, config, resource): etisserant@0: return "R::%s::%s" % (config, resource) etisserant@0: etisserant@0: # Open a pou by giving its name etisserant@0: def OpenElementEditing(self, name): etisserant@0: # If pou not opened yet etisserant@0: if name not in self.ElementsOpened: etisserant@0: # Add pou name to list of pou opened and make it current editing etisserant@0: self.ElementsOpened.append(name) etisserant@0: self.CurrentElementEditing = len(self.ElementsOpened) - 1 etisserant@0: return self.CurrentElementEditing etisserant@0: return None etisserant@0: etisserant@0: # Open a pou transition by giving pou and transition names etisserant@0: def OpenPouTransitionEditing(self, pou, transition): etisserant@0: return self.OpenElementEditing(self.ComputePouTransitionName(pou, transition)) etisserant@0: etisserant@0: # Open a pou action by giving pou and action names etisserant@0: def OpenPouActionEditing(self, pou, action): etisserant@0: return self.OpenElementEditing(self.ComputePouActionName(pou, action)) etisserant@0: etisserant@0: # Open a configuration resource by giving configuration and resource names etisserant@0: def OpenConfigurationResourceEditing(self, config, resource): etisserant@0: return self.OpenElementEditing(self.ComputeConfigurationResourceName(config, resource)) etisserant@0: etisserant@0: # Return if pou given by name is opened etisserant@0: def IsElementEditing(self, name): etisserant@0: return name in self.ElementsOpened etisserant@0: etisserant@0: # Return if pou transition given by pou and transition names is opened etisserant@0: def IsPouTransitionEditing(self, pou, transition): etisserant@0: return self.ComputePouTransitionName(pou, transition) in self.ElementsOpened etisserant@0: etisserant@0: # Return if pou action given by pou and action names is opened etisserant@0: def IsPouActionEditing(self, pou, action): etisserant@0: return self.ComputePouActionName(pou, action) in self.ElementsOpened etisserant@0: etisserant@0: # Return if pou action given by pou and action names is opened etisserant@0: def IsConfigurationResourceEditing(self, pou, action): etisserant@0: return self.ComputeConfigurationResourceName(config, resource) in self.ElementsOpened etisserant@0: etisserant@0: # Close current pou editing etisserant@0: def CloseElementEditing(self): etisserant@0: # Remove pou from list of pou opened etisserant@0: self.ElementsOpened.pop(self.CurrentElementEditing) etisserant@0: # Update index of current pou editing etisserant@0: if len(self.ElementsOpened) > 0: etisserant@0: self.CurrentElementEditing = min(self.CurrentElementEditing, len(self.ElementsOpened) - 1) etisserant@0: else: etisserant@0: self.CurrentElementEditing = None etisserant@0: etisserant@0: # Change current pou editing for pou given by name etisserant@0: def ChangeElementEditing(self, name): etisserant@0: # Verify that pou is opened etisserant@0: if name in self.ElementsOpened: etisserant@0: # Change current pou editing etisserant@0: self.CurrentElementEditing = self.ElementsOpened.index(name) etisserant@0: return self.CurrentElementEditing etisserant@0: return None etisserant@0: etisserant@0: # Change current pou editing for transition given by pou and transition names etisserant@0: def ChangePouTransitionEditing(self, pou, transition): etisserant@0: return self.ChangeElementEditing(self.ComputePouTransitionName(pou, transition)) etisserant@0: etisserant@0: # Change current pou editing for action given by pou and action names etisserant@0: def ChangePouActionEditing(self, pou, action): etisserant@0: return self.ChangeElementEditing(self.ComputePouActionName(pou, action)) etisserant@0: etisserant@0: # Change current pou editing for action given by configuration and resource names etisserant@0: def ChangeConfigurationResourceEditing(self, config, resource): etisserant@0: return self.ChangeElementEditing(self.ComputeConfigurationResourceName(config, resource)) etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Project opened Pous management functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Return current pou editing etisserant@0: def GetCurrentElementEditing(self): etisserant@0: # Verify that there's one editing and return it etisserant@0: if self.CurrentElementEditing != None: etisserant@0: name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = name.split("::") etisserant@0: if len(words) == 1: etisserant@0: return self.Project.getPou(name) etisserant@0: else: etisserant@0: if words[0] in ['T', 'A']: etisserant@0: pou = self.Project.getPou(words[1]) etisserant@0: if words[0] == 'T': etisserant@0: return pou.getTransition(words[2]) etisserant@0: elif words[0] == 'A': etisserant@0: return pou.getAction(words[2]) etisserant@0: elif words[0] == 'R': etisserant@0: result = self.Project.getConfigurationResource(words[1], words[2]) etisserant@0: return result etisserant@0: return None etisserant@0: etisserant@0: # Return current pou editing name etisserant@0: def GetCurrentElementEditingName(self): etisserant@0: # Verify that there's one editing and return its name etisserant@0: if self.CurrentElementEditing != None: etisserant@0: name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = name.split("::") etisserant@0: if len(words) == 1: etisserant@0: return name etisserant@0: else: etisserant@0: return words[2] etisserant@0: return None etisserant@0: etisserant@0: # Replace the index of current pou editing by the one given etisserant@0: def RefreshCurrentElementEditing(self, index): etisserant@0: self.CurrentElementEditing = index etisserant@0: etisserant@0: # Return language in which current pou editing is written etisserant@0: def GetCurrentElementEditingBodyType(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = name.split("::") etisserant@0: if len(words) == 1: etisserant@0: return self.GetPouBodyType(name) etisserant@0: else: etisserant@0: if words[0] == 'T': etisserant@0: return self.GetTransitionBodyType(words[1], words[2]) etisserant@0: elif words[0] == 'A': etisserant@0: return self.GetActionBodyType(words[1], words[2]) etisserant@0: return None etisserant@0: etisserant@0: # Return the variables of the current pou editing etisserant@0: def GetCurrentElementEditingInterfaceVars(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: current_name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = current_name.split("::") etisserant@0: if len(words) == 1: etisserant@0: pou = self.Project.getPou(current_name) etisserant@0: return self.GetPouInterfaceVars(pou) etisserant@0: else: etisserant@0: pou = self.Project.getPou(words[1]) etisserant@0: return self.GetPouInterfaceVars(pou) etisserant@0: return [] etisserant@0: etisserant@0: # Return the return type of the current pou editing etisserant@0: def GetCurrentElementEditingInterfaceReturnType(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: current_name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = current_name.split("::") etisserant@0: if len(words) == 1: etisserant@0: pou = self.Project.getPou(current_name) etisserant@0: return self.GetPouInterfaceReturnType(pou) etisserant@0: elif words[0] == 'T': etisserant@0: return "BOOL" etisserant@0: return None etisserant@0: etisserant@0: # Change the text of the current pou editing etisserant@0: def SetCurrentElementEditingText(self, text): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: self.GetCurrentElementEditing().setText(text) etisserant@0: self.RefreshPouUsingTree() etisserant@0: etisserant@0: # Return the current pou editing text etisserant@0: def GetCurrentElementEditingText(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: return self.GetCurrentElementEditing().getText() etisserant@0: return "" etisserant@0: etisserant@0: # Return the current pou editing transitions etisserant@0: def GetCurrentElementEditingTransitions(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: pou = self.GetCurrentElementEditing() etisserant@0: if pou.getBodyType() == "SFC": etisserant@0: transitions = [] etisserant@0: for transition in pou.getTransitionList(): etisserant@0: transitions.append(transition.getName()) etisserant@0: return transitions etisserant@0: return [] etisserant@0: etisserant@0: # Return the current pou editing transitions etisserant@0: def GetCurrentElementEditingActions(self): etisserant@0: if self.CurrentElementEditing != None: etisserant@0: pou = self.GetCurrentElementEditing() etisserant@0: if pou.getBodyType() == "SFC": etisserant@0: actions = [] etisserant@0: for action in pou.getActionList(): etisserant@0: actions.append(action.getName()) etisserant@0: return actions etisserant@0: return [] etisserant@0: etisserant@0: # Return the current pou editing informations etisserant@0: def GetCurrentElementEditingInstanceInfos(self, id = None, exclude = []): etisserant@0: infos = {} etisserant@0: # if id is defined etisserant@0: if id != None: etisserant@0: instance = self.GetCurrentElementEditing().getInstance(id) etisserant@0: else: etisserant@0: instance = self.GetCurrentElementEditing().getRandomInstance(exclude) etisserant@0: if instance: etisserant@0: if id != None: etisserant@0: infos["id"] = id etisserant@0: else: etisserant@0: infos["id"] = instance.getLocalId() etisserant@0: infos["x"] = instance.getX() etisserant@0: infos["y"] = instance.getY() etisserant@0: infos["height"] = instance.getHeight() etisserant@0: infos["width"] = instance.getWidth() etisserant@0: if isinstance(instance, plcopen.block): etisserant@0: infos["name"] = instance.getInstanceName() etisserant@0: infos["type"] = instance.getTypeName() etisserant@0: infos["connectors"] = {"inputs":[],"outputs":[]} etisserant@0: for variable in instance.inputVariables.getVariable(): etisserant@0: connector = {} etisserant@0: connector["position"] = variable.connectionPointIn.getRelPosition() etisserant@0: connector["negated"] = variable.getNegated() etisserant@0: connector["edge"] = variable.getConnectorEdge() etisserant@0: connector["links"] = [] etisserant@0: connections = variable.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: connector["links"].append(dic) etisserant@0: infos["connectors"]["inputs"].append(connector) etisserant@0: for variable in instance.outputVariables.getVariable(): etisserant@0: connector = {} etisserant@0: connector["position"] = variable.connectionPointOut.getRelPosition() etisserant@0: connector["negated"] = variable.getNegated() etisserant@0: connector["edge"] = variable.getConnectorEdge() etisserant@0: infos["connectors"]["outputs"].append(connector) etisserant@0: elif isinstance(instance, plcopen.inVariable): etisserant@0: infos["name"] = instance.getExpression() etisserant@0: infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"]) etisserant@0: infos["type"] = "input" etisserant@0: infos["connector"] = {} etisserant@0: infos["connector"]["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: infos["connector"]["negated"] = instance.getNegated() etisserant@0: infos["connector"]["edge"] = instance.getConnectorEdge() etisserant@0: elif isinstance(instance, plcopen.outVariable): etisserant@0: infos["name"] = instance.getExpression() etisserant@0: infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"]) etisserant@0: infos["type"] = "output" etisserant@0: infos["connector"] = {} etisserant@0: infos["connector"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connector"]["negated"] = instance.getNegated() etisserant@0: infos["connector"]["edge"] = instance.getConnectorEdge() etisserant@0: infos["connector"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connector"]["links"].append(dic) etisserant@0: elif isinstance(instance, plcopen.inOutVariable): etisserant@0: infos["name"] = instance.getExpression() etisserant@0: infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"]) etisserant@0: infos["type"] = "inout" etisserant@0: infos["connectors"] = {"input":{},"output":{}} etisserant@0: infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: infos["connectors"]["output"]["negated"] = instance.getNegatedOut() etisserant@0: infos["connectors"]["output"]["edge"] = instance.getOutputEdge() etisserant@0: infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connectors"]["input"]["negated"] = instance.getNegatedIn() etisserant@0: infos["connectors"]["input"]["edge"] = instance.getInputEdge() etisserant@0: infos["connectors"]["input"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connectors"]["input"]["links"].append(dic) etisserant@0: elif isinstance(instance, plcopen.continuation): etisserant@0: infos["name"] = instance.getName() etisserant@0: infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"]) etisserant@0: infos["type"] = "continuation" etisserant@0: infos["connector"] = {} etisserant@0: infos["connector"]["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: elif isinstance(instance, plcopen.connector): etisserant@0: infos["name"] = instance.getName() etisserant@0: infos["value_type"] = self.GetPouVarValueType(self.GetCurrentElementEditing(), infos["name"]) etisserant@0: infos["type"] = "connection" etisserant@0: infos["connector"] = {} etisserant@0: infos["connector"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connector"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connector"]["links"].append(dic) etisserant@0: elif isinstance(instance, plcopen.comment): etisserant@0: infos["type"] = "comment" etisserant@0: infos["content"] = instance.getContentText() etisserant@0: elif isinstance(instance, plcopen.leftPowerRail): etisserant@0: infos["type"] = "leftPowerRail" etisserant@0: infos["connectors"] = [] etisserant@0: for connection in instance.getConnectionPointOut(): etisserant@0: connector = {} etisserant@0: connector["position"] = connection.getRelPosition() etisserant@0: infos["connectors"].append(connector) etisserant@0: elif isinstance(instance, plcopen.rightPowerRail): etisserant@0: infos["type"] = "rightPowerRail" etisserant@0: infos["connectors"] = [] etisserant@0: for connection in instance.getConnectionPointIn(): etisserant@0: connector = {} etisserant@0: connector["position"] = connection.getRelPosition() etisserant@0: connector["links"] = [] etisserant@0: for link in connection.getConnections(): etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: connector["links"].append(dic) etisserant@0: infos["connectors"].append(connector) etisserant@0: elif isinstance(instance, plcopen.contact): etisserant@0: infos["type"] = "contact" etisserant@0: infos["name"] = instance.getVariable() etisserant@0: infos["negated"] = instance.getNegated() etisserant@0: infos["edge"] = instance.getContactEdge() etisserant@0: infos["connectors"] = {"input":{},"output":{}} etisserant@0: infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connectors"]["input"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connectors"]["input"]["links"].append(dic) etisserant@0: infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: elif isinstance(instance, plcopen.coil): etisserant@0: infos["type"] = "coil" etisserant@0: infos["name"] = instance.getVariable() etisserant@0: infos["negated"] = instance.getNegated() etisserant@0: infos["storage"] = instance.getCoilStorage() etisserant@0: infos["connectors"] = {"input":{},"output":{}} etisserant@0: infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connectors"]["input"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connectors"]["input"]["links"].append(dic) etisserant@0: infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: elif isinstance(instance, plcopen.step): etisserant@0: infos["type"] = "step" etisserant@0: infos["name"] = instance.getName() etisserant@0: infos["initial"] = instance.getInitialStep() etisserant@0: infos["connectors"] = {} etisserant@0: if instance.connectionPointIn: etisserant@0: infos["connectors"]["input"] = {} etisserant@0: infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connectors"]["input"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connectors"]["input"]["links"].append(dic) etisserant@0: if instance.connectionPointOut: etisserant@0: infos["connectors"]["output"] = {"position" : instance.connectionPointOut.getRelPosition()} etisserant@0: if instance.connectionPointOutAction: etisserant@0: infos["connectors"]["action"] = {"position" : instance.connectionPointOutAction.getRelPosition()} etisserant@0: elif isinstance(instance, plcopen.transition): etisserant@0: infos["type"] = "transition" etisserant@0: condition = instance.getConditionContent() etisserant@0: infos["condition_type"] = condition["type"] etisserant@0: infos["condition"] = condition["value"] etisserant@0: infos["connectors"] = {"input":{},"output":{}} etisserant@0: infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connectors"]["input"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connectors"]["input"]["links"].append(dic) etisserant@0: infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: elif isinstance(instance, (plcopen.selectionDivergence, plcopen.simultaneousDivergence)): etisserant@0: if isinstance(instance, plcopen.selectionDivergence): etisserant@0: infos["type"] = "selectionDivergence" etisserant@0: else: etisserant@0: infos["type"] = "simultaneousDivergence" etisserant@0: infos["connectors"] = {"inputs":[],"outputs":[]} etisserant@0: connector = {} etisserant@0: connector["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: connector["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: connector["links"].append(dic) etisserant@0: infos["connectors"]["inputs"].append(connector) etisserant@0: for sequence in instance.getConnectionPointOut(): etisserant@0: connector = {} etisserant@0: connector["position"] = sequence.getRelPosition() etisserant@0: infos["connectors"]["outputs"].append(connector) etisserant@0: elif isinstance(instance, (plcopen.selectionConvergence, plcopen.simultaneousConvergence)): etisserant@0: if isinstance(instance, plcopen.selectionConvergence): etisserant@0: infos["type"] = "selectionConvergence" etisserant@0: else: etisserant@0: infos["type"] = "simultaneousConvergence" etisserant@0: infos["connectors"] = {"inputs":[],"outputs":[]} etisserant@0: for sequence in instance.getConnectionPointIn(): etisserant@0: connector = {} etisserant@0: connector["position"] = sequence.getRelPosition() etisserant@0: connector["links"] = [] etisserant@0: connections = sequence.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: connector["links"].append(dic) etisserant@0: infos["connectors"]["inputs"].append(connector) etisserant@0: connector = {} etisserant@0: connector["position"] = instance.connectionPointOut.getRelPosition() etisserant@0: infos["connectors"]["outputs"].append(connector) etisserant@0: elif isinstance(instance, plcopen.jumpStep): etisserant@0: infos["type"] = "jump" etisserant@0: infos["target"] = instance.getTargetName() etisserant@0: infos["connector"] = {} etisserant@0: infos["connector"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connector"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connector"]["links"].append(dic) etisserant@0: elif isinstance(instance, plcopen.actionBlock): etisserant@0: infos["type"] = "actionBlock" etisserant@0: infos["actions"] = instance.getActions() etisserant@0: infos["connector"] = {} etisserant@0: infos["connector"]["position"] = instance.connectionPointIn.getRelPosition() etisserant@0: infos["connector"]["links"] = [] etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections: etisserant@0: for link in connections: etisserant@0: dic = {"refLocalId":link.getRefLocalId(),"points":link.getPoints()} etisserant@0: infos["connector"]["links"].append(dic) etisserant@0: return infos etisserant@0: return False etisserant@0: etisserant@0: # Return the variable type of the given pou etisserant@0: def GetPouVarValueType(self, pou, varname): etisserant@0: for type, varlist in pou.getVars(): etisserant@0: for var in varlist.getVariable(): etisserant@0: if var.getName() == varname: etisserant@0: return var.getType() etisserant@0: return "" etisserant@0: etisserant@0: def SetConnectionWires(self, connection, connector): etisserant@0: wires = connector.GetWires() etisserant@0: idx = 0 etisserant@0: for wire, handle in wires: etisserant@0: points = wire.GetPoints(handle != 0) etisserant@0: if handle == 0: etisserant@0: refLocalId = wire.GetConnectedId(-1) etisserant@0: else: etisserant@0: refLocalId = wire.GetConnectedId(0) etisserant@0: if refLocalId != None: etisserant@0: connection.addConnection() etisserant@0: connection.setConnectionId(idx, refLocalId) etisserant@0: connection.setConnectionPoints(idx, points) etisserant@0: idx += 1 etisserant@0: etisserant@0: def AddCurrentElementEditingBlock(self, id): etisserant@0: block = plcopen.block() etisserant@0: block.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("block", block) etisserant@0: self.RefreshPouUsingTree() etisserant@0: etisserant@0: def SetCurrentElementEditingBlockInfos(self, id, infos): etisserant@0: block = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "name": etisserant@0: block.setInstanceName(value) etisserant@0: elif param == "type": etisserant@0: block.setTypeName(value) etisserant@0: elif param == "height": etisserant@0: block.setHeight(value) etisserant@0: elif param == "width": etisserant@0: block.setWidth(value) etisserant@0: elif param == "x": etisserant@0: block.setX(value) etisserant@0: elif param == "y": etisserant@0: block.setY(value) etisserant@0: elif param == "connectors": etisserant@0: block.inputVariables.setVariable([]) etisserant@0: block.outputVariables.setVariable([]) etisserant@0: for connector in value["inputs"]: etisserant@0: variable = plcopen.inputVariables_variable() etisserant@0: variable.setFormalParameter(connector.GetName()) etisserant@0: if connector.IsNegated(): etisserant@0: variable.setNegated(True) etisserant@0: if connector.GetEdge() != "none": etisserant@0: variable.setConnectorEdge(connector.GetEdge()) etisserant@0: position = connector.GetRelPosition() etisserant@0: variable.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(variable.connectionPointIn, connector) etisserant@0: block.inputVariables.appendVariable(variable) etisserant@0: for connector in value["outputs"]: etisserant@0: variable = plcopen.outputVariables_variable() etisserant@0: variable.setFormalParameter(connector.GetName()) etisserant@0: if connector.IsNegated(): etisserant@0: variable.setNegated(True) etisserant@0: if connector.GetEdge() != "none": etisserant@0: variable.setConnectorEdge(connector.GetEdge()) etisserant@0: position = connector.GetRelPosition() etisserant@0: variable.addConnectionPointOut() etisserant@0: variable.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: block.outputVariables.appendVariable(variable) etisserant@0: self.RefreshPouUsingTree() etisserant@0: etisserant@0: def AddCurrentElementEditingVariable(self, id, type): etisserant@0: if type == INPUT: etisserant@0: name = "inVariable" etisserant@0: variable = plcopen.inVariable() etisserant@0: elif type == OUTPUT: etisserant@0: name = "outVariable" etisserant@0: variable = plcopen.outVariable() etisserant@0: elif type == INOUT: etisserant@0: name = "inOutVariable" etisserant@0: variable = plcopen.inOutVariable() etisserant@0: variable.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance(name, variable) etisserant@0: etisserant@0: def SetCurrentElementEditingVariableInfos(self, id, infos): etisserant@0: variable = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "name": etisserant@0: variable.setExpression(value) etisserant@0: elif param == "height": etisserant@0: variable.setHeight(value) etisserant@0: elif param == "width": etisserant@0: variable.setWidth(value) etisserant@0: elif param == "x": etisserant@0: variable.setX(value) etisserant@0: elif param == "y": etisserant@0: variable.setY(value) etisserant@0: elif param == "connectors": etisserant@0: if isinstance(variable, plcopen.inVariable): etisserant@0: if value["output"].IsNegated(): etisserant@0: variable.setNegated(True) etisserant@0: if value["output"].GetEdge() != "none": etisserant@0: variable.setConnectorEdge(value["output"].GetEdge()) etisserant@0: position = value["output"].GetRelPosition() etisserant@0: variable.addConnectionPointOut() etisserant@0: variable.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: elif isinstance(variable, plcopen.outVariable): etisserant@0: if value["input"].IsNegated(): etisserant@0: variable.setNegated(True) etisserant@0: if value["input"].GetEdge() != "none": etisserant@0: variable.setConnectorEdge(value["input"].GetEdge()) etisserant@0: position = value["input"].GetRelPosition() etisserant@0: variable.addConnectionPointIn() etisserant@0: variable.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(variable.connectionPointIn, value["input"]) etisserant@0: elif isinstance(variable, plcopen.inOutVariable): etisserant@0: if value["input"].IsNegated(): etisserant@0: variable.setNegatedIn(True) etisserant@0: if value["input"].GetEdge() != "none": etisserant@0: variable.setInputEdge(value["input"].GetEdge()) etisserant@0: if value["output"].IsNegated(): etisserant@0: variable.setNegatedOut(True) etisserant@0: if value["output"].GetEdge() != "none": etisserant@0: variable.setOutputEdge(value["output"].GetEdge()) etisserant@0: position = value["output"].GetRelPosition() etisserant@0: variable.addConnectionPointOut() etisserant@0: variable.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: position = value["input"].GetRelPosition() etisserant@0: variable.addConnectionPointIn() etisserant@0: variable.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(variable.connectionPointIn, value["input"]) etisserant@0: etisserant@0: etisserant@0: def AddCurrentElementEditingConnection(self, id, type): etisserant@0: if type == CONNECTOR: etisserant@0: name = "connector" etisserant@0: connection = plcopen.connector() etisserant@0: elif type == CONTINUATION: etisserant@0: name = "continuation" etisserant@0: connection = plcopen.continuation() etisserant@0: connection.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance(name, connection) etisserant@0: etisserant@0: def SetCurrentElementEditingConnectionInfos(self, id, infos): etisserant@0: connection = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "name": etisserant@0: connection.setName(value) etisserant@0: elif param == "height": etisserant@0: connection.setHeight(value) etisserant@0: elif param == "width": etisserant@0: connection.setWidth(value) etisserant@0: elif param == "x": etisserant@0: connection.setX(value) etisserant@0: elif param == "y": etisserant@0: connection.setY(value) etisserant@0: elif param == "connector": etisserant@0: position = value.GetRelPosition() etisserant@0: if isinstance(connection, plcopen.continuation): etisserant@0: connection.addConnectionPointOut() etisserant@0: connection.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: elif isinstance(connection, plcopen.connector): etisserant@0: connection.addConnectionPointIn() etisserant@0: connection.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(connection.connectionPointIn, value) etisserant@0: etisserant@0: def AddCurrentElementEditingComment(self, id): etisserant@0: comment = plcopen.comment() etisserant@0: comment.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("comment", comment) etisserant@0: etisserant@0: def SetCurrentElementEditingCommentInfos(self, id, infos): etisserant@0: comment = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "content": etisserant@0: comment.setContentText(value) etisserant@0: elif param == "height": etisserant@0: comment.setHeight(value) etisserant@0: elif param == "width": etisserant@0: comment.setWidth(value) etisserant@0: elif param == "x": etisserant@0: comment.setX(value) etisserant@0: elif param == "y": etisserant@0: comment.setY(value) etisserant@0: etisserant@0: def AddCurrentElementEditingPowerRail(self, id, type): etisserant@0: if type == LEFTRAIL: etisserant@0: name = "leftPowerRail" etisserant@0: powerrail = plcopen.leftPowerRail() etisserant@0: elif type == RIGHTRAIL: etisserant@0: name = "rightPowerRail" etisserant@0: powerrail = plcopen.rightPowerRail() etisserant@0: powerrail.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance(name, powerrail) etisserant@0: etisserant@0: def SetCurrentElementEditingPowerRailInfos(self, id, infos): etisserant@0: powerrail = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "height": etisserant@0: powerrail.setHeight(value) etisserant@0: elif param == "width": etisserant@0: powerrail.setWidth(value) etisserant@0: elif param == "x": etisserant@0: powerrail.setX(value) etisserant@0: elif param == "y": etisserant@0: powerrail.setY(value) etisserant@0: elif param == "connectors": etisserant@0: if isinstance(powerrail, plcopen.leftPowerRail): etisserant@0: powerrail.setConnectionPointOut([]) etisserant@0: for connector in value: etisserant@0: position = connector.GetRelPosition() etisserant@0: connection = plcopen.leftPowerRail_connectionPointOut() etisserant@0: connection.setRelPosition(position.x, position.y) etisserant@0: powerrail.connectionPointOut.append(connection) etisserant@0: elif isinstance(powerrail, plcopen.rightPowerRail): etisserant@0: powerrail.setConnectionPointIn([]) etisserant@0: for connector in value: etisserant@0: position = connector.GetRelPosition() etisserant@0: connection = plcopen.connectionPointIn() etisserant@0: connection.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(connection, connector) etisserant@0: powerrail.connectionPointIn.append(connection) etisserant@0: etisserant@0: def AddCurrentElementEditingContact(self, id): etisserant@0: contact = plcopen.contact() etisserant@0: contact.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("contact", contact) etisserant@0: etisserant@0: def SetCurrentElementEditingContactInfos(self, id, infos): etisserant@0: contact = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "name": etisserant@0: contact.setVariable(value) etisserant@0: elif param == "type": etisserant@0: if value == CONTACT_NORMAL: etisserant@0: contact.setNegated(False) etisserant@0: contact.setContactEdge("none") etisserant@0: elif value == CONTACT_REVERSE: etisserant@0: contact.setNegated(True) etisserant@0: contact.setContactEdge("none") etisserant@0: elif value == CONTACT_RISING: etisserant@0: contact.setNegated(False) etisserant@0: contact.setContactEdge("rising") etisserant@0: elif value == CONTACT_FALLING: etisserant@0: contact.setNegated(False) etisserant@0: contact.setContactEdge("falling") etisserant@0: elif param == "height": etisserant@0: contact.setHeight(value) etisserant@0: elif param == "width": etisserant@0: contact.setWidth(value) etisserant@0: elif param == "x": etisserant@0: contact.setX(value) etisserant@0: elif param == "y": etisserant@0: contact.setY(value) etisserant@0: elif param == "connectors": etisserant@0: input_connector = value["input"] etisserant@0: position = input_connector.GetRelPosition() etisserant@0: contact.addConnectionPointIn() etisserant@0: contact.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(contact.connectionPointIn, input_connector) etisserant@0: output_connector = value["output"] etisserant@0: position = output_connector.GetRelPosition() etisserant@0: contact.addConnectionPointOut() etisserant@0: contact.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: etisserant@0: def AddCurrentElementEditingCoil(self, id): etisserant@0: coil = plcopen.coil() etisserant@0: coil.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("coil", coil) etisserant@0: etisserant@0: def SetCurrentElementEditingCoilInfos(self, id, infos): etisserant@0: coil = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "name": etisserant@0: coil.setVariable(value) etisserant@0: elif param == "type": etisserant@0: if value == COIL_NORMAL: etisserant@0: coil.setNegated(False) etisserant@0: coil.setCoilStorage("none") etisserant@0: elif value == COIL_REVERSE: etisserant@0: coil.setNegated(True) etisserant@0: coil.setCoilStorage("none") etisserant@0: elif value == COIL_SET: etisserant@0: coil.setNegated(False) etisserant@0: coil.setCoilStorage("set") etisserant@0: elif value == COIL_RESET: etisserant@0: coil.setNegated(False) etisserant@0: coil.setCoilStorage("reset") etisserant@0: elif param == "height": etisserant@0: coil.setHeight(value) etisserant@0: elif param == "width": etisserant@0: coil.setWidth(value) etisserant@0: elif param == "x": etisserant@0: coil.setX(value) etisserant@0: elif param == "y": etisserant@0: coil.setY(value) etisserant@0: elif param == "connectors": etisserant@0: input_connector = value["input"] etisserant@0: position = input_connector.GetRelPosition() etisserant@0: coil.addConnectionPointIn() etisserant@0: coil.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(coil.connectionPointIn, input_connector) etisserant@0: output_connector = value["output"] etisserant@0: position = output_connector.GetRelPosition() etisserant@0: coil.addConnectionPointOut() etisserant@0: coil.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: etisserant@0: def AddCurrentElementEditingStep(self, id): etisserant@0: step = plcopen.step() etisserant@0: step.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("step", step) etisserant@0: etisserant@0: def SetCurrentElementEditingStepInfos(self, id, infos): etisserant@0: step = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "name": etisserant@0: step.setName(value) etisserant@0: elif param == "initial": etisserant@0: step.setInitialStep(value) etisserant@0: elif param == "height": etisserant@0: step.setHeight(value) etisserant@0: elif param == "width": etisserant@0: step.setWidth(value) etisserant@0: elif param == "x": etisserant@0: step.setX(value) etisserant@0: elif param == "y": etisserant@0: step.setY(value) etisserant@0: elif param == "connectors": etisserant@0: input_connector = value["input"] etisserant@0: if input_connector: etisserant@0: position = input_connector.GetRelPosition() etisserant@0: step.addConnectionPointIn() etisserant@0: step.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(step.connectionPointIn, input_connector) etisserant@0: else: etisserant@0: step.deleteConnectionPointIn() etisserant@0: output_connector = value["output"] etisserant@0: if output_connector: etisserant@0: position = output_connector.GetRelPosition() etisserant@0: step.addConnectionPointOut() etisserant@0: step.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: else: etisserant@0: step.deleteConnectionPointOut() etisserant@0: action_connector = value["action"] etisserant@0: if action_connector: etisserant@0: position = action_connector.GetRelPosition() etisserant@0: step.addConnectionPointOutAction() etisserant@0: step.connectionPointOutAction.setRelPosition(position.x, position.y) etisserant@0: else: etisserant@0: step.deleteConnectionPointOutAction() etisserant@0: etisserant@0: def AddCurrentElementEditingTransition(self, id): etisserant@0: transition = plcopen.transition() etisserant@0: transition.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("transition", transition) etisserant@0: etisserant@0: def SetCurrentElementEditingTransitionInfos(self, id, infos): etisserant@0: transition = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "type" and "condition" in infos: etisserant@0: transition.setConditionContent(value, infos["condition"]) etisserant@0: elif param == "height": etisserant@0: transition.setHeight(value) etisserant@0: elif param == "width": etisserant@0: transition.setWidth(value) etisserant@0: elif param == "x": etisserant@0: transition.setX(value) etisserant@0: elif param == "y": etisserant@0: transition.setY(value) etisserant@0: elif param == "connectors": etisserant@0: input_connector = value["input"] etisserant@0: position = input_connector.GetRelPosition() etisserant@0: transition.addConnectionPointIn() etisserant@0: transition.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(transition.connectionPointIn, input_connector) etisserant@0: output_connector = value["output"] etisserant@0: position = output_connector.GetRelPosition() etisserant@0: transition.addConnectionPointOut() etisserant@0: transition.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: etisserant@0: def AddCurrentElementEditingDivergence(self, id, type): etisserant@0: if type == SELECTION_DIVERGENCE: etisserant@0: name = "selectionDivergence" etisserant@0: divergence = plcopen.selectionDivergence() etisserant@0: elif type == SELECTION_CONVERGENCE: etisserant@0: name = "selectionConvergence" etisserant@0: divergence = plcopen.selectionConvergence() etisserant@0: elif type == SIMULTANEOUS_DIVERGENCE: etisserant@0: name = "simultaneousDivergence" etisserant@0: divergence = plcopen.simultaneousDivergence() etisserant@0: elif type == SIMULTANEOUS_CONVERGENCE: etisserant@0: name = "simultaneousConvergence" etisserant@0: divergence = plcopen.simultaneousConvergence() etisserant@0: divergence.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance(name, divergence) etisserant@0: etisserant@0: def SetCurrentElementEditingDivergenceInfos(self, id, infos): etisserant@0: divergence = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "height": etisserant@0: divergence.setHeight(value) etisserant@0: elif param == "width": etisserant@0: divergence.setWidth(value) etisserant@0: elif param == "x": etisserant@0: divergence.setX(value) etisserant@0: elif param == "y": etisserant@0: divergence.setY(value) etisserant@0: elif param == "connectors": etisserant@0: input_connectors = value["inputs"] etisserant@0: if isinstance(divergence, (plcopen.selectionDivergence, plcopen.simultaneousDivergence)): etisserant@0: position = input_connectors[0].GetRelPosition() etisserant@0: divergence.addConnectionPointIn() etisserant@0: divergence.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0]) etisserant@0: else: etisserant@0: divergence.setConnectionPointIn([]) etisserant@0: for input_connector in input_connectors: etisserant@0: position = input_connector.GetRelPosition() etisserant@0: if isinstance(divergence, plcopen.selectionConvergence): etisserant@0: connection = plcopen.selectionConvergence_connectionPointIn() etisserant@0: else: etisserant@0: connection = plcopen.connectionPointIn() etisserant@0: connection.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(connection, input_connector) etisserant@0: divergence.appendConnectionPointIn(connection) etisserant@0: output_connectors = value["outputs"] etisserant@0: if isinstance(divergence, (plcopen.selectionConvergence, plcopen.simultaneousConvergence)): etisserant@0: position = output_connectors[0].GetRelPosition() etisserant@0: divergence.addConnectionPointOut() etisserant@0: divergence.connectionPointOut.setRelPosition(position.x, position.y) etisserant@0: else: etisserant@0: divergence.setConnectionPointOut([]) etisserant@0: for output_connector in output_connectors: etisserant@0: position = output_connector.GetRelPosition() etisserant@0: if isinstance(divergence, plcopen.selectionDivergence): etisserant@0: connection = plcopen.selectionDivergence_connectionPointOut() etisserant@0: else: etisserant@0: connection = plcopen.simultaneousDivergence_connectionPointOut() etisserant@0: connection.setRelPosition(position.x, position.y) etisserant@0: divergence.appendConnectionPointOut(connection) etisserant@0: etisserant@0: def AddCurrentElementEditingJump(self, id): etisserant@0: jump = plcopen.jumpStep() etisserant@0: jump.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("jumpStep", jump) etisserant@0: etisserant@0: def SetCurrentElementEditingJumpInfos(self, id, infos): etisserant@0: jump = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "target": etisserant@0: jump.setTargetName(value) etisserant@0: elif param == "height": etisserant@0: jump.setHeight(value) etisserant@0: elif param == "width": etisserant@0: jump.setWidth(value) etisserant@0: elif param == "x": etisserant@0: jump.setX(value) etisserant@0: elif param == "y": etisserant@0: jump.setY(value) etisserant@0: elif param == "connector": etisserant@0: position = value.GetRelPosition() etisserant@0: jump.addConnectionPointIn() etisserant@0: jump.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(jump.connectionPointIn, value) etisserant@0: etisserant@0: def AddCurrentElementEditingActionBlock(self, id): etisserant@0: actionBlock = plcopen.actionBlock() etisserant@0: actionBlock.setLocalId(id) etisserant@0: self.GetCurrentElementEditing().addInstance("actionBlock", actionBlock) etisserant@0: etisserant@0: def SetCurrentElementEditingActionBlockInfos(self, id, infos): etisserant@0: actionBlock = self.GetCurrentElementEditing().getInstance(id) etisserant@0: for param, value in infos.items(): etisserant@0: if param == "actions": etisserant@0: actionBlock.setActions(value) etisserant@0: elif param == "height": etisserant@0: actionBlock.setHeight(value) etisserant@0: elif param == "width": etisserant@0: actionBlock.setWidth(value) etisserant@0: elif param == "x": etisserant@0: actionBlock.setX(value) etisserant@0: elif param == "y": etisserant@0: actionBlock.setY(value) etisserant@0: elif param == "connector": etisserant@0: position = value.GetRelPosition() etisserant@0: actionBlock.addConnectionPointIn() etisserant@0: actionBlock.connectionPointIn.setRelPosition(position.x, position.y) etisserant@0: self.SetConnectionWires(actionBlock.connectionPointIn, value) etisserant@0: etisserant@0: def RemoveCurrentElementEditingInstance(self, id): etisserant@0: self.GetCurrentElementEditing().removeInstance(id) etisserant@0: self.RefreshPouUsingTree() etisserant@0: etisserant@0: def GetCurrentResourceEditingVariables(self): etisserant@0: varlist = [] etisserant@0: name = self.ElementsOpened[self.CurrentElementEditing] etisserant@0: words = name.split("::") etisserant@0: for var in self.GetConfigurationGlobalVars(words[1]): etisserant@0: if var["Type"] == "BOOL": etisserant@0: varlist.append(var["Name"]) etisserant@0: for var in self.GetConfigurationResourceGlobalVars(words[1], words[2]): etisserant@0: if var["Type"] == "BOOL": etisserant@0: varlist.append(var["Name"]) etisserant@0: return varlist etisserant@0: etisserant@0: def SetCurrentResourceEditingInfos(self, tasks, instances): etisserant@0: resource = self.GetCurrentElementEditing() etisserant@0: resource.setTask([]) etisserant@0: resource.setPouInstance([]) etisserant@0: task_list = {} etisserant@0: for task in tasks: etisserant@0: new_task = plcopen.resource_task() etisserant@0: new_task.setName(task["Name"]) etisserant@0: if task["Single"] != "": etisserant@0: new_task.setSingle(task["Single"]) etisserant@0: if task["Interval"] != "": etisserant@0: new_task.setInterval(task["Interval"]) etisserant@0: new_task.priority.setValue(int(task["Priority"])) etisserant@0: if task["Name"] != "": etisserant@0: task_list[task["Name"]] = new_task etisserant@0: resource.appendTask(new_task) etisserant@0: for instance in instances: etisserant@0: new_instance = plcopen.pouInstance() etisserant@0: new_instance.setName(instance["Name"]) etisserant@0: new_instance.setType(instance["Type"]) etisserant@0: if instance["Task"] != "": etisserant@0: task_list[instance["Task"]].appendPouInstance(new_instance) etisserant@0: else: etisserant@0: resource.appendPouInstance(new_instance) etisserant@0: etisserant@0: def GetCurrentResourceEditingInfos(self): etisserant@0: resource = self.GetCurrentElementEditing() etisserant@0: tasks = resource.getTask() etisserant@0: instances = resource.getPouInstance() etisserant@0: tasks_data = [] etisserant@0: instances_data = [] etisserant@0: for task in tasks: etisserant@0: new_task = {} etisserant@0: new_task["Name"] = task.getName() etisserant@0: single = task.getSingle() etisserant@0: if single: etisserant@0: new_task["Single"] = single etisserant@0: else: etisserant@0: new_task["Single"] = "" etisserant@0: interval = task.getInterval() etisserant@0: if interval: etisserant@0: new_task["Interval"] = interval etisserant@0: else: etisserant@0: new_task["Interval"] = "" etisserant@0: new_task["Priority"] = str(task.priority.getValue()) etisserant@0: tasks_data.append(new_task) etisserant@0: for instance in task.getPouInstance(): etisserant@0: new_instance = {} etisserant@0: new_instance["Name"] = instance.getName() etisserant@0: new_instance["Type"] = instance.getType() etisserant@0: new_instance["Task"] = task.getName() etisserant@0: instances_data.append(new_instance) etisserant@0: for instance in instances: etisserant@0: new_instance = {} etisserant@0: new_instance["Name"] = instance.getName() etisserant@0: new_instance["Type"] = instance.getType() etisserant@0: new_instance["Task"] = "" etisserant@0: instances_data.append(new_instance) etisserant@0: return tasks_data, instances_data etisserant@0: etisserant@0: def OpenXMLFile(self, filepath): etisserant@0: if sys: etisserant@0: sys.stdout = plcopen.HolePseudoFile() etisserant@0: tree = pyxsval.parseAndValidate(filepath, "plcopen/TC6_XML_V10_B.xsd") etisserant@0: if sys: etisserant@0: sys.stdout = sys.__stdout__ etisserant@0: etisserant@0: self.Project = plcopen.project() etisserant@0: self.Project.loadXMLTree(tree.getTree().childNodes[0]) etisserant@0: self.UndoBuffer = UndoBuffer(self.Copy(self.Project), True) etisserant@0: self.SetFilePath(filepath) etisserant@0: self.ElementsOpened = [] etisserant@0: self.CurrentElementEditing = None etisserant@0: self.RefreshPouUsingTree() etisserant@0: self.RefreshBlockTypes() etisserant@0: etisserant@0: def SaveXMLFile(self, filepath = None): etisserant@0: if not filepath and self.FilePath == "": etisserant@0: return False etisserant@0: else: etisserant@0: text = "\n" etisserant@0: extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd", etisserant@0: "xmlns:xhtml" : "http://www.w3.org/1999/xhtml", etisserant@0: "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", etisserant@0: "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd http://www.plcopen.org/xml/tc6.xsd"} etisserant@0: text += self.Project.generateXMLText("project", 0, extras) etisserant@0: etisserant@0: if sys: etisserant@0: sys.stdout = plcopen.HolePseudoFile() etisserant@0: pyxsval.parseAndValidateString(text, open("plcopen/TC6_XML_V10_B.xsd","r").read()) etisserant@0: if sys: etisserant@0: sys.stdout = sys.__stdout__ etisserant@0: etisserant@0: if filepath: etisserant@0: xmlfile = open(filepath,"w") etisserant@0: else: etisserant@0: xmlfile = open(self.FilePath,"w") etisserant@0: xmlfile.write(text) etisserant@0: xmlfile.close() etisserant@0: self.UndoBuffer.CurrentSaved() etisserant@0: if filepath: etisserant@0: self.SetFilePath(filepath) etisserant@0: return True etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Current Buffering Management Functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: """ etisserant@0: Return a copy of the project etisserant@0: """ etisserant@0: def Copy(self, model): etisserant@0: return cPickle.loads(cPickle.dumps(model)) etisserant@0: etisserant@0: def BufferProject(self): etisserant@0: self.UndoBuffer.Buffering(self.Copy(self)) etisserant@0: etisserant@0: def ProjectIsSaved(self): etisserant@0: return self.UndoBuffer.IsCurrentSaved() etisserant@0: etisserant@0: def LoadPrevious(self): etisserant@0: self.Project = self.Copy(self.UndoBuffer.Previous()) etisserant@0: self.RefreshElementsOpened() etisserant@0: etisserant@0: def LoadNext(self): etisserant@0: self.Project = self.Copy(self.UndoBuffer.Next()) etisserant@0: self.RefreshElementsOpened() etisserant@0: etisserant@0: def GetBufferState(self): etisserant@0: first = self.UndoBuffer.IsFirst() etisserant@0: last = self.UndoBuffer.IsLast() etisserant@0: return not first, not last