]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - objdictgen/nodelist.py
Adding support for replace imported EDS in nodelist
[CanFestival-3.git] / objdictgen / nodelist.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 #This file is part of CanFestival, a library implementing CanOpen Stack. 
5 #
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
7 #
8 #See COPYING file for copyrights details.
9 #
10 #This library is free software; you can redistribute it and/or
11 #modify it under the terms of the GNU Lesser General Public
12 #License as published by the Free Software Foundation; either
13 #version 2.1 of the License, or (at your option) any later version.
14 #
15 #This library is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 #Lesser General Public License for more details.
19 #
20 #You should have received a copy of the GNU Lesser General Public
21 #License along with this library; if not, write to the Free Software
22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24 from node import *
25 import eds_utils
26 import os, shutil, types
27
28 #-------------------------------------------------------------------------------
29 #                          Definition of NodeList Object
30 #-------------------------------------------------------------------------------
31
32 """
33 Class recording a node list for a CANOpen network.
34 """
35
36 class NodeList:
37     
38     def __init__(self, manager, netname = ""):
39         self.Root = ""
40         self.EDSFolder = ""
41         self.Manager = manager
42         self.NetworkName = netname
43         self.SlaveNodes = {}
44         self.EDSNodes = {}
45         self.CurrentSelected = None
46         self.Changed = False
47     
48     def HasChanged(self):
49         return self.Changed or not self.Manager.CurrentIsSaved()
50     
51     def ForceChanged(self, changed):
52         self.Changed = changed
53     
54     def GetNetworkName(self):
55         return self.NetworkName
56     
57     def SetNetworkName(self, name):
58         self.NetworkName = name
59     
60     def GetManager(self):
61         return self.Manager
62     
63     def GetRoot(self):
64         return self.Root
65
66     def SetRoot(self, newrootpath):
67         """
68         Define a new path for the CanOpen network project
69         !!! Does not check if new path is valid !!!
70         """
71         self.Root = newrootpath
72         self.Manager.SetCurrentFilePath(os.path.join(self.Root, "master.od"))
73     
74     def GetSlaveNumber(self):
75         return len(self.SlaveNodes)
76     
77     def GetSlaveNames(self):
78         nodes = self.SlaveNodes.keys()
79         nodes.sort()
80         return ["0x%2.2X %s"%(idx, self.SlaveNodes[idx]["Name"]) for idx in nodes]
81     
82     def GetSlaveIDs(self):
83         nodes = self.SlaveNodes.keys()
84         nodes.sort()
85         return nodes
86         
87     def SetCurrentSelected(self, selected):
88         self.CurrentSelected = selected
89         
90     def GetCurrentSelected(self):
91         return self.CurrentSelected
92             
93     def LoadProject(self, root, netname = None):
94         self.SlaveNodes = {}
95         self.EDSNodes = {}
96         
97         self.Root = root
98         if not os.path.exists(self.Root):
99             return "\"%s\" folder doesn't exist"%self.Root
100         
101         self.EDSFolder = os.path.join(self.Root, "eds")
102         if not os.path.exists(self.EDSFolder):
103             os.mkdir(self.EDSFolder)
104             #return "\"%s\" folder doesn't contain a \"eds\" folder"%self.Root
105         
106         files = os.listdir(self.EDSFolder)
107         for file in files:
108             filepath = os.path.join(self.EDSFolder, file)
109             if os.path.isfile(filepath) and os.path.splitext(filepath)[-1] == ".eds":
110                 result = self.LoadEDS(file)
111                 if result != None:
112                     return result
113                 
114         result = self.LoadMasterNode(netname)
115         if result != None:
116             return result
117             
118         result = self.LoadSlaveNodes(netname)
119         if result != None:
120             return result
121         
122         self.NetworkName = netname
123     
124     def SaveProject(self, netname = None):
125         result = self.SaveMasterNode(netname)
126         if result != None:
127             return result
128             
129         result = self.SaveNodeList(netname)
130         if result != None:
131             return result
132     
133     def ImportEDSFile(self, edspath, force = False):
134         dir, file = os.path.split(edspath)
135         eds = os.path.join(self.EDSFolder, file)
136         if not force and os.path.isfile(eds):
137             return "EDS file already imported"
138         else:
139             shutil.copy(edspath, self.EDSFolder)
140             return self.LoadEDS(file)
141     
142     def LoadEDS(self, eds):
143         edspath = os.path.join(self.EDSFolder, eds)
144         node = eds_utils.GenerateNode(edspath)
145         if isinstance(node, Node):
146             self.EDSNodes[eds] = node
147             return None
148         else:
149             return node
150     
151     def AddSlaveNode(self, nodeName, nodeID, eds):
152         if eds in self.EDSNodes.keys():
153             slave = {"Name" : nodeName, "EDS" : eds, "Node" : self.EDSNodes[eds]}
154             self.SlaveNodes[nodeID] = slave
155             self.Changed = True
156             return None
157         else:
158             return "\"%s\" EDS file is not available"%eds
159     
160     def RemoveSlaveNode(self, index):
161         if index in self.SlaveNodes.keys():
162             self.SlaveNodes.pop(index)
163             return None
164         else:
165             return "Node with \"0x%2.2X\" ID doesn't exist"
166     
167     def LoadMasterNode(self, netname = None):
168         if netname:
169             masterpath = os.path.join(self.Root, "%s_master.od"%netname)
170         else:
171             masterpath = os.path.join(self.Root, "master.od")
172         if os.path.isfile(masterpath):
173             result = self.Manager.OpenFileInCurrent(masterpath)
174         else:
175             result = self.Manager.CreateNewNode("MasterNode", 0x00, "master", "", "None", "", "heartbeat", ["DS302"])
176         if not isinstance(result, types.IntType):
177             return result
178         return None
179     
180     def SaveMasterNode(self, netname = None):
181         if netname:
182             masterpath = os.path.join(self.Root, "%s_master.od"%netname)
183         else:
184             masterpath = os.path.join(self.Root, "master.od")
185         if self.Manager.SaveCurrentInFile(masterpath):
186             return None
187         else:
188             return "Fail to save Master Node"
189     
190     def LoadSlaveNodes(self, netname = None):
191         cpjpath = os.path.join(self.Root, "nodelist.cpj")
192         if os.path.isfile(cpjpath):
193             try:
194                 networks = eds_utils.ParseCPJFile(cpjpath)
195                 network = None
196                 if netname:
197                     for net in networks:
198                         if net["Name"] == netname:
199                             network = net
200                     self.NetworkName = netname
201                 elif len(networks) > 0:
202                     network = networks[0]
203                     self.NetworkName = network["Name"]
204                 if network:
205                     for nodeid, node in network["Nodes"].items():
206                         if node["Present"] == 1:
207                             result = self.AddSlaveNode(node["Name"], nodeid, node["DCFName"])
208                             if result != None:
209                                 return result        
210                 self.Changed = False
211             except SyntaxError, message:
212                 return "Unable to load CPJ file\n%s"%message
213         return None
214     
215     def SaveNodeList(self, netname = None):
216         try:
217             cpjpath = os.path.join(self.Root, "nodelist.cpj")
218             content = eds_utils.GenerateCPJContent(self)
219             if netname:
220                 file = open(cpjpath, "a")
221             else:
222                 file = open(cpjpath, "w")
223             file.write(content)
224             file.close()
225             self.Changed = False
226             return None
227         except:
228             return "Fail to save node list"
229     
230     def GetSlaveNodeEntry(self, nodeid, index, subindex = None):
231         if nodeid in self.SlaveNodes.keys():
232             self.SlaveNodes[nodeid]["Node"].SetNodeID(nodeid)
233             return self.SlaveNodes[nodeid]["Node"].GetEntry(index, subindex)
234         else:
235             return "Node 0x%2.2X doesn't exist"%nodeid
236
237     def GetMasterNodeEntry(self, index, subindex = None):
238         return self.Manager.GetCurrentEntry(index, subindex)
239         
240     def SetMasterNodeEntry(self, index, subindex = None, value = None):
241         self.Manager.SetCurrentEntry(index, subindex, value)
242     
243     def GetOrderNumber(self, nodeid):
244         nodeindexes = self.SlaveNodes.keys()
245         nodeindexes.sort()
246         return nodeindexes.index(nodeid) + 1
247     
248     def GetNodeByOrder(self, order):
249         if order > 0:
250             nodeindexes = self.SlaveNodes.keys()
251             nodeindexes.sort()
252             if order <= len(nodeindexes):
253                 return self.SlaveNodes[nodeindexes[order - 1]]["Node"]
254         return None
255     
256     def IsCurrentEntry(self, index):
257         if self.CurrentSelected != None:
258             if self.CurrentSelected == 0:
259                 return self.Manager.IsCurrentEntry(index)
260             else:
261                 node = self.SlaveNodes[self.CurrentSelected]["Node"]
262                 if node:
263                     node.SetNodeID(self.CurrentSelected)
264                     return node.IsEntry(index)
265         return False
266     
267     def GetEntryInfos(self, index):
268         if self.CurrentSelected != None:
269             if self.CurrentSelected == 0:
270                 return self.Manager.GetEntryInfos(index)
271             else:
272                 node = self.SlaveNodes[self.CurrentSelected]["Node"]
273                 if node:
274                     node.SetNodeID(self.CurrentSelected)
275                     return node.GetEntryInfos(index)
276         return None
277
278     def GetSubentryInfos(self, index, subindex):
279         if self.CurrentSelected != None:
280             if self.CurrentSelected == 0:
281                 return self.Manager.GetSubentryInfos(index, subindex)
282             else:
283                 node = self.SlaveNodes[self.CurrentSelected]["Node"]
284                 if node:
285                     node.SetNodeID(self.CurrentSelected)
286                     return node.GetSubentryInfos(index, subindex)
287         return None
288
289     def GetCurrentValidIndexes(self, min, max):
290         if self.CurrentSelected != None:
291             if self.CurrentSelected == 0:
292                 return self.Manager.GetCurrentValidIndexes(min, max)
293             else:
294                 node = self.SlaveNodes[self.CurrentSelected]["Node"]
295                 if node:
296                     node.SetNodeID(self.CurrentSelected)
297                     validindexes = []
298                     for index in node.GetIndexes():
299                         if min <= index <= max:
300                             validindexes.append((node.GetEntryName(index), index))
301                     return validindexes
302                 else:
303                     print "Can't find node"
304         return []
305     
306     def GetCurrentEntryValues(self, index):
307         if self.CurrentSelected != None:
308             node = self.SlaveNodes[self.CurrentSelected]["Node"]
309             if node:
310                 node.SetNodeID(self.CurrentSelected)
311                 return self.Manager.GetNodeEntryValues(node, index)
312             else:
313                 print "Can't find node"
314         return [], []
315     
316     def AddToMasterDCF(self, node_id, index, subindex, size, value):
317         # Adding DCF entry into Master node
318         if not self.Manager.IsCurrentEntry(0x1F22):
319             self.Manager.ManageEntriesOfCurrent([0x1F22], [])
320         self.Manager.AddSubentriesToCurrent(0x1F22, 127)
321
322         self.Manager.AddToDCF(node_id, index, subindex, size, value)
323     
324 if __name__ == "__main__":
325     from nodemanager import *
326     import os, sys, shutil
327     
328     manager = NodeManager(sys.path[0])
329     
330     nodelist = NodeList(manager)
331     
332     result = nodelist.LoadProject("/home/laurent/test_nodelist")
333     if result != None:
334         print result
335     else:
336         print "MasterNode :"
337         manager.CurrentNode.Print()
338         print 
339         for nodeid, node in nodelist.SlaveNodes.items():
340             print "SlaveNode name=%s id=0x%2.2X :"%(node["Name"], nodeid)
341             node["Node"].Print()
342             print
343