class _EthercatCTN(object): CTNChildrenTypes = [("EthercatSlave", _EthercatSlaveCTN, "Ethercat Slave")] if HAS_MCL: CTNChildrenTypes.append( ("EthercatCIA402Slave", _EthercatCIA402SlaveCTN, "Ethercat CIA402 Slave")) EditorType = MasterEditor def __init__(self): config_filepath = self.ConfigFileName() config_is_saved = False self.Config = None # if os.path.isfile(config_filepath): # config_xmlfile = open(config_filepath, 'r') # try: # self.Config, error = \ # EtherCATConfigParser.LoadXMLString(config_xmlfile.read()) # if error is None: # config_is_saved = True # except Exception as e: # error = str(e) # config_xmlfile.close() # if error is not None: # self.GetCTRoot().logger.write_error( # _("Couldn't load %s network configuration file.") % self.CTNName()) if self.Config is None: self.Config = EtherCATConfigParser.CreateElement("EtherCATConfig") process_filepath = self.ProcessVariablesFileName() process_is_saved = False self.ProcessVariables = None if os.path.isfile(process_filepath): process_xmlfile = open(process_filepath, 'r', encoding='utf-8') try: self.ProcessVariables, error = \ ProcessVariablesParser.LoadXMLString(process_xmlfile.read()) if error is None: process_is_saved = True except Exception as e: error = str(e) process_xmlfile.close() if error is not None: self.GetCTRoot().logger.write_error( _("Couldn't load %s network process variables file.") % self.CTNName()) if self.ProcessVariables is None: self.ProcessVariables = ProcessVariablesParser.CreateElement( "ProcessVariables") # if config_is_saved and process_is_saved: if process_is_saved: self.CreateBuffer(True) else: self.CreateBuffer(False) self.OnCTNSave() if os.path.isfile(config_filepath): config_xmlfile = open(config_filepath, 'r', encoding='utf-8') try: self.Config, error = \ EtherCATConfigParser.LoadXMLString(config_xmlfile.read()) if error is None: config_is_saved = True except Exception as e: error = e.message config_xmlfile.close() if error is not None: self.GetCTRoot().logger.write_error( _("Couldn't load %s network configuration file.") % self.CTNName()) # ----------- call ethercat mng. function -------------- self.CommonMethod = _CommonSlave(self) def GetIconName(self): return "Ethercat" def GetContextualMenuItems(self): return [(_("Add Ethercat Slave"), _("Add Ethercat Slave to Master"), self.OnAddEthercatSlave)] def OnAddEthercatSlave(self, event): app_frame = self.GetCTRoot().AppFrame dialog = BrowseValuesLibraryDialog(app_frame, _("Ethercat Slave Type"), self.GetSlaveTypesLibrary()) if dialog.ShowModal() == wx.ID_OK: type_infos = dialog.GetValueInfos() device, _module_extra_params = self.GetModuleInfos(type_infos) if device is not None: if HAS_MCL and str(_EthercatCIA402SlaveCTN.NODE_PROFILE ) in device.GetProfileNumbers(): ConfNodeType = "EthercatCIA402Slave" else: ConfNodeType = "EthercatSlave" new_child = self.CTNAddChild("%s_0" % ConfNodeType, ConfNodeType) new_child.SetParamsAttribute("SlaveParams.Type", type_infos) self.CTNRequestSave() new_child._OpenView() app_frame._Refresh(TITLE, FILEMENU, PROJECTTREE) dialog.Destroy() def ExtractHexDecValue(self, value): return ExtractHexDecValue(value) def GetSizeOfType(self, type): return TYPECONVERSION.get(self.GetCTRoot().GetBaseType(type), None) def ConfigFileName(self): return os.path.join(self.CTNPath(), "config.xml") def ProcessVariablesFileName(self): return os.path.join(self.CTNPath(), "process_variables.xml") def FilterSlave(self, slave, vendor=None, slave_pos=None, slave_profile=None): if slave_pos is not None and slave.getInfo().getPhysAddr( ) != slave_pos: return False type_infos = slave.getType() if vendor is not None and ExtractHexDecValue( type_infos["vendor"]) != vendor: return False device, _module_extra_params = self.GetModuleInfos(type_infos) if slave_profile is not None and slave_profile not in device.GetProfileNumbers( ): return False return True def GetSlaveName(self, slave_pos): CTNChild = self.GetChildByIECLocation((slave_pos, )) if CTNChild is not None: return CTNChild.CTNName() return self.CTNName() def GetSlaves(self, vendor=None, slave_pos=None, slave_profile=None): slaves = [] for slave in self.Config.getConfig().getSlave(): if self.FilterSlave(slave, vendor, slave_pos, slave_profile): slaves.append(slave.getInfo().getPhysAddr()) slaves.sort() return slaves def GetSlave(self, slave_pos): for slave in self.Config.getConfig().getSlave(): slave_info = slave.getInfo() if slave_info.getPhysAddr() == slave_pos: return slave return None def GetStartupCommands(self, vendor=None, slave_pos=None, slave_profile=None): commands = [] for slave in self.Config.getConfig().getSlave(): if self.FilterSlave(slave, vendor, slave_pos, slave_profile): commands.append((slave.getInfo().getPhysAddr(), slave.getStartupCommands())) commands.sort() return reduce(lambda x, y: x + y[1], commands, []) def AppendStartupCommand(self, command_infos): slave = self.GetSlave(command_infos["Position"]) if slave is not None: command_idx = slave.appendStartupCommand(command_infos) self.BufferModel() return command_idx return None def SetStartupCommandInfos(self, command_infos): slave = self.GetSlave(command_infos["Position"]) if slave is not None: slave.setStartupCommand(command_infos) self.BufferModel() def RemoveStartupCommand(self, slave_pos, command_idx, buffer=True): slave = self.GetSlave(slave_pos) if slave is not None: slave.removeStartupCommand(command_idx) if buffer: self.BufferModel() def SetProcessVariables(self, variables): vars = [] for var in variables: variable = ProcessVariablesParser.CreateElement( "variable", "ProcessVariables") variable.setName(var["Name"]) variable.setComment(var["Description"]) if var["ReadFrom"] != "": position, index, subindex = var["ReadFrom"] if variable.getReadFrom() is None: variable.addReadFrom() read_from = variable.getReadFrom() read_from.setPosition(position) read_from.setIndex(index) read_from.setSubIndex(subindex) elif variable.getReadFrom() is not None: variable.deleteReadFrom() if var["WriteTo"] != "": position, index, subindex = var["WriteTo"] if variable.getWriteTo() is None: variable.addWriteTo() write_to = variable.getWriteTo() write_to.setPosition(position) write_to.setIndex(index) write_to.setSubIndex(subindex) elif variable.getWriteTo() is not None: variable.deleteWriteTo() vars.append(variable) self.ProcessVariables.setvariable(vars) self.BufferModel() def GetProcessVariables(self): variables = [] idx = 0 for variable in self.ProcessVariables.getvariable(): var = { "Name": variable.getName(), "Number": idx, "Description": variable.getComment() } read_from = variable.getReadFrom() if read_from is not None: var["ReadFrom"] = (read_from.getPosition(), read_from.getIndex(), read_from.getSubIndex()) else: var["ReadFrom"] = "" write_to = variable.getWriteTo() if write_to is not None: var["WriteTo"] = (write_to.getPosition(), write_to.getIndex(), write_to.getSubIndex()) else: var["WriteTo"] = "" variables.append(var) idx += 1 return variables def _ScanNetwork(self): app_frame = self.GetCTRoot().AppFrame execute = True if len(self.Children) > 0: dialog = wx.MessageDialog( app_frame, _("The current network configuration will be deleted.\nDo you want to continue?" ), _("Scan Network"), wx.YES_NO | wx.ICON_QUESTION) execute = dialog.ShowModal() == wx.ID_YES dialog.Destroy() if execute: error, returnVal = self.RemoteExec(SCAN_COMMAND, returnVal=None) if error != 0: dialog = wx.MessageDialog(app_frame, returnVal, _("Error"), wx.OK | wx.ICON_ERROR) dialog.ShowModal() dialog.Destroy() elif returnVal is not None: for child in self.IECSortedChildren(): self._doRemoveChild(child) for slave in returnVal: type_infos = { "vendor": slave["vendor_id"], "product_code": slave["product_code"], "revision_number": slave["revision_number"], } device, _module_extra_params = self.GetModuleInfos( type_infos) if device is not None: if HAS_MCL and _EthercatCIA402SlaveCTN.NODE_PROFILE in device.GetProfileNumbers( ): CTNType = "EthercatCIA402Slave" else: CTNType = "EthercatSlave" self.CTNAddChild("slave%s" % slave["idx"], CTNType, slave["idx"]) self.SetSlaveAlias(slave["idx"], slave["alias"]) type_infos["device_type"] = device.getType( ).getcontent() self.SetSlaveType(slave["idx"], type_infos) if app_frame: app_frame.RefreshProjectTree() def CTNAddChild(self, CTNName, CTNType, IEC_Channel=0): """ Create the confnodes that may be added as child to this node self @param CTNType: string desining the confnode class name (get name from CTNChildrenTypes) @param CTNName: string for the name of the confnode instance """ newConfNodeOpj = ConfigTreeNode.CTNAddChild(self, CTNName, CTNType, IEC_Channel) slave = self.GetSlave(newConfNodeOpj.BaseParams.getIEC_Channel()) if slave is None: slave = EtherCATConfigParser.CreateElement("Slave", "Config") self.Config.getConfig().appendSlave(slave) slave_infos = slave.getInfo() slave_infos.setName("undefined") slave_infos.setPhysAddr(newConfNodeOpj.BaseParams.getIEC_Channel()) slave_infos.setAutoIncAddr(0) self.BufferModel() self.OnCTNSave() return newConfNodeOpj def _doRemoveChild(self, CTNInstance): slave_pos = CTNInstance.GetSlavePos() config = self.Config.getConfig() for idx, slave in enumerate(config.getSlave()): slave_infos = slave.getInfo() if slave_infos.getPhysAddr() == slave_pos: config.removeSlave(idx) self.BufferModel() self.OnCTNSave() ConfigTreeNode._doRemoveChild(self, CTNInstance) def SetSlavePosition(self, slave_pos, new_pos): slave = self.GetSlave(slave_pos) if slave is not None: slave_info = slave.getInfo() slave_info.setPhysAddr(new_pos) for variable in self.ProcessVariables.getvariable(): read_from = variable.getReadFrom() if read_from is not None and read_from.getPosition( ) == slave_pos: read_from.setPosition(new_pos) write_to = variable.getWriteTo() if write_to is not None and write_to.getPosition( ) == slave_pos: write_to.setPosition(new_pos) self.CreateBuffer(True) self.CTNRequestSave() if self._View is not None: self._View.RefreshView() self._View.RefreshBuffer() def GetSlaveAlias(self, slave_pos): slave = self.GetSlave(slave_pos) if slave is not None: slave_info = slave.getInfo() return slave_info.getAutoIncAddr() return None def SetSlaveAlias(self, slave_pos, alias): slave = self.GetSlave(slave_pos) if slave is not None: slave_info = slave.getInfo() slave_info.setAutoIncAddr(alias) self.BufferModel() def GetSlaveType(self, slave_pos): slave = self.GetSlave(slave_pos) if slave is not None: return slave.getType() return None def SetSlaveType(self, slave_pos, type_infos): slave = self.GetSlave(slave_pos) if slave is not None: slave.setType(type_infos) self.BufferModel() def GetSlaveInfos(self, slave_pos): slave = self.GetSlave(slave_pos) if slave is not None: type_infos = slave.getType() device, _module_extra_params = self.GetModuleInfos(type_infos) if device is not None: infos = type_infos.copy() infos.update({ "physics": device.getPhysics(), "sync_managers": device.GetSyncManagers(), "entries": self.GetSlaveVariables(device) }) return infos return None def GetSlaveVariables(self, slave_pos=None, limits=None, device=None, module=None): # add jblee files = os.listdir(self.CTNPath()) moduleNames = [] modulePos = 1 for file in files: filepath = os.path.join(self.CTNPath(), file) if os.path.isdir(filepath): MDPFilePath = os.path.join(filepath, "DataForMDP.txt") CheckConfNodePath = os.path.join(filepath, "baseconfnode.xml") try: moduleDataFile = open(MDPFilePath, 'r', encoding='utf-8') confNodeFile = open(CheckConfNodePath, 'r', encoding='utf-8') lines = moduleDataFile.readlines() checklines = confNodeFile.readlines() moduleDataFile.close() confNodeFile.close() module_info = self.GetModuleEntryList() # checklines(ex) : <BaseParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" IEC_Channel="0" Name="EthercatSlave_0"/> # checklines[1].split() : [<BaseParams, xmlns:xsd="http://www.w3.org/2001/XMLSchema" # IEC_Channel="0", Name="EthercatSlave_0"/>] # checklines[1].split()[2] : IEC_Channel="0" # checklines[1].split()[2].split("\"") = [IEC_Channel=, 0, ] pos_check = int(checklines[1].split()[2].split("\"")[1]) if slave_pos != pos_check: continue for line in lines: if line == "\n": continue # module_name : ST-1214, ST-2314, ... # if user add module => ST-1214 3EA, ST-2314 3EA # each result_module_name : # (ST-1214, Module 1), (ST-1214, Module 2), (ST-1214, Module 3) # (ST-2314, Module 4), (ST-2314, Module 5), (ST-2314, Module 6) module_name = line.split()[0] result_module_name = module_name + ", Module %d" % modulePos moduleNames.append(result_module_name) modulePos += 1 except: pass if device is None and slave_pos is not None: slave = self.GetSlave(slave_pos) if slave is not None: type_infos = slave.getType() device, _module_extra_params = self.GetModuleInfos(type_infos) if device is not None: # Test OD entries = device.GetEntriesList(limits) # entries = self.CTNParent.GetEntriesList() entries_list = list(entries.items()) entries_list.sort() entries = [] current_index = None current_entry = {} for (index, _subindex), entry in entries_list: entry["children"] = [] if slave_pos is not None: entry["Position"] = str(slave_pos) if index != current_index: current_index = index current_entry = entry entries.append(entry) elif current_entry: current_entry["children"].append(entry) else: entries.append(entry) increment = self.CTNParent.GetModuleIncrement()[0] count = 1 # print module_info # moduleNameAndPos : (ST-1214, Module 1), (ST-1214, Module 2), ... , # moduleNameAndPos.split(",") : ["ST-1214", " Module 1"] # moduleNameAndPos.split(",")[0] : "ST-1214" for moduleNameAndPos in moduleNames: moduleName = moduleNameAndPos.split(",")[0] modulePosName = moduleNameAndPos.split(",")[1] idx_increment = int(increment) * count for MDP_entry in module_info.get(moduleName): LocalMDPEntry = [] # print MDP_entry local_idx = MDP_entry["Index"] if ExtractHexDecValue( local_idx) == 0: # and local_idx[0] == "#": temp_index = ExtractHexDecValue(local_idx) else: temp_index = ExtractHexDecValue( MDP_entry["Index"]) + idx_increment # temp_index = ExtractHexDecValue(MDP_entry["Index"]) + idx_increment entry_index = hex(temp_index) entry_subidx = MDP_entry["SubIndex"] entry_name = MDP_entry["Name"] + ", " + " " + \ moduleName + " - " + modulePosName entry_type = MDP_entry["Type"] entry_bitsize = MDP_entry["BitSize"] entry_access = MDP_entry["Access"] mapping_type = MDP_entry["PDOMapping"] LocalMDPEntry.append({ "Index": entry_index, "SubIndex": entry_subidx, "Name": entry_name, "Type": entry_type, "BitSize": entry_bitsize, "Access": entry_access, "PDOMapping": mapping_type, "children": "" }) entries.append(LocalMDPEntry[0]) count += 1 # print entries return entries return [] def GetSlaveVariableDataType(self, slave_pos, index, subindex): slave = self.GetSlave(slave_pos) if slave is not None: device, _module_extra_params = self.GetModuleInfos(slave.getType()) if device is not None: entries = device.GetEntriesList() entry_infos = entries.get((index, subindex)) if entry_infos is not None: return entry_infos["Type"] return None def GetNodesVariables(self, vendor=None, slave_pos=None, slave_profile=None, limits=None): entries = [] for slave_position in self.GetSlaves(): if slave_pos is not None and slave_position != slave_pos: continue slave = self.GetSlave(slave_position) type_infos = slave.getType() if vendor is not None and ExtractHexDecValue( type_infos["vendor"]) != vendor: continue device, _module_extra_params = self.GetModuleInfos(type_infos) if slave_profile is not None and slave_profile not in device.GetProfileNumbers( ): continue entries.extend( self.GetSlaveVariables(slave_position, limits, device)) return entries def GetModuleInfos(self, type_infos): return self.CTNParent.GetModuleInfos(type_infos) # add jblee def GetModuleEntryList(self): return self.CTNParent.GetModuleEntryList() def GetSlaveTypesLibrary(self, profile_filter=None): return self.CTNParent.GetModulesLibrary(profile_filter) def GetLibraryVendors(self): return self.CTNParent.GetVendors() def GetDeviceLocationTree(self, slave_pos, current_location, device_name): slave = self.GetSlave(slave_pos) vars = [] # add jblee files = os.listdir(self.CTNPath()) moduleNames = [] modulePos = 1 for file in files: filepath = os.path.join(self.CTNPath(), file) if os.path.isdir(filepath): MDPFilePath = os.path.join(filepath, "DataForMDP.txt") CheckConfNodePath = os.path.join(filepath, "baseconfnode.xml") try: moduleDataFile = open(MDPFilePath, 'r', encoding='utf-8') confNodeFile = open(CheckConfNodePath, 'r', encoding='utf-8') lines = moduleDataFile.readlines() checklines = confNodeFile.readlines() moduleDataFile.close() confNodeFile.close() module_info = self.GetModuleEntryList() # checklines(ex) : <BaseParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" IEC_Channel="0" Name="EthercatSlave_0"/> # checklines[1].split() : [<BaseParams, xmlns:xsd="http://www.w3.org/2001/XMLSchema" # IEC_Channel="0", Name="EthercatSlave_0"/>] # checklines[1].split()[2] : IEC_Channel="0" # checklines[1].split()[2].split("\"") = [IEC_Channel=, 0, ] pos_check = int(checklines[1].split()[2].split("\"")[1]) if slave_pos != pos_check: continue for line in lines: if line == "\n": continue # module_name : ST-1214, ST-2314, ... # if user add module => ST-1214 3EA, ST-2314 3EA # each result_module_name : # (ST-1214, Module 1), (ST-1214, Module 2), (ST-1214, Module 3) # (ST-2314, Module 4), (ST-2314, Module 5), (ST-2314, Module 6) module_name = line.split()[0] result_module_name = module_name + ", Module %d" % modulePos moduleNames.append(result_module_name) modulePos += 1 except: pass if slave is not None: type_infos = slave.getType() device, _module_extra_params = self.GetModuleInfos(type_infos) if device is not None: sync_managers = [] for sync_manager in device.getSm(): sync_manager_control_byte = ExtractHexDecValue( sync_manager.getControlByte()) sync_manager_direction = sync_manager_control_byte & 0x0c if sync_manager_direction: sync_managers.append(LOCATION_VAR_OUTPUT) else: sync_managers.append(LOCATION_VAR_INPUT) entries = list(device.GetEntriesList().items()) entries.sort() for (index, subindex), entry in entries: var_size = self.GetSizeOfType(entry["Type"]) if var_size is not None: var_class = VARCLASSCONVERSION.get( entry["PDOMapping"], None) if var_class is not None: if var_class == LOCATION_VAR_INPUT: var_dir = "%I" else: var_dir = "%Q" vars.append({ "name": "0x%4.4x-0x%2.2x: %s" % (index, subindex, entry["Name"]), "type": var_class, "size": var_size, "IEC_type": entry["Type"], "var_name": "%s_%4.4x_%2.2x" % ("_".join( device_name.split()), index, subindex), "location": "%s%s%s" % (var_dir, var_size, ".".join( map(str, current_location + (index, subindex)))), "description": "", "children": [], }) # add jblee for MDP if not entries: increment = self.CTNParent.GetModuleIncrement()[0] count = 1 for moduleNameAndPos in moduleNames: moduleName = moduleNameAndPos.split(",")[0] idx_increment = int(increment) * count for MDP_entry in module_info.get(moduleName): local_idx = MDP_entry["Index"] if ExtractHexDecValue( local_idx) != 0 and local_idx[0] == "#": index = ExtractHexDecValue( local_idx) + idx_increment else: index = ExtractHexDecValue(MDP_entry["Index"]) subindex = int(MDP_entry["SubIndex"]) var_class = VARCLASSCONVERSION.get( MDP_entry["PDOMapping"], None) if var_class is not None: if var_class == LOCATION_VAR_INPUT: var_dir = "%I" else: var_dir = "%Q" var_size = self.GetSizeOfType(MDP_entry["Type"]) result_name = MDP_entry[ "Name"] + ", " + moduleNameAndPos vars.append({ "name": "0x%4.4x-0x%2.2x: %s" % (index, subindex, result_name), "type": var_class, "size": var_size, "IEC_type": MDP_entry["Type"], "var_name": "%s_%4.4x_%2.2x" % ("_".join( moduleName.split()), index, subindex), "location": "%s%s%s" % (var_dir, var_size, ".".join( map(str, current_location + (index, subindex)))), "description": "", "children": [] }) count += 1 return vars def CTNTestModified(self): return self.ChangesToSave or not self.ModelIsSaved() def OnCTNSave(self, from_project_path=None): config_filepath = self.ConfigFileName() config_xmlfile = open(config_filepath, "w", encoding='utf-8') config_xmlfile.write( etree.tostring(self.Config, pretty_print=True, xml_declaration=True, encoding='utf-8').decode()) config_xmlfile.close() process_filepath = self.ProcessVariablesFileName() process_xmlfile = open(process_filepath, "w", encoding='utf-8') process_xmlfile.write( etree.tostring(self.ProcessVariables, pretty_print=True, xml_declaration=True, encoding='utf-8').decode()) process_xmlfile.close() self.Buffer.CurrentSaved() return True def GetProcessVariableName(self, location, var_type): return "__M%s_%s" % (self.GetSizeOfType(var_type), "_".join( map(str, location))) def _Generate_C(self, buildpath, locations): current_location = self.GetCurrentLocation() # define a unique name for the generated C file location_str = "_".join(map(str, current_location)) Gen_Ethercatfile_path = os.path.join(buildpath, "ethercat_%s.c" % location_str) self.FileGenerator = _EthercatCFileGenerator(self) LocationCFilesAndCFLAGS, LDFLAGS, extra_files = ConfigTreeNode._Generate_C( self, buildpath, locations) for idx, variable in enumerate(self.ProcessVariables.getvariable()): name = None var_type = None read_from = variable.getReadFrom() write_to = variable.getWriteTo() if read_from is not None: pos = read_from.getPosition() index = read_from.getIndex() subindex = read_from.getSubIndex() location = current_location + (idx, ) var_type = self.GetSlaveVariableDataType(pos, index, subindex) name = self.FileGenerator.DeclareVariable( pos, index, subindex, var_type, "I", self.GetProcessVariableName(location, var_type)) if write_to is not None: pos = write_to.getPosition() index = write_to.getIndex() subindex = write_to.getSubIndex() if name is None: location = current_location + (idx, ) var_type = self.GetSlaveVariableDataType( pos, index, subindex) name = self.GetProcessVariableName(location, var_type) self.FileGenerator.DeclareVariable(pos, index, subindex, var_type, "Q", name, True) self.FileGenerator.GenerateCFile(Gen_Ethercatfile_path, location_str, self.BaseParams.getIEC_Channel()) LocationCFilesAndCFLAGS.insert(0, (current_location, [ (Gen_Ethercatfile_path, '"-I%s"' % os.path.abspath(self.GetCTRoot().GetIECLibPath())) ], True)) LDFLAGS.append("-lethercat_rtdm -lrtdm") return LocationCFilesAndCFLAGS, LDFLAGS, extra_files ConfNodeMethods = [ { "bitmap": "ScanNetwork", "name": _("Scan Network"), "tooltip": _("Scan Network"), "method": "_ScanNetwork", }, ] def CTNGenerate_C(self, buildpath, locations): current_location = self.GetCurrentLocation() slaves = self.GetSlaves() for slave_pos in slaves: slave = self.GetSlave(slave_pos) if slave is not None: self.FileGenerator.DeclareSlave(slave_pos, slave) for location in locations: loc = location["LOC"][len(current_location):] slave_pos = loc[0] if slave_pos in slaves and len( loc) == 3 and location["DIR"] != "M": self.FileGenerator.DeclareVariable(slave_pos, loc[1], loc[2], location["IEC_TYPE"], location["DIR"], location["NAME"]) return [], "", False # ------------------------------------------------------------------------------- # Current Buffering Management Functions # ------------------------------------------------------------------------------- def Copy(self, model): """Return a copy of the config""" return deepcopy(model) def CreateBuffer(self, saved): self.Buffer = UndoBuffer((EtherCATConfigParser.Dumps( self.Config), ProcessVariablesParser.Dumps(self.ProcessVariables)), saved) def BufferModel(self): self.Buffer.Buffering( (EtherCATConfigParser.Dumps(self.Config), ProcessVariablesParser.Dumps(self.ProcessVariables))) def ModelIsSaved(self): if self.Buffer is not None: return self.Buffer.IsCurrentSaved() else: return True def LoadPrevious(self): config, process_variables = self.Buffer.Previous() self.Config = EtherCATConfigParser.Loads(config) self.ProcessVariables = ProcessVariablesParser.Loads(process_variables) def LoadNext(self): config, process_variables = self.Buffer.Next() self.Config = EtherCATConfigParser.Loads(config) self.ProcessVariables = ProcessVariablesParser.Loads(process_variables) def GetBufferState(self): first = self.Buffer.IsFirst() last = self.Buffer.IsLast() return not first, not last
class CodeFile(object): CODEFILE_NAME = "CodeFile" SECTIONS_NAMES = [] def __init__(self): sections_str = {"codefile_name": self.CODEFILE_NAME} if "includes" in self.SECTIONS_NAMES: sections_str["includes_section"] = SECTION_TAG_ELEMENT % "includes" else: sections_str["includes_section"] = "" sections_str["sections"] = "\n".join( [SECTION_TAG_ELEMENT % name for name in self.SECTIONS_NAMES if name != "includes"]) self.CodeFileParser = GenerateParserFromXSDstring( CODEFILE_XSD % sections_str) self.CodeFileVariables = etree.XPath("variables/variable") filepath = self.CodeFileName() if os.path.isfile(filepath): xmlfile = open(filepath, 'r', encoding='utf-8') codefile_xml = xmlfile.read() xmlfile.close() codefile_xml = codefile_xml.replace( '<%s>' % self.CODEFILE_NAME, '<%s xmlns:xhtml="http://www.w3.org/1999/xhtml">' % self.CODEFILE_NAME) for cre, repl in [ (re.compile(r"(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), (re.compile(r"(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: codefile_xml = cre.sub(repl, codefile_xml) try: self.CodeFile, error = self.CodeFileParser.LoadXMLString(codefile_xml) if error is not None: (fname, lnum, src) = ((self.CODEFILE_NAME,) + error) self.GetCTRoot().logger.write_warning(XSDSchemaErrorMessage.format(a1=fname, a2=lnum, a3=src)) self.CreateCodeFileBuffer(True) except Exception as exc: msg = _("Couldn't load confnode parameters {a1} :\n {a2}").format(a1=self.CTNName(), a2=str(exc)) self.GetCTRoot().logger.write_error(msg) print(traceback.format_exc()) raise Exception else: self.CodeFile = self.CodeFileParser.CreateRoot() self.CreateCodeFileBuffer(False) self.OnCTNSave() def GetBaseTypes(self): return self.GetCTRoot().GetBaseTypes() def GetDataTypes(self, basetypes=False): return self.GetCTRoot().GetDataTypes(basetypes=basetypes) def GenerateNewName(self, name, format): return self.GetCTRoot().GenerateNewName( None, name, format, exclude=dict([(var.getname().upper(), True) for var in self.CodeFile.variables.getvariable()])) def SetVariables(self, variables): self.CodeFile.variables.setvariable([]) for var in variables: variable = self.CodeFileParser.CreateElement("variable", "variables") variable.setname(var["Name"]) variable.settype(var["Type"]) variable.setinitial(var["Initial"]) variable.setdesc(var["Description"]) variable.setonchange(var["OnChange"]) variable.setopts(var["Options"]) self.CodeFile.variables.appendvariable(variable) def GetVariables(self): datas = [] for var in self.CodeFileVariables(self.CodeFile): datas.append({ "Name": var.getname(), "Type": var.gettype(), "Initial": var.getinitial(), "Description": var.getdesc(), "OnChange": var.getonchange(), "Options": var.getopts(), }) return datas def SetTextParts(self, parts): for section in self.SECTIONS_NAMES: section_code = parts.get(section) if section_code is not None: getattr(self.CodeFile, section).setanyText(section_code) def GetTextParts(self): return dict([(section, getattr(self.CodeFile, section).getanyText()) for section in self.SECTIONS_NAMES]) def CTNTestModified(self): return self.ChangesToSave or not self.CodeFileIsSaved() def OnCTNSave(self, from_project_path=None): filepath = self.CodeFileName() xmlfile = open(filepath, "w", encoding='utf-8') xmlfile.write(etree.tostring( self.CodeFile, pretty_print=True, xml_declaration=True, encoding='utf-8').decode()) xmlfile.close() self.MarkCodeFileAsSaved() return True def CTNGlobalInstances(self): variables = self.CodeFileVariables(self.CodeFile) ret = [(variable.getname(), variable.gettype(), variable.getinitial()) for variable in variables] ret.extend([("On" + variable.getname() + "Change", "python_poll", "") for variable in variables if variable.getonchange()]) return ret def CTNSearch(self, criteria): variables = self.GetVariables() results = [] tagname = self.CTNFullName() for index, var in enumerate(variables): varname = var["Name"] results.extend([((tagname, "var_inout", index, "name"),) + result for result in TestTextElement(varname, criteria)]) results.extend([((tagname, "body"),) + result for result in TestTextElement( GetSectionsText(self, lambda x: ""), criteria)]) return results # ------------------------------------------------------------------------------- # Current Buffering Management Functions # ------------------------------------------------------------------------------- def Copy(self, model): """ Return a copy of the codefile model """ return deepcopy(model) def CreateCodeFileBuffer(self, saved): self.Buffering = False self.CodeFileBuffer = UndoBuffer(self.CodeFileParser.Dumps(self.CodeFile), saved) def BufferCodeFile(self): self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile)) def StartBuffering(self): self.Buffering = True def EndBuffering(self): if self.Buffering: self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile)) self.Buffering = False def MarkCodeFileAsSaved(self): self.EndBuffering() self.CodeFileBuffer.CurrentSaved() def CodeFileIsSaved(self): return self.CodeFileBuffer.IsCurrentSaved() and not self.Buffering def LoadPrevious(self): self.EndBuffering() self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Previous()) def LoadNext(self): self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Next()) def GetBufferState(self): first = self.CodeFileBuffer.IsFirst() and not self.Buffering last = self.CodeFileBuffer.IsLast() return not first, not last
def CreateBuffer(self, saved): self.Buffer = UndoBuffer((EtherCATConfigParser.Dumps( self.Config), ProcessVariablesParser.Dumps(self.ProcessVariables)), saved)
def CreateCodeFileBuffer(self, saved): self.Buffering = False self.CodeFileBuffer = UndoBuffer(self.CodeFileParser.Dumps(self.CodeFile), saved)