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()