lbessard@205: #!/usr/bin/env python lbessard@205: # -*- coding: utf-8 -*- lbessard@205: lbessard@205: #This file is part of CanFestival, a library implementing CanOpen Stack. lbessard@205: # lbessard@205: #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD lbessard@205: # lbessard@205: #See COPYING file for copyrights details. lbessard@205: # lbessard@205: #This library is free software; you can redistribute it and/or lbessard@205: #modify it under the terms of the GNU Lesser General Public lbessard@205: #License as published by the Free Software Foundation; either lbessard@205: #version 2.1 of the License, or (at your option) any later version. lbessard@205: # lbessard@205: #This library is distributed in the hope that it will be useful, lbessard@205: #but WITHOUT ANY WARRANTY; without even the implied warranty of lbessard@205: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU lbessard@205: #Lesser General Public License for more details. lbessard@205: # lbessard@205: #You should have received a copy of the GNU Lesser General Public lbessard@205: #License along with this library; if not, write to the Free Software lbessard@205: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA lbessard@205: lbessard@205: from node import * lbessard@205: import eds_utils lbessard@268: import os, shutil, types lbessard@205: lbessard@205: #------------------------------------------------------------------------------- lbessard@205: # Definition of NodeList Object lbessard@205: #------------------------------------------------------------------------------- lbessard@205: lbessard@205: """ lbessard@205: Class recording a node list for a CANOpen network. lbessard@205: """ lbessard@205: lbessard@205: class NodeList: lbessard@205: lbessard@242: def __init__(self, manager, netname = ""): lbessard@205: self.Root = "" lbessard@205: self.Manager = manager lbessard@242: self.NetworkName = netname lbessard@205: self.SlaveNodes = {} lbessard@205: self.EDSNodes = {} lbessard@205: self.CurrentSelected = None lbessard@242: self.Changed = False lbessard@242: lbessard@242: def HasChanged(self): lbessard@242: return self.Changed or not self.Manager.CurrentIsSaved() lbessard@242: lbessard@242: def ForceChanged(self, changed): lbessard@242: self.Changed = changed lbessard@205: lbessard@205: def GetNetworkName(self): lbessard@205: return self.NetworkName lbessard@205: lbessard@205: def SetNetworkName(self, name): lbessard@205: self.NetworkName = name lbessard@205: lbessard@205: def GetManager(self): lbessard@205: return self.Manager lbessard@205: Laurent@781: def GetEDSFolder(self, root_path=None): Laurent@781: if root_path is None: Laurent@781: root_path = self.Root Laurent@781: return os.path.join(root_path, "eds") Laurent@781: lbessard@205: def GetRoot(self): lbessard@205: return self.Root etisserant@272: etisserant@272: def SetRoot(self, newrootpath): Laurent@781: if os.path.isdir(newrootpath): Laurent@781: self.Root = newrootpath Laurent@781: self.Manager.SetCurrentFilePath(os.path.join(self.Root, "master.od")) Laurent@781: return True Laurent@781: return False lbessard@205: Laurent@748: def GetMasterNodeID(self): Laurent@748: return self.Manager.GetCurrentNodeID() Laurent@748: lbessard@205: def GetSlaveNumber(self): lbessard@205: return len(self.SlaveNodes) lbessard@205: Laurent@740: def GetSlaveName(self, idx): Laurent@740: return self.SlaveNodes[idx]["Name"] Laurent@740: lbessard@205: def GetSlaveNames(self): lbessard@205: nodes = self.SlaveNodes.keys() lbessard@205: nodes.sort() lbessard@205: return ["0x%2.2X %s"%(idx, self.SlaveNodes[idx]["Name"]) for idx in nodes] lbessard@205: lbessard@205: def GetSlaveIDs(self): lbessard@205: nodes = self.SlaveNodes.keys() lbessard@205: nodes.sort() lbessard@205: return nodes lbessard@205: lbessard@205: def SetCurrentSelected(self, selected): lbessard@205: self.CurrentSelected = selected lbessard@205: lbessard@205: def GetCurrentSelected(self): lbessard@205: return self.CurrentSelected lbessard@205: lbessard@242: def LoadProject(self, root, netname = None): lbessard@205: self.SlaveNodes = {} lbessard@205: self.EDSNodes = {} lbessard@205: lbessard@205: self.Root = root lbessard@205: if not os.path.exists(self.Root): laurent@580: return _("\"%s\" folder doesn't exist")%self.Root lbessard@205: Laurent@781: eds_folder = self.GetEDSFolder() Laurent@781: if not os.path.exists(eds_folder): Laurent@781: os.mkdir(eds_folder) lbessard@265: #return "\"%s\" folder doesn't contain a \"eds\" folder"%self.Root lbessard@205: Laurent@781: files = os.listdir(eds_folder) lbessard@205: for file in files: Laurent@781: filepath = os.path.join(eds_folder, file) lbessard@243: if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".eds": lbessard@243: result = self.LoadEDS(file) lbessard@243: if result != None: lbessard@243: return result etisserant@270: lbessard@242: result = self.LoadMasterNode(netname) lbessard@205: if result != None: lbessard@205: return result lbessard@205: lbessard@242: result = self.LoadSlaveNodes(netname) lbessard@205: if result != None: lbessard@205: return result lbessard@242: lbessard@242: self.NetworkName = netname lbessard@242: lbessard@242: def SaveProject(self, netname = None): lbessard@242: result = self.SaveMasterNode(netname) lbessard@205: if result != None: lbessard@205: return result lbessard@205: lbessard@242: result = self.SaveNodeList(netname) lbessard@205: if result != None: lbessard@205: return result lbessard@205: lbessard@505: def ImportEDSFile(self, edspath, force = False): lbessard@205: dir, file = os.path.split(edspath) Laurent@781: eds_folder = self.GetEDSFolder() Laurent@781: eds = os.path.join(eds_folder, file) lbessard@505: if not force and os.path.isfile(eds): Laurent@740: return _("EDS file already imported"), True lbessard@205: else: Laurent@781: shutil.copy(edspath, eds_folder) Laurent@740: return self.LoadEDS(file), False lbessard@205: lbessard@205: def LoadEDS(self, eds): Laurent@781: edspath = os.path.join(self.GetEDSFolder(), eds) lbessard@258: node = eds_utils.GenerateNode(edspath) lbessard@205: if isinstance(node, Node): lbessard@205: self.EDSNodes[eds] = node lbessard@205: return None lbessard@205: else: lbessard@205: return node lbessard@205: lbessard@205: def AddSlaveNode(self, nodeName, nodeID, eds): lbessard@205: if eds in self.EDSNodes.keys(): lbessard@205: slave = {"Name" : nodeName, "EDS" : eds, "Node" : self.EDSNodes[eds]} lbessard@205: self.SlaveNodes[nodeID] = slave lbessard@242: self.Changed = True lbessard@205: return None lbessard@205: else: laurent@580: return _("\"%s\" EDS file is not available")%eds lbessard@205: lbessard@205: def RemoveSlaveNode(self, index): lbessard@205: if index in self.SlaveNodes.keys(): lbessard@205: self.SlaveNodes.pop(index) Laurent@744: self.Changed = True lbessard@205: return None lbessard@205: else: laurent@580: return _("Node with \"0x%2.2X\" ID doesn't exist") lbessard@205: lbessard@242: def LoadMasterNode(self, netname = None): lbessard@242: if netname: lbessard@242: masterpath = os.path.join(self.Root, "%s_master.od"%netname) lbessard@242: else: lbessard@242: masterpath = os.path.join(self.Root, "master.od") lbessard@205: if os.path.isfile(masterpath): lbessard@268: result = self.Manager.OpenFileInCurrent(masterpath) lbessard@268: else: lbessard@268: result = self.Manager.CreateNewNode("MasterNode", 0x00, "master", "", "None", "", "heartbeat", ["DS302"]) lbessard@268: if not isinstance(result, types.IntType): lbessard@268: return result lbessard@268: return None lbessard@205: lbessard@242: def SaveMasterNode(self, netname = None): lbessard@242: if netname: lbessard@242: masterpath = os.path.join(self.Root, "%s_master.od"%netname) lbessard@242: else: lbessard@242: masterpath = os.path.join(self.Root, "master.od") lbessard@205: if self.Manager.SaveCurrentInFile(masterpath): lbessard@205: return None lbessard@205: else: laurent@580: return _("Fail to save Master Node") lbessard@205: lbessard@242: def LoadSlaveNodes(self, netname = None): lbessard@205: cpjpath = os.path.join(self.Root, "nodelist.cpj") lbessard@205: if os.path.isfile(cpjpath): lbessard@205: try: lbessard@205: networks = eds_utils.ParseCPJFile(cpjpath) lbessard@242: network = None lbessard@242: if netname: lbessard@242: for net in networks: lbessard@242: if net["Name"] == netname: lbessard@242: network = net lbessard@242: self.NetworkName = netname lbessard@242: elif len(networks) > 0: lbessard@242: network = networks[0] lbessard@242: self.NetworkName = network["Name"] lbessard@242: if network: lbessard@242: for nodeid, node in network["Nodes"].items(): lbessard@205: if node["Present"] == 1: lbessard@205: result = self.AddSlaveNode(node["Name"], nodeid, node["DCFName"]) lbessard@205: if result != None: lbessard@242: return result lbessard@242: self.Changed = False lbessard@205: except SyntaxError, message: laurent@580: return _("Unable to load CPJ file\n%s")%message lbessard@205: return None lbessard@205: lbessard@242: def SaveNodeList(self, netname = None): lbessard@242: try: lbessard@242: cpjpath = os.path.join(self.Root, "nodelist.cpj") lbessard@242: content = eds_utils.GenerateCPJContent(self) lbessard@242: if netname: lbessard@242: file = open(cpjpath, "a") lbessard@242: else: lbessard@242: file = open(cpjpath, "w") lbessard@242: file.write(content) lbessard@242: file.close() lbessard@242: self.Changed = False lbessard@242: return None lbessard@242: except: laurent@580: return _("Fail to save node list") lbessard@205: lbessard@205: def GetSlaveNodeEntry(self, nodeid, index, subindex = None): lbessard@205: if nodeid in self.SlaveNodes.keys(): lbessard@205: self.SlaveNodes[nodeid]["Node"].SetNodeID(nodeid) lbessard@205: return self.SlaveNodes[nodeid]["Node"].GetEntry(index, subindex) lbessard@205: else: laurent@580: return _("Node 0x%2.2X doesn't exist")%nodeid lbessard@205: lbessard@205: def GetMasterNodeEntry(self, index, subindex = None): lbessard@205: return self.Manager.GetCurrentEntry(index, subindex) lbessard@205: lbessard@205: def SetMasterNodeEntry(self, index, subindex = None, value = None): lbessard@205: self.Manager.SetCurrentEntry(index, subindex, value) lbessard@205: lbessard@205: def GetOrderNumber(self, nodeid): lbessard@205: nodeindexes = self.SlaveNodes.keys() lbessard@205: nodeindexes.sort() lbessard@205: return nodeindexes.index(nodeid) + 1 lbessard@205: lbessard@205: def GetNodeByOrder(self, order): lbessard@205: if order > 0: lbessard@205: nodeindexes = self.SlaveNodes.keys() lbessard@205: nodeindexes.sort() lbessard@205: if order <= len(nodeindexes): lbessard@205: return self.SlaveNodes[nodeindexes[order - 1]]["Node"] lbessard@205: return None lbessard@205: lbessard@205: def IsCurrentEntry(self, index): lbessard@205: if self.CurrentSelected != None: lbessard@205: if self.CurrentSelected == 0: lbessard@205: return self.Manager.IsCurrentEntry(index) lbessard@205: else: lbessard@205: node = self.SlaveNodes[self.CurrentSelected]["Node"] lbessard@205: if node: lbessard@273: node.SetNodeID(self.CurrentSelected) lbessard@205: return node.IsEntry(index) lbessard@205: return False lbessard@205: lbessard@205: def GetEntryInfos(self, index): lbessard@205: if self.CurrentSelected != None: lbessard@205: if self.CurrentSelected == 0: lbessard@205: return self.Manager.GetEntryInfos(index) lbessard@205: else: lbessard@205: node = self.SlaveNodes[self.CurrentSelected]["Node"] lbessard@205: if node: lbessard@273: node.SetNodeID(self.CurrentSelected) lbessard@205: return node.GetEntryInfos(index) lbessard@205: return None lbessard@205: lbessard@242: def GetSubentryInfos(self, index, subindex): lbessard@242: if self.CurrentSelected != None: lbessard@242: if self.CurrentSelected == 0: lbessard@242: return self.Manager.GetSubentryInfos(index, subindex) lbessard@242: else: lbessard@242: node = self.SlaveNodes[self.CurrentSelected]["Node"] lbessard@242: if node: lbessard@273: node.SetNodeID(self.CurrentSelected) lbessard@242: return node.GetSubentryInfos(index, subindex) lbessard@242: return None lbessard@242: lbessard@205: def GetCurrentValidIndexes(self, min, max): lbessard@205: if self.CurrentSelected != None: lbessard@205: if self.CurrentSelected == 0: lbessard@205: return self.Manager.GetCurrentValidIndexes(min, max) lbessard@205: else: lbessard@205: node = self.SlaveNodes[self.CurrentSelected]["Node"] lbessard@205: if node: lbessard@273: node.SetNodeID(self.CurrentSelected) lbessard@205: validindexes = [] lbessard@205: for index in node.GetIndexes(): lbessard@205: if min <= index <= max: lbessard@205: validindexes.append((node.GetEntryName(index), index)) lbessard@205: return validindexes lbessard@205: else: laurent@580: print _("Can't find node") lbessard@205: return [] lbessard@205: lbessard@205: def GetCurrentEntryValues(self, index): lbessard@205: if self.CurrentSelected != None: lbessard@205: node = self.SlaveNodes[self.CurrentSelected]["Node"] lbessard@205: if node: lbessard@273: node.SetNodeID(self.CurrentSelected) lbessard@205: return self.Manager.GetNodeEntryValues(node, index) lbessard@205: else: laurent@580: print _("Can't find node") lbessard@205: return [], [] lbessard@242: lbessard@327: def AddToMasterDCF(self, node_id, index, subindex, size, value): lbessard@327: # Adding DCF entry into Master node lbessard@327: if not self.Manager.IsCurrentEntry(0x1F22): lbessard@337: self.Manager.ManageEntriesOfCurrent([0x1F22], []) lbessard@327: self.Manager.AddSubentriesToCurrent(0x1F22, 127) lbessard@327: lbessard@327: self.Manager.AddToDCF(node_id, index, subindex, size, value) lbessard@327: lbessard@205: if __name__ == "__main__": lbessard@205: from nodemanager import * lbessard@205: import os, sys, shutil lbessard@205: lbessard@205: manager = NodeManager(sys.path[0]) lbessard@242: lbessard@205: nodelist = NodeList(manager) lbessard@242: lbessard@242: result = nodelist.LoadProject("/home/laurent/test_nodelist") lbessard@205: if result != None: lbessard@205: print result lbessard@205: else: lbessard@205: print "MasterNode :" lbessard@205: manager.CurrentNode.Print() lbessard@242: print lbessard@205: for nodeid, node in nodelist.SlaveNodes.items(): lbessard@205: print "SlaveNode name=%s id=0x%2.2X :"%(node["Name"], nodeid) lbessard@205: node["Node"].Print() lbessard@242: print lbessard@242: