plugins/canfestival/canfestival.py
changeset 163 482ca562d414
parent 159 1c5710e8c941
child 166 121b18748de0
equal deleted inserted replaced
162:bf3eac08a96b 163:482ca562d414
     1 import os, sys, wx
     1 import os, sys
     2 base_folder = os.path.split(sys.path[0])[0]
     2 base_folder = os.path.split(sys.path[0])[0]
     3 CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
     3 CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
     4 sys.path.append(os.path.join(CanFestivalPath, "objdictgen"))
     4 sys.path.append(os.path.join(CanFestivalPath, "objdictgen"))
     5 
     5 
     6 from nodelist import NodeList
     6 from nodelist import NodeList
    13 
    13 
    14 from gnosis.xml.pickle import *
    14 from gnosis.xml.pickle import *
    15 from gnosis.xml.pickle.util import setParanoia
    15 from gnosis.xml.pickle.util import setParanoia
    16 setParanoia(0)
    16 setParanoia(0)
    17 
    17 
    18 class _NetworkEdit(networkedit):
    18 #--------------------------------------------------
    19     " Overload some of CanFestival Network Editor methods "
    19 #                    SLAVE
       
    20 #--------------------------------------------------
       
    21 
       
    22 class _NodeEdit(objdictedit):
       
    23     " Overload some of CanFestival Node Editor methods "
    20     def OnCloseFrame(self, event):
    24     def OnCloseFrame(self, event):
    21         " Do reset _NodeListPlug.View when closed"
    25         " Do reset _NodeListPlug.View when closed"
    22         self._onclose()
    26         self._onclose()
    23         event.Skip()
    27         event.Skip()
    24 
    28 
    25 class _NodeListPlug(NodeList):
    29 class _SlavePlug(NodeManager):
    26     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    30     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    27     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    31     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    28       <xsd:element name="CanFestivalNode">
    32       <xsd:element name="CanFestivalNode">
    29         <xsd:complexType>
    33         <xsd:complexType>
    30           <xsd:attribute name="CAN_Device" type="xsd:string" use="required"/>
    34           <xsd:attribute name="CAN_Device" type="xsd:string" use="required"/>
    31           <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="required"/>
    35           <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="required"/>
    32           <xsd:attribute name="NodeId" type="xsd:string" use="required"/>
    36           <xsd:attribute name="NodeId" type="xsd:string" use="required"/>
    33           <xsd:attribute name="Sync_TPDOs" type="xsd:boolean" use="optional" default="true"/>
       
    34         </xsd:complexType>
    37         </xsd:complexType>
    35       </xsd:element>
    38       </xsd:element>
    36     </xsd:schema>
    39     </xsd:schema>
    37     """
    40     """
    38 
    41 
       
    42     def GetSlaveODPath(self):
       
    43         os.path.join(self.PlugPath(), 'slave.od')
       
    44 
    39     def __init__(self):
    45     def __init__(self):
    40         manager = NodeManager()
       
    41         # TODO change netname when name change
    46         # TODO change netname when name change
    42         NodeList.__init__(self, manager, self.BaseParams.getName())
    47         NodeManager.__init__(self)
    43         self.LoadProject(self.PlugPath())
    48         odfilepath = self.GetSlaveODPath()
    44 
    49         if(os.path.isfile(odfilepath)):
       
    50             self.OpenFileInCurrent(odfilepath)
       
    51         else:
       
    52             self.CreateNewNode("SlaveNode",  # Name - will be changed at build time
       
    53                                0x00,         # NodeID - will be changed at build time
       
    54                                "slave",      # Type
       
    55                                "",           # description 
       
    56                                "None",       # profile
       
    57                                "",           # prfile filepath
       
    58                                "heartbeat",  # NMT
       
    59                                [])           # options
       
    60             
    45     _View = None
    61     _View = None
    46     def _OpenView(self, logger):
    62     def _OpenView(self, logger):
    47         if not self._View:
    63         if not self._View:
    48             def _onclose():
    64             def _onclose():
    49                 self._View = None
    65                 self._View = None
    50             def _onsave():
    66             def _onsave():
    51                 self.GetPlugRoot().SaveProject()
    67                 self.GetPlugRoot().SaveProject()
    52             self._View = _NetworkEdit(self.GetPlugRoot().AppFrame, self)
    68             self._View = _NodeEdit(self.GetPlugRoot().AppFrame, self)
    53             # TODO redefine BusId when IEC channel change
    69             # TODO redefine BusId when IEC channel change
    54             self._View.SetBusId(self.GetCurrentLocation())
    70             self._View.SetBusId(self.GetCurrentLocation())
    55             self._View._onclose = _onclose
    71             self._View._onclose = _onclose
    56             self._View._onsave = _onsave
    72             self._View._onsave = _onsave
    57             self._View.Show()
    73             self._View.Show()
   119         file = open(os.path.join(buildpath, "MasterGenerated.od"), "w")
   135         file = open(os.path.join(buildpath, "MasterGenerated.od"), "w")
   120         dump(master, file)
   136         dump(master, file)
   121         file.close()
   137         file.close()
   122         
   138         
   123         return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False
   139         return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False
       
   140 
       
   141 #--------------------------------------------------
       
   142 #                    MASTER
       
   143 #--------------------------------------------------
       
   144 
       
   145 class _NetworkEdit(networkedit):
       
   146     " Overload some of CanFestival Network Editor methods "
       
   147     def OnCloseFrame(self, event):
       
   148         " Do reset _NodeListPlug.View when closed"
       
   149         self._onclose()
       
   150         event.Skip()
       
   151 
       
   152 class _NodeListPlug(NodeList):
       
   153     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
       
   154     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       
   155       <xsd:element name="CanFestivalNode">
       
   156         <xsd:complexType>
       
   157           <xsd:attribute name="CAN_Device" type="xsd:string" use="required"/>
       
   158           <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="required"/>
       
   159           <xsd:attribute name="NodeId" type="xsd:string" use="required"/>
       
   160           <xsd:attribute name="Sync_TPDOs" type="xsd:boolean" use="optional" default="true"/>
       
   161         </xsd:complexType>
       
   162       </xsd:element>
       
   163     </xsd:schema>
       
   164     """
       
   165 
       
   166     def __init__(self):
       
   167         manager = NodeManager()
       
   168         # TODO change netname when name change
       
   169         NodeList.__init__(self, manager, self.BaseParams.getName())
       
   170         self.LoadProject(self.PlugPath())
       
   171 
       
   172     _View = None
       
   173     def _OpenView(self, logger):
       
   174         if not self._View:
       
   175             def _onclose():
       
   176                 self._View = None
       
   177             def _onsave():
       
   178                 self.GetPlugRoot().SaveProject()
       
   179             self._View = _NetworkEdit(self.GetPlugRoot().AppFrame, self)
       
   180             # TODO redefine BusId when IEC channel change
       
   181             self._View.SetBusId(self.GetCurrentLocation())
       
   182             self._View._onclose = _onclose
       
   183             self._View._onsave = _onsave
       
   184             self._View.Show()
       
   185 
       
   186     def _ShowMasterGenerated(self, logger):
       
   187         buildpath = self._getBuildPath()
       
   188         # Eventually create build dir
       
   189         if not os.path.exists(buildpath):
       
   190             logger.write_error("Error: No PLC built\n")
       
   191             return
       
   192         
       
   193         masterpath = os.path.join(buildpath, "MasterGenerated.od")
       
   194         if not os.path.exists(masterpath):
       
   195             logger.write_error("Error: No Master generated\n")
       
   196             return
       
   197         
       
   198         new_dialog = objdictedit(None, [masterpath])
       
   199         new_dialog.Show()
       
   200 
       
   201     PluginMethods = [
       
   202         {"bitmap" : os.path.join("images", "NetworkEdit"),
       
   203          "name" : "Edit network", 
       
   204          "tooltip" : "Edit CanOpen Network with NetworkEdit",
       
   205          "method" : "_OpenView"},
       
   206         {"name" : "Show Master", 
       
   207          "tooltip" : "Show Master generated by config_utils",
       
   208          "method" : "_ShowMasterGenerated"}
       
   209     ]
       
   210 
       
   211     def OnPlugClose(self):
       
   212         if self._View:
       
   213             self._View.Close()
       
   214 
       
   215     def PlugTestModified(self):
       
   216         return self.ChangesToSave or self.HasChanged()
       
   217         
       
   218     def OnPlugSave(self):
       
   219         self.SetRoot(self.PlugPath())
       
   220         self.SaveProject()
       
   221         return True
       
   222 
       
   223     def PlugGenerate_C(self, buildpath, locations, logger):
       
   224         """
       
   225         Generate C code
       
   226         @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
       
   227         @param locations: List of complete variables locations \
       
   228             [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
       
   229             "NAME" : name of the variable (generally "__IW0_1_2" style)
       
   230             "DIR" : direction "Q","I" or "M"
       
   231             "SIZE" : size "X", "B", "W", "D", "L"
       
   232             "LOC" : tuple of interger for IEC location (0,1,2,...)
       
   233             }, ...]
       
   234         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
       
   235         """
       
   236         current_location = self.GetCurrentLocation()
       
   237         # define a unique name for the generated C file
       
   238         prefix = "_".join(map(lambda x:str(x), current_location))
       
   239         Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix )
       
   240         # Create a new copy of the model with DCF loaded with PDO mappings for desired location
       
   241         master, pointers = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix)
       
   242         res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers)
       
   243         if res :
       
   244             raise Exception, res
       
   245         
       
   246         file = open(os.path.join(buildpath, "MasterGenerated.od"), "w")
       
   247         dump(master, file)
       
   248         file.close()
       
   249         
       
   250         return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False
   124     
   251     
   125 class RootClass:
   252 class RootClass:
   126     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   253     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   127     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   254     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   128       <xsd:element name="CanFestivalInstance">
   255       <xsd:element name="CanFestivalInstance">
   131           <xsd:attribute name="Debug_mode" type="xsd:boolean" use="optional" default="false"/>
   258           <xsd:attribute name="Debug_mode" type="xsd:boolean" use="optional" default="false"/>
   132         </xsd:complexType>
   259         </xsd:complexType>
   133       </xsd:element>
   260       </xsd:element>
   134     </xsd:schema>
   261     </xsd:schema>
   135     """
   262     """
   136     PlugChildsTypes = [("CanOpenNode",_NodeListPlug, "CanOpen node")]
   263     PlugChildsTypes = [("CanOpenNode",_NodeListPlug, "CanOpen Master"),("CanOpenSlave",_SlavePlug, "CanOpen Slave")]
   137     def GetParamsAttributes(self, path = None):
   264     def GetParamsAttributes(self, path = None):
   138         infos = PlugTemplate.GetParamsAttributes(self, path = None)
   265         infos = PlugTemplate.GetParamsAttributes(self, path = None)
   139         for element in infos:
   266         for element in infos:
   140             if element["name"] == "CanFestivalInstance":                         
   267             if element["name"] == "CanFestivalInstance":
   141                 for child in element["children"]:
   268                 for child in element["children"]:
   142                     if child["name"] == "CAN_Driver":
   269                     if child["name"] == "CAN_Driver":
   143                         DLL_LIST= getattr(canfestival_config,"DLL_LIST",None)
   270                         DLL_LIST= getattr(canfestival_config,"DLL_LIST",None)
   144                         if DLL_LIST is not None:
   271                         if DLL_LIST is not None:
   145                             child["type"] = DLL_LIST
   272                             child["type"] = DLL_LIST
   176             format_dict["nodes_open"] += 'NODE_OPEN(%s)\n    '%(nodename)
   303             format_dict["nodes_open"] += 'NODE_OPEN(%s)\n    '%(nodename)
   177             format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n    '%(nodename)
   304             format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n    '%(nodename)
   178             format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n    '%(nodename)
   305             format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n    '%(nodename)
   179             format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n    '%(nodename)
   306             format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n    '%(nodename)
   180         
   307         
   181         if wx.Platform == '__WXMSW__':
   308         if sys.platform == 'win32':
   182             if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))):
   309             if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))):
   183                     format_dict["candriver"] += '_DEBUG.dll'
   310                     format_dict["candriver"] += '_DEBUG.dll'
   184             else:
   311             else:
   185                 format_dict["candriver"] += '.dll'
   312                 format_dict["candriver"] += '.dll'
   186         
   313