Exemplo n.º 1
0
class App:
    def __init__(self, master):
        self._master = master
        self._master.title("ArduinoMonitor")
        
        self.refresh_time = 100
        
        self.state_hold = False
        
        self._status = {}
        
        self.info_message = None
        self._serialdevicevar = StringVar()
        self._baudratevar = StringVar()
        self._autoreconnectvar = BooleanVar()
        
        self.serialsettingsframe = Frame(self._master)
        
        Label(self.serialsettingsframe, text='Serial device:').pack(side=LEFT)
        
        self.serialdeviceoptionmenu = OptionMenu(self.serialsettingsframe, self._serialdevicevar, (''))
        self.serialdeviceoptionmenu.pack(side=LEFT)
        self.serialdeviceoptionmenu.bind('<Button-1>', self.reloadserialdevices)
        self._serialdevicevar.trace('w', self.serialdeviceoptionmenu_changed)
        
        Label(self.serialsettingsframe, text='Baudrate:').pack(side=LEFT)
        self.baudratoptionmenu = OptionMenu(self.serialsettingsframe, self._baudratevar, '300', '600', '1200', '2400', '4800', '9600', '14400', '19200', '28800', '38400', '57600', '115200')
        self._baudratevar.trace('w', self.baudratoptionmenu_changed)
        self.baudratoptionmenu.pack(side=LEFT)
        
        self.autoreconnectcheckbox = Checkbutton(master=self.serialsettingsframe, text="Auto reconnect", variable=self._autoreconnectvar, command=self.autoreconnectcheckbox_changed)
        self.autoreconnectcheckbox.select()
        self.autoreconnectcheckbox.pack(side=LEFT)
        
        self.connectbutton = Button(master=self.serialsettingsframe, text='Connect', command=self.connectbutton_clicked)
        self.connectbutton.pack(side=LEFT)
        
        self.controlsframe = Frame(self.serialsettingsframe)
        
        self.holdbutton = Button(master=self.controlsframe, text='Hold', command=self.holdbuttonclicked)
        self.holdbutton.pack(side=LEFT)
        
        self.hidedatabutton = Button(master=self.controlsframe, text='Show Data', command=self.hidedatabuttonclicked)
        self.hidedatabutton.pack(side=LEFT)
        
        self.configbutton = Button(master=self.controlsframe, text='Config Graphs', command=self.configbutton_clicked)
        self.configbutton.pack(side=LEFT)
        
        self.exportbutton = Button(master=self.controlsframe, text='Export', command=self.export_data)
        self.exportbutton.pack(side=LEFT)
        
        self.importbutton = Button(master=self.controlsframe, text='Import', command=self.import_data)
        self.importbutton.pack(side=LEFT)
        
        self.controlsframe.pack(side=RIGHT, fill=X)
        
        self.serialsettingsframe.grid(column=0, row=0, columnspan=2, sticky=NSEW)
        
        self.plotframe = PlotFrame(self._master)
        self.plotframe.grid(row=1, column=0, sticky=NSEW)
        
        self.communicationframe = CommunicationFrame(self._master)
        self.communicationframe.grid(column=1, row=1, sticky=NSEW)
        
        self.serial_communication = SerialCommunication(self._autoreconnectvar.get(), 1)
        self.communicationframe.serial_send = self.serial_communication.send
 
        self._master.columnconfigure(0, weight=8)
        self._master.columnconfigure(1, weight=2)
        self._master.rowconfigure(0, weight=0)
        self._master.rowconfigure(1, weight=1)
        
        
        self.settings = Settings()
        self._serialdevicevar.set(self.settings.get_serial_device())
        self._baudratevar.set(self.settings.get_baud_rate())
        self._autoreconnectvar.set(self.settings.get_auto_reconnect())
        for m in reversed(self.settings.get_history()):
            self.communicationframe.add_to_history(m)

        self.reloadserialdevices()
        
        self.__file_options = {}
        self.__file_options['defaultextension'] = '.aml'
        self.__file_options['filetypes'] = [('ArduinoMonitor-Log', '.aml')]
        self.__file_options['initialdir'] = self.settings.get_last_dir()
        self.__file_options['parent'] = self._master
        
        self.__update()
    
    def finish(self):
        self.settings.set_serial_device(self._serialdevicevar.get())
        self.settings.set_baud_rate(self._baudratevar.get())
        self.settings.set_auto_reconnect(self._autoreconnectvar.get())
        self.settings.set_history(self.communicationframe.get_history())
        self.settings.write()
    
    def export_data(self):
        fileh = tkFileDialog.asksaveasfile(mode='w', title="Export ArduinoMonitor-Log", **self.__file_options)
        
        if not fileh:
            return
        
        self.settings.set_last_dir(os.path.dirname(fileh.name))
        
        for item in self.serial_communication.get_action_handler_log():
            print>>fileh, item
        
        fileh.close()
    
    def import_data(self):
        fileh = tkFileDialog.askopenfile(mode='r', title='Import ArduinoMonitor-Log', **self.__file_options)
        if not fileh:
            return
        
        actions = []
        
        action_handler = ActionHandler()
        
        for l in fileh.readlines():
            actions.append(action_handler.action_from_string(l))
            if actions[-1:][0].name == "LOG":
                actions[-1:][0].message = actions[-1:][0].message[:-2]
        
        self.reset()
        self.show_data(actions)
        
        fileh.close()
    
    def __update(self):
        self.__check_serial_states()
        self.show_data()
        self._master.after(self.refresh_time, self.__update)
    
    def __check_serial_states(self, sender=None, earg=None):
        state = NORMAL
        not_state = DISABLED
        if self.serial_communication.connected:
            state = DISABLED
            not_state = NORMAL
        
        self.connectbutton['text'] = ('Disconnect' if self.serial_communication.connected else 'Connect')
        self.serialdeviceoptionmenu.configure(state=state)
        self.baudratoptionmenu.configure(state=state)
        
        self.importbutton.configure(state=state)
        self.exportbutton.configure(state=state)
        
        self.holdbutton.configure(state=not_state)
        self.hidedatabutton.configure(state=not_state)
        
        self.communicationframe.set_state(not_state)
        
        if len(Graph.graphs.values()) <= 0:
            self.configbutton.configure(state=DISABLED)
        else:
            self.configbutton.configure(state=NORMAL)
        
        mse = self.serial_communication.messaage_sending_failed_with_error
        if mse:
            self.communicationframe.add_text_to_comlog(mse.message, error=True)
        
        if self.serial_communication.error:
            self.info_message = self.serial_communication.error.message
        
        msg = self.serial_communication.sent_message
        if msg:
            self.communicationframe.add_text_to_comlog(msg, out=True)
    
    def configbutton_clicked(self, *args):
        GraphConfigView(self.plotframe.update_graph)
    
    def baudratoptionmenu_changed(self, *args):
        self.serial_communication.baud_rate = self._baudratevar.get()
    
    def autoreconnectcheckbox_changed(self):
        self.serial_communication.auto_reconnect = self._autoreconnectvar.get()
    
    def serialdeviceoptionmenu_changed(self, *args):
        self.serial_communication.serial_device_name = self._serialdevicevar.get()
    
    def serial_send(self, message):
        self.serial_communication.send(message)
    
    def reloadserialdevices(self, sender=None):
        menu = self.serialdeviceoptionmenu['menu']
        menu.delete(0, 'end')
        currententry_available = False
        for sd in self.serial_communication.available_devices:
            if(sd[0] == self._serialdevicevar.get()):
                currententry_available = True
            menu.add_command(label=sd[0], command=lambda value=sd[0]:
                                  self._serialdevicevar.set(value))
        
        
        if not currententry_available:
            self._serialdevicevar.set("")
    
    def connectbutton_clicked(self, value=None):
        if(not self.serial_communication.connected):
            self.serial_communication.connect()
        else:
            self.serial_communication.disconnect()
    
    def hidedatabuttonclicked(self):
        self.serial_communication.log_all_messages = not self.serial_communication.log_all_messages
        self.hidedatabutton['text'] = ('Show Data' if not self.serial_communication.log_all_messages else 'Hide Data')
    
    def holdbuttonclicked(self):
        self.state_hold = not self.state_hold
        self.holdbutton['text'] = ('Start' if self.state_hold else 'Hold')
    
    def reset(self):
        self.communicationframe.clearcomlog()
        self.plotframe.reset()
        self.clear_status()
    
    def show_data(self, actions=None):
        if self.state_hold:
            self.draw()
            return
        
        status = {}
        if not actions:
            actions = self.serial_communication.action_list
        for a in actions:
            if not a:
                continue
            if(a.name == "DRAW"):
                self.update_graph(a)
            elif(a.name == "RESET"):
                self.reset()
            elif(a.name == "INIT_GRAPH"):
                self.init_graph(a)
            elif(a.name == "STATUS"):
                status[a.status_id] = a.message
            elif(a.name == "LOG"):
                self.communicationframe.add_text_to_comlog(a.message)
            elif(a.name == "CLEAR_GRAPH"):
                self.clear_graph(a)
                
        if status:
            self.set_status(status)
        
        if self.serial_communication.connected:
            self.info_message = "Characters in Buffer: " + str(self.serial_communication.in_waiting)
        self.draw()
        
    def clear_graph(self, a):
        graph = Graph.graphs[a.graph_id]
        self.plotframe.clear_graph(graph)
    
    def init_graph(self, a):
        graph = Graph(a.graph_id, a.config_str, a.position)
        self.plotframe.add_graph(graph)
    
    def update_graph(self, a):
        graph_identifier = a.graph_id
        x_value = a.x_value
        y_value = a.y_value
        
        if(not Graph.graphs.has_key(graph_identifier)):
            a = InitGraphAction(graph_identifier, '', "111")
            self.init_graph(a)
        
        graph = Graph.graphs[a.graph_id]
        graph.add_values(x_value, y_value)    
    
    def set_status(self, statDict):
        for k in statDict.keys():
            self._status[k] = statDict[k]
        
        text = ""
        for k in self._status:
            text += k + ': ' + self._status[k] + '\n'
        self.communicationframe.set_status(text)
    
    def clear_status(self):
        self._status = {}
        self.communicationframe.set_status("")
      
    def draw(self):
        self.communicationframe.set_info(self.info_message)
        self.plotframe.update()