From 936284e50b7510183d22cf96d3a3f3ade35847be Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 20 Aug 2015 21:55:54 +0200 Subject: [PATCH 01/37] further code cleanup --- ArdumowerDK.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index b2ff160..43987cf 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -51,13 +51,13 @@ def donothing(): button = tk.Button(filewin, text="Do nothing button") button.pack() -## self.lastCommand = [] -## for i in range(100): -## self.lastCommand.append(".") + self.lastCommand = [] + for i in range(100): + self.lastCommand.append(".") ##---------------Menu-------------------------------------------- menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff = 0) -## filemenu.add_command(label="New", command=donothing) + filemenu.add_command(label="New", command=donothing) ## filemenu.add_command(label="Open", command=donothing) ## filemenu.add_command(label="Save", command=donothing) ## filemenu.add_command(label="Save as...", command=donothing) @@ -255,16 +255,22 @@ def update_plots(self, tdata1=[], data=[], channel=0,dnumber=0, *args): return True def sendLeft(self,event): + self.mainmenu() self.send("nl") def sendRight(self,event): + self.mainmenu() self.send("nr") def sendUp(self,event): + self.mainmenu() self.send("nf") def sendDown(self,event): + self.mainmenu() self.send("ns") def sendB(self,event): + self.mainmenu() self.send("nb") def sendF1(self,event): + self.mainmenu() self.send("nm") def sendPrior(self,event): pass @@ -624,23 +630,22 @@ def openDebug(): self.gui_Debug.lift() self.gui_Debug.focus_set() - def hide_Inout(): + def hide_Debug(): self.gui_Debug.withdraw() master.deiconify() self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug) self.gui_Debug = GuiDebug(master, self.received_queueDebug, self.send_queue) - self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Inout) + self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) + # Set up the thread to do asynchronous I/O # More can be made if necessary self.running = False self.threadI = threading.Thread(target=self.initThread) self.master.after(1000,self.threadI.start) self.threadR = threading.Thread(target=self.receiveThread) -## self.thread2.start() self.threadS = threading.Thread(target=self.sendThread) -## self.thread3.start() - self.threadIN = threading.Thread(target=self.gui.processIncoming) + # Start the periodic call in the GUI to check if the queue contains # anything self.master.after(1000,self.periodicCall) From d17ed44842ee8643f0a122e9d1a75a3a616f9dc3 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 20 Aug 2015 21:57:06 +0200 Subject: [PATCH 02/37] serial enumeration code found - not yet implemented https://github.com/djs/serialenum --- serialenum.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 serialenum.py diff --git a/serialenum.py b/serialenum.py new file mode 100644 index 0000000..ca91027 --- /dev/null +++ b/serialenum.py @@ -0,0 +1,54 @@ +from glob import glob +import os +import os.path +from serial import Serial +import sys + + +def enumerate(): +## print "enu" + ports = [] + + if sys.platform == 'win32': + # Iterate through registry because WMI does not show virtual serial ports +## print "win" + import _winreg + + try: + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'HARDWARE\DEVICEMAP\SERIALCOMM') + except WindowsError: + return [] + i = 0 + while True: + try: + ports.append(_winreg.EnumValue(key, i)[1]) + i = i + 1 + except WindowsError: + break + elif sys.platform == 'linux2': + if os.path.exists('/dev/serial/by-id'): + entries = os.listdir('/dev/serial/by-id') + dirs = [os.readlink(os.path.join('/dev/serial/by-id', x)) + for x in entries] + ports.extend([os.path.normpath(os.path.join('/dev/serial/by-id', x)) + for x in dirs]) + + for dev in glob('/dev/ttyS*'): + try: + port = Serial(dev) + except: + pass + else: + ports.append(dev) + + else: + return [] + + return ports + +def script(): + for port in enumerate(): + print "Ports: ", port + +if __name__ == "__main__": + script() \ No newline at end of file From e8f55fee5487cd89283947c5323fdbb5794a660c Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 20 Aug 2015 22:11:32 +0200 Subject: [PATCH 03/37] added acknowledgments --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c46ec73..3f15704 100644 --- a/README.md +++ b/README.md @@ -32,4 +32,14 @@ Bluetooth Serial Communication to Ardumower #Debug Window (View/Debug) ',' or '|' or '{' or '}' should not be used in the debug strings - since these characters are used for filtering normal communication (commands/plot data) \ No newline at end of file + since these characters are used for filtering normal communication (commands/plot data) + +thanks go to: +http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/ +for the io_threading recipe +and +https://github.com/djs/serialenum +for a multiplatform serial enumeration possibility + +and Sebastian Held and Frederic Goddeeris and the all the active developpers of the Ardumower Project +http://ardumower.de \ No newline at end of file From 9bf1c957da1cb91942101673919be98603daae6c Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 20 Aug 2015 22:25:11 +0200 Subject: [PATCH 04/37] more acknowledgments --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f15704..11ca6f4 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,12 @@ for the io_threading recipe and https://github.com/djs/serialenum for a multiplatform serial enumeration possibility +and +http://www.daniweb.com/forums/post202523-3.html vegaseat for the ringbuffer +and +'''Michael Lange +for the statusbar -and Sebastian Held and Frederic Goddeeris and the all the active developpers of the Ardumower Project +and +Sebastian Held and Frederic Goddeeris and the all the active developpers of the Ardumower Project http://ardumower.de \ No newline at end of file From ef70dcf9eacbb5cb64c66f15dee88e61bbc13ad0 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 20 Aug 2015 22:32:02 +0200 Subject: [PATCH 05/37] ok --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 11ca6f4..fa7f7b6 100644 --- a/README.md +++ b/README.md @@ -33,18 +33,26 @@ Bluetooth Serial Communication to Ardumower #Debug Window (View/Debug) ',' or '|' or '{' or '}' should not be used in the debug strings since these characters are used for filtering normal communication (commands/plot data) + + + thanks go to: +Jacob Hallén http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/ for the io_threading recipe and +Dan Savilonis https://github.com/djs/serialenum for a multiplatform serial enumeration possibility and -http://www.daniweb.com/forums/post202523-3.html vegaseat for the ringbuffer +vegaseat +http://www.daniweb.com/forums/post202523-3.html +for the ringbuffer and -'''Michael Lange -for the statusbar +Michael Lange +http://tkinter.unpythonic.net/wiki/ProgressMeter +for the statusbar / class meter and Sebastian Held and Frederic Goddeeris and the all the active developpers of the Ardumower Project From 126cf04371dcf17ff995647b32eece6fc9a503de Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 20 Aug 2015 22:46:31 +0200 Subject: [PATCH 06/37] so long --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fa7f7b6..d7c5d81 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,10 @@ Bluetooth Serial Communication to Ardumower ',' or '|' or '{' or '}' should not be used in the debug strings since these characters are used for filtering normal communication (commands/plot data) - - +#use at your own risk + + thanks go to: Jacob Hallén http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/ @@ -56,4 +57,6 @@ for the statusbar / class meter and Sebastian Held and Frederic Goddeeris and the all the active developpers of the Ardumower Project -http://ardumower.de \ No newline at end of file +http://ardumower.de + +and as always: thanks for all the fish \ No newline at end of file From af3d62a11d0235e0c760e5dd41a438525b244442 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Fri, 21 Aug 2015 14:03:50 +0200 Subject: [PATCH 07/37] plotting bug corrected bug in update_plot --- ArdumowerDK.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 43987cf..08ae3b9 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -239,9 +239,9 @@ def update_plots(self, tdata1=[], data=[], channel=0,dnumber=0, *args): self.ax[channel].set_ylim(self.lo[dnumber], self.hi[dnumber]) self.master.after_idle(self.ax[channel].figure.canvas.draw) - for i in range(len(self.plotnumbers)): + for i in range(self.canvasnumber): self.master.after_idle(self.ax[i].draw_artist,self.lines[i]) - for i in range(len(self.plotnumbers)): + for i in range(self.canvasnumber): self.master.after_idle(self.canvas[i].blit,self.ax[i].bbox) From 47569ddac98a5889f889452966b9dffabc822311 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Fri, 21 Aug 2015 14:04:20 +0200 Subject: [PATCH 08/37] new --- Ringbuffer.pyc | Bin 1593 -> 1413 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Ringbuffer.pyc b/Ringbuffer.pyc index f9d20ddb618e95dbc2f9e30e78cac8495f4bec5e..9d9aa21045b4c06394f90b5b0143d8e6af574a2b 100644 GIT binary patch delta 103 zcmdnV)5^`k{F#?aC^f`;BgZpFHW>y626wB;hOE+)b(y*lT&c-lnbsh<(vu%BcO$q` SlUK5&Ah^pAOsUDDY$^cZ{}#*u delta 283 zcmZqW-pRwk{F#?4O^Z2jBgZpF6)Oe?24}07(Bjmh;ux2r#Ps~U7?=Fy(%jU%lHwTm w%o2~%q{;J{q$cw*brY-j7_kbaCbu&85UW^vvJp!%v5KW8Z)G9D Date: Mon, 24 Aug 2015 23:27:30 +0200 Subject: [PATCH 09/37] comport enumeration implemented --- ArdumowerDK.py | 171 +++++++++++++++++++++++++++++++++++++++---------- serialenum.py | 3 + serialenum.pyc | Bin 0 -> 1472 bytes 3 files changed, 140 insertions(+), 34 deletions(-) create mode 100644 serialenum.pyc diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 08ae3b9..9f213c6 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -42,9 +42,10 @@ from matplotlib.lines import Line2D from matplotlib.ticker import MultipleLocator, FormatStrFormatter import platform +import serialenum class GuiPart: - def __init__(self, master, receivedQueue, sendQueue, endCommand, Debug): + def __init__(self, master, receivedQueue, sendQueue, endCommand, Debug, Com): self.master = master def donothing(): filewin = tk.Toplevel(master) @@ -83,7 +84,7 @@ def donothing(): viewmenu = tk.Menu(menubar, tearoff=0) viewmenu.add_command(label="Debug", command=Debug) -## viewmenu.add_command(label="", command=donothing) + viewmenu.add_command(label="Connect", command=Com) ## viewmenu.add_command(label="", command=donothing) ## viewmenu.add_command(label="", command=donothing) menubar.add_cascade(label="View", menu=viewmenu) @@ -150,7 +151,7 @@ def donothing(): self.scale[i].grid_remove() # -----------------------------------Plot--------------------------- - self.canvasnumber =6 + self.canvasnumber =5 self.plot = False self.channel = 0 self.f = Figure() @@ -184,7 +185,7 @@ def donothing(): self.ax.append(self.f.add_subplot(11+i+(self.canvasnumber*100))) self.lines.append(Line2D(self.tdata, self.data, animated=True)) self.ax[i].add_line(self.lines[i]) - self.ax[i].set_ylim(-10, 255) + self.ax[i].set_ylim(-10.1, 255.0) self.ax[i].set_xlim(1, 300) self.ax[i].set_xlabel(self.plotxlabels[i]) self.ax[i].set_ylabel(self.plotylabels[i]) @@ -320,7 +321,7 @@ def setplot(self,buttonpressed): for lo in self.lo: lo = 0.0 for hi in self.hi: - hi = -1 + hi = -1.0 self.plotnumbers.sort() ## print self.plotnumbers @@ -519,7 +520,7 @@ def processIncoming(self): self.titles=[] self.c.get_tk_widget().grid() - self.toolbar.grid + self.toolbar.grid() self.plot = True self.maincommand_list = [] self.maincomName_list = [] @@ -604,6 +605,57 @@ def send_debug_command(): self.autoscroll_checkbutton.grid(column = 3, row = 7) self.withdraw() +class GuiConnect(tk.Toplevel): + def __init__(self, master,initQueue): + tk.Toplevel.__init__(self) + self.initQueue = initQueue + self.master = master + self.title("Connection") + self.geometry('+300+10') + self.connection_entry_var=tk.StringVar() + self.connection_entry = tk.Entry(self, textvariable = self.connection_entry_var) + self.connection_entry.grid(column = 3, row =4) + self.options_var=tk.StringVar() + self.connection_options = serialenum.enumerate() +## self.connection_options.append("Network") + self.connection_options.append("") + self.options_var.set(self.connection_options[-1]) + self.options = apply(tk.OptionMenu,(self,self.options_var)+tuple(self.connection_options)) + self.options.grid(column = 3, row = 5) + self.___entry_in_var=tk.StringVar() + self.___entry_in = tk.Entry(self, textvariable = self.___entry_in_var) +## self.___entry_in.grid(column = 3, row =5, sticky="nesw") +## self.___text = tk.Text(self,width=100, height = 20) +## self.___entry_var.set("") +## self.___text_scrollbar = tk.Scrollbar(self) +## self.___text.config(yscrollcommand=self.debug_text_scrollbar.set) +## self.___text_scrollbar.config(command=self.debug_text.yview) +## self.___text.grid(row=6,column=3,sticky="nesw") +## self.___text_scrollbar.grid(row=6,column=3,sticky="nesw") + def connect_command(): + def IPadress(): + filewin = tk.Toplevel(master) + button = tk.Button(filewin, text="Do nothing button") + button.pack() + + if self.options_var.get() != "": self.connection_entry_var.set(str(self.options_var.get())) + if self.autodetect_checkbutton_var.get() == 1: autodetect = True + else: autodetect = False + com_device = self.connection_entry_var.get() + print com_device + msg = autodetect,com_device + if self.options_var.get() == "Network": + IPadress() + else: + self.initQueue.put(msg) + self.connectbutton = tk.Button(self, text='Connect', command= connect_command) + self.connectbutton.grid(column = 3, row =4, sticky = "e") + self.autodetect_checkbutton_var = tk.IntVar() + self.autodetect_checkbutton_var.set(1) + self.autodetect_checkbutton = tk.Checkbutton(self, text = "Autodetect", variable = self.autodetect_checkbutton_var) + if (platform.system() == 'Windows'):self.autodetect_checkbutton.grid(column = 3, row = 7) +## self.withdraw() + class ThreadedClient: """ @@ -624,6 +676,7 @@ def __init__(self, master): self.received_queue = Queue.Queue() self.received_queueDebug = Queue.Queue() self.send_queue = Queue.Queue() + self.init_Queue = Queue.Queue() # Set up the GUI part def openDebug(): self.gui_Debug.deiconify() @@ -634,10 +687,20 @@ def hide_Debug(): self.gui_Debug.withdraw() master.deiconify() - self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug) + def openCom(): + self.gui_com.deiconify() + self.gui_com.lift() + self.gui_com.focus_set() + + def hide_Com(): + self.gui_com.withdraw() + master.deiconify() + + self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug, openCom) self.gui_Debug = GuiDebug(master, self.received_queueDebug, self.send_queue) self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) - + self.gui_com = GuiConnect(master, self.init_Queue) + self.gui_com.protocol("WM_DELETE_WINDOW", hide_Com) # Set up the thread to do asynchronous I/O # More can be made if necessary self.running = False @@ -649,6 +712,8 @@ def hide_Debug(): # Start the periodic call in the GUI to check if the queue contains # anything self.master.after(1000,self.periodicCall) + self.init_com = True + def periodicCall(self): """ @@ -681,14 +746,13 @@ def initThread(self): One important thing to remember is that the thread has to yield control. """ - def scan_comport(com_exclude = None): com_device = None comport = "1" while com_device == None and int(comport) <= 50: if comport not in com_exclude: try: - com_device = serial.Serial("com" + comport, baudrate=115200, writeTimeout = 100) + com_device = serial.Serial("com" + comport, baudrate=19200, writeTimeout = 100000) print "Testing com:",comport except: if int(comport) <= 49: @@ -706,34 +770,72 @@ def scan_comport(com_exclude = None): return com_device, comport - print "init" +## print "init" com_device = "" com = "" com_exclude = [] + while self.init_com: - while com_device != None and self.running == False: - com_device, com = scan_comport(com_exclude) -## time.sleep(0.1) - if com_device != None: - com_device.write("{.}") - time.sleep(0.5) - while com_device.inWaiting() != 0 and self.running == False: - muC = com_device.readline() -## print muC - if muC.find("Ardumower") >= 0: - print"found Ardumower" - self.Ardumower = com_device - msg = muC + "init" - self.received_queue.put(msg) - msg = "" - self.running = True - - self.threadR.start() - self.threadS.start() - com_exclude.append(com) - if not self.running: - self.threadR.start() - self.threadS.start() + + if self.init_Queue.qsize(): + try: + # Check contents of message and do what it says + # + msg = self.init_Queue.get(0) +## print msg + autodetect, com = msg +## if self.running: +## com_device.close() + + if autodetect and (platform.system() == 'Windows'): + while com_device != None and self.running == False: + com_device, com = scan_comport(com_exclude) + ## time.sleep(0.1) + if com_device != None: + com_device.write("{.}") + time.sleep(0.5) + while com_device.inWaiting() != 0 and self.running == False: + muC = com_device.readline() + ## print muC + if muC.find("Ardumower") >= 0: + print"found Ardumower" + self.Ardumower = com_device + msg = muC + "init" + print msg + self.received_queue.put(msg) + msg = "" + self.running = True + + self.threadR.start() + self.threadS.start() + self.gui_com.connectbutton.configure(state = tk.DISABLED) + com_exclude.append(com) + elif com != "": + com_device = serial.Serial(com, baudrate=19200, writeTimeout = 10000) + if com_device != None: + com_device.write("{.}") + time.sleep(0.5) + while com_device.inWaiting() != 0 and self.running == False: + muC = com_device.readline() + ## print muC + if muC.find("Ardumower") >= 0: + print"found Ardumower" + self.Ardumower = com_device + msg = muC + "init" + self.received_queue.put(msg) + msg = "" + self.running = True + + self.threadR.start() + self.threadS.start() + self.gui_com.connectbutton.configure(state = tk.DISABLED) +## else: print "Failed to connect to Device" + + except Queue.Empty: + pass +## if not self.running: +## self.threadR.start() +## self.threadS.start() def receiveThread(self): """ @@ -829,6 +931,7 @@ def sendThread(self): def endApplication(self): + self.init_com = False if self.running: if tkMessageBox.askokcancel("Quit", "Do you really wish to quit?"): self.running = False diff --git a/serialenum.py b/serialenum.py index ca91027..95f44f8 100644 --- a/serialenum.py +++ b/serialenum.py @@ -5,6 +5,7 @@ import sys + def enumerate(): ## print "enu" ports = [] @@ -25,6 +26,7 @@ def enumerate(): i = i + 1 except WindowsError: break + return ports elif sys.platform == 'linux2': if os.path.exists('/dev/serial/by-id'): entries = os.listdir('/dev/serial/by-id') @@ -40,6 +42,7 @@ def enumerate(): pass else: ports.append(dev) + return ports else: return [] diff --git a/serialenum.pyc b/serialenum.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99c41ae09f4d514e61e0dad428547ed0efffcb3e GIT binary patch literal 1472 zcmb7EO>f&q5S=Bd&&u&f0t7Caq6G?6Xb>An+e;b*5hTKPZOaB#M2g{*V8X3SnIdKG zs+Iuhm0*qe8k$ahWb1 zDpJxFxnSX|8DK%Is0>(hb%f>StTz*%DpWspyhY3YmHXFkiSd{g!N*ir;DW znC3`b5pb2}4$TFRy0&i=DR?j+0@A-4+@<@C)16{rfYC>S-iqH+fnSuZ(XdX#4=9Ed ziV9y=8Y_36)x&3P=l2q@`M+pKo*Y+ZE}OUkd^2< z$-aCljWv(p?ze(YzZLlB9skuq+dpodp7;FVpmo$fIX+GhK#BC98=fZFWct)>!rYDZ zPrF7A!0y}GlO#6v+f{34y)T;g;aV4ynHgKf|2U284|y@N6*wVS6#7E!ld;YY^$cZ! z&7uD~JUVH&j>6+sd;g&8+Xj~VNfzhV#xIJzkdydbG0`{*M9~=N7_A`kv&raHl;Qzj zoZLv@II=%Vpq?hi8rd*~6(@zTDs&X1tV;{7tK7zIP?7UUPlTm)Hi_YQsQelnC zcE&TQl5Jf?R&&Yb1*4s^v+gz=S8b~`RZ?YDQ?7cX?!l`mPpzvh3|H;I``Wn=YXie` zHkIdkj$B`6&7#Tm{S?OZL%zE=gk!hP7a3Q059era|Ef-X+~Ho6!@GuidCDq0`$XOg z0UxQQ#nrq|aV(>GS0rQm6 Date: Wed, 26 Aug 2015 23:15:23 +0200 Subject: [PATCH 10/37] disconnect and rescan added to connection gui --- ArdumowerDK.py | 236 +++++++++++++++++++++++++++++++------------------ 1 file changed, 148 insertions(+), 88 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 9f213c6..3713fe0 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -613,17 +613,22 @@ def __init__(self, master,initQueue): self.title("Connection") self.geometry('+300+10') self.connection_entry_var=tk.StringVar() - self.connection_entry = tk.Entry(self, textvariable = self.connection_entry_var) + self.connection_entry = tk.Entry(self, textvariable = self.connection_entry_var, width = 50) self.connection_entry.grid(column = 3, row =4) self.options_var=tk.StringVar() - self.connection_options = serialenum.enumerate() + self.connection_options = [] + def scan(): + self.connection_options = [] + self.connection_options = serialenum.enumerate() ## self.connection_options.append("Network") - self.connection_options.append("") - self.options_var.set(self.connection_options[-1]) + self.connection_options.append("") + self.options_var.set(self.connection_options[-1]) + + scan() self.options = apply(tk.OptionMenu,(self,self.options_var)+tuple(self.connection_options)) - self.options.grid(column = 3, row = 5) - self.___entry_in_var=tk.StringVar() - self.___entry_in = tk.Entry(self, textvariable = self.___entry_in_var) + self.options.grid(column = 3, row = 5, sticky = "w") +## self.___entry_in_var=tk.StringVar() +## self.___entry_in = tk.Entry(self, textvariable = self.___entry_in_var) ## self.___entry_in.grid(column = 3, row =5, sticky="nesw") ## self.___text = tk.Text(self,width=100, height = 20) ## self.___entry_var.set("") @@ -642,14 +647,24 @@ def IPadress(): if self.autodetect_checkbutton_var.get() == 1: autodetect = True else: autodetect = False com_device = self.connection_entry_var.get() - print com_device +## print com_device msg = autodetect,com_device if self.options_var.get() == "Network": IPadress() else: self.initQueue.put(msg) + + def disconnect_command(): + msg = True, "disconnect" + self.initQueue.put(msg) + + + self.scanbutton = tk.Button(self, text='Rescan', command = scan) + self.scanbutton.grid(column = 3, row = 5, sticky = "e") self.connectbutton = tk.Button(self, text='Connect', command= connect_command) - self.connectbutton.grid(column = 3, row =4, sticky = "e") + self.connectbutton.grid(column = 3, row =4, sticky = "w") + self.disconnectbutton = tk.Button(self, text='Disconnect', command= disconnect_command, state = tk.DISABLED) + self.disconnectbutton.grid(column = 3, row =4, sticky = "e") self.autodetect_checkbutton_var = tk.IntVar() self.autodetect_checkbutton_var.set(1) self.autodetect_checkbutton = tk.Checkbutton(self, text = "Autodetect", variable = self.autodetect_checkbutton_var) @@ -677,6 +692,7 @@ def __init__(self, master): self.received_queueDebug = Queue.Queue() self.send_queue = Queue.Queue() self.init_Queue = Queue.Queue() + self.receive_connected_queue = Queue.Queue() # Set up the GUI part def openDebug(): self.gui_Debug.deiconify() @@ -703,16 +719,21 @@ def hide_Com(): self.gui_com.protocol("WM_DELETE_WINDOW", hide_Com) # Set up the thread to do asynchronous I/O # More can be made if necessary - self.running = False + self.running = True + self.connected = False + self.init_com = True self.threadI = threading.Thread(target=self.initThread) self.master.after(1000,self.threadI.start) self.threadR = threading.Thread(target=self.receiveThread) self.threadS = threading.Thread(target=self.sendThread) + self.threadR.start() + self.threadS.start() + # Start the periodic call in the GUI to check if the queue contains # anything self.master.after(1000,self.periodicCall) - self.init_com = True + def periodicCall(self): @@ -746,34 +767,36 @@ def initThread(self): One important thing to remember is that the thread has to yield control. """ - def scan_comport(com_exclude = None): - com_device = None - comport = "1" - while com_device == None and int(comport) <= 50: + def scan_comport(com_exclude): + com_device = "" + comport = 1 + while com_device == "" and comport <= 50: if comport not in com_exclude: try: - com_device = serial.Serial("com" + comport, baudrate=19200, writeTimeout = 100000) + com_device = serial.Serial("com" + str(comport), baudrate=19200, writeTimeout = 100000) print "Testing com:",comport except: if int(comport) <= 49: - comport = str(int(comport) + 1) -## print comport + comport += 1 + print comport else: - com_device = None + com_device = "" print "Failed to connect to Device" connected = False -## print comport + print comport comport ="51" else: - comport = str(int(comport) + 1) + comport += 1 print "Testing com:",comport +## comport =1 return com_device, comport ## print "init" com_device = "" - com = "" + com = 0 com_exclude = [] + connected = False while self.init_com: @@ -782,53 +805,73 @@ def scan_comport(com_exclude = None): # Check contents of message and do what it says # msg = self.init_Queue.get(0) -## print msg - autodetect, com = msg -## if self.running: -## com_device.close() - - if autodetect and (platform.system() == 'Windows'): - while com_device != None and self.running == False: + print msg + autodetect, msg = msg + + if (msg == "disconnect") and autodetect: + self.receive_connected_queue.put("disconnected") + self.gui_com.connectbutton.configure(state = tk.NORMAL) + self.gui_com.disconnectbutton.configure(state = tk.DISABLED) + connected = False + try: + self.Ardumower.close() + except: + print "port cannot close" + + + elif autodetect and (platform.system() == 'Windows'): + print "autodetect" + while com_device == "" and connected == False and com <=49: com_device, com = scan_comport(com_exclude) + print com_device, com ## time.sleep(0.1) - if com_device != None: + if com_device != "": com_device.write("{.}") time.sleep(0.5) - while com_device.inWaiting() != 0 and self.running == False: + while com_device.inWaiting() != 0 and connected == False: muC = com_device.readline() - ## print muC + print "muC",muC if muC.find("Ardumower") >= 0: print"found Ardumower" self.Ardumower = com_device - msg = muC + "init" - print msg - self.received_queue.put(msg) + ms = muC + "init" + print ms + self.received_queue.put(ms) + self.receive_connected_queue.put("connected") + self.send_queue.put("connected") msg = "" - self.running = True - - self.threadR.start() - self.threadS.start() + autodetect = False + com_exclude = [] + com = 0 self.gui_com.connectbutton.configure(state = tk.DISABLED) + self.gui_com.disconnectbutton.configure(state = tk.NORMAL) + connected = True + com_device = "" com_exclude.append(com) - elif com != "": - com_device = serial.Serial(com, baudrate=19200, writeTimeout = 10000) - if com_device != None: + print com_exclude, self.connected + print "com_device", com_device + + elif msg != "": + com_device = serial.Serial(msg, baudrate=19200, writeTimeout = 10000) + if com_device != "": + print com_device com_device.write("{.}") time.sleep(0.5) - while com_device.inWaiting() != 0 and self.running == False: + while com_device.inWaiting() != 0 and self.connected == False: muC = com_device.readline() - ## print muC + print muC if muC.find("Ardumower") >= 0: print"found Ardumower" self.Ardumower = com_device - msg = muC + "init" - self.received_queue.put(msg) + ms = muC + "init" + print ms + self.receive_connected_queue.put("connected") + self.send_queue.put("connected") + self.received_queue.put(ms) msg = "" - self.running = True - - self.threadR.start() - self.threadS.start() self.gui_com.connectbutton.configure(state = tk.DISABLED) + self.gui_com.disconnectbutton.configure(state = tk.NORMAL) + self.connected = True ## else: print "Failed to connect to Device" except Queue.Empty: @@ -845,14 +888,26 @@ def receiveThread(self): control. """ msg = "" - if self.running: Mower = self.Ardumower + connected = False while self.running: # To simulate asynchronous I/O, we create a random number at # random intervals. Replace the following 2 lines with the real # thing. - if Mower.inWaiting() != 0: + if self.receive_connected_queue.qsize(): + try: + # Check contents of message and do what it says + # + msg = self.receive_connected_queue.get(0) + if msg == "connected": + connected = True + mower = self.Ardumower + elif msg == "disconnected": connected = False + except Queue.Empty: + pass + + if connected and mower.inWaiting() != 0: - msg += Mower.readline() + msg += mower.readline() if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): @@ -870,37 +925,38 @@ def receiveThread(self): if self.running == False: - msg = "{.Ardumower (Ardumower)|r~Commands|n~Manual|s~Settings|in~Info|c~Test compass|m1~Log sensors|yp~Plot|y4~Error counters|y9~ADC calibration}init" - self.received_queue.put(msg) -## msg = "{.Commands`5000|ro~OFF|ra~Auto mode|rc~RC mode|rm~Mowing is OFF|rp~Pattern is RAND|rh~Home|rk~Track|rs~State is OFF |rr~Auto rotate is 0.00|r1~User switch 1 is OFF|r2~User switch 2 is OFF|r3~User switch 3 is OFF}" -#### msg = "|nl~Left|nr~Right|nf~Forward|nb~Reverse|nm~Mow is OFF}" -#### msg = "{.Mow`1000|o00~Overload Counter 0|o01~Power in Watt 0.00|o11~current in mA 0.00|o02~Power max `1000`1000`0~ ~0.1|o03~calibrate mow motor `0`3000`0~ ~1|o04~Speed 0.00|o05~Speed max `255`255`0~ ~1|o06~Modulate NO|o07~RPM 0|o08~RPM set `3300`4500`0~ ~1|o09p~RPM_P `0`100`0~ ~0.01|o09i~RPM_I `1`100`0~ ~0.01|o09d~RPM_D `1`100`0~ ~0.01|o10~Testing is OFF|o04~for config file: motorMowSenseScale:15.30}" - time.sleep(5) - msg = "{.Plot|y7~Sensors|y5~Sensor counters|y3~IMU|y6~Perimeter|y8~GPS|y1~Battery|y2~Odometry2D|y11~Motor control|y10~GPS2D}" - self.received_queue.put(msg) - msg ="{=Sensors`300|time s`0|state`1|motL`2|motR`3|motM`4|sonL`5|sonC`6|sonR`7|peri`8|lawn`9|rain`10|dropL`11|dropR`12}" - time.sleep(5) - self.received_queue.put(msg) - for i in range(1000): - time.sleep(0.5) - if i%2 == 0 : - msg = str(i)+",12,2,0.02,0.10,100,2507,5,1,3,27,25000,0" -## print "data:", msg - if i%2 != 0: - msg = "Debug string " + str(i) -## print "dbug:", msg - - if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): - self.received_queueDebug.put(msg) - msg = "" - elif not msg.find("{")>= 0: - self.received_queue.put(msg) -## print msg - msg = "" - elif msg.find("}")>= 0: - self.received_queue.put(msg) -## print msg - msg = "" + pass +## msg = "{.Ardumower (Ardumower)|r~Commands|n~Manual|s~Settings|in~Info|c~Test compass|m1~Log sensors|yp~Plot|y4~Error counters|y9~ADC calibration}init" +## self.received_queue.put(msg) +#### msg = "{.Commands`5000|ro~OFF|ra~Auto mode|rc~RC mode|rm~Mowing is OFF|rp~Pattern is RAND|rh~Home|rk~Track|rs~State is OFF |rr~Auto rotate is 0.00|r1~User switch 1 is OFF|r2~User switch 2 is OFF|r3~User switch 3 is OFF}" +###### msg = "|nl~Left|nr~Right|nf~Forward|nb~Reverse|nm~Mow is OFF}" +###### msg = "{.Mow`1000|o00~Overload Counter 0|o01~Power in Watt 0.00|o11~current in mA 0.00|o02~Power max `1000`1000`0~ ~0.1|o03~calibrate mow motor `0`3000`0~ ~1|o04~Speed 0.00|o05~Speed max `255`255`0~ ~1|o06~Modulate NO|o07~RPM 0|o08~RPM set `3300`4500`0~ ~1|o09p~RPM_P `0`100`0~ ~0.01|o09i~RPM_I `1`100`0~ ~0.01|o09d~RPM_D `1`100`0~ ~0.01|o10~Testing is OFF|o04~for config file: motorMowSenseScale:15.30}" +## time.sleep(5) +## msg = "{.Plot|y7~Sensors|y5~Sensor counters|y3~IMU|y6~Perimeter|y8~GPS|y1~Battery|y2~Odometry2D|y11~Motor control|y10~GPS2D}" +## self.received_queue.put(msg) +## msg ="{=Sensors`300|time s`0|state`1|motL`2|motR`3|motM`4|sonL`5|sonC`6|sonR`7|peri`8|lawn`9|rain`10|dropL`11|dropR`12}" +## time.sleep(5) +## self.received_queue.put(msg) +## for i in range(1000): +## time.sleep(0.5) +## if i%2 == 0 : +## msg = str(i)+",12,2,0.02,0.10,100,2507,5,1,3,27,25000,0" +#### print "data:", msg +## if i%2 != 0: +## msg = "Debug string " + str(i) +#### print "dbug:", msg +## +## if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): +## self.received_queueDebug.put(msg) +## msg = "" +## elif not msg.find("{")>= 0: +## self.received_queue.put(msg) +#### print msg +## msg = "" +## elif msg.find("}")>= 0: +## self.received_queue.put(msg) +#### print msg +## msg = "" def sendThread(self): """ @@ -909,14 +965,18 @@ def sendThread(self): One important thing to remember is that the thread has to yield control. """ - if self.running: Mower = self.Ardumower + connected = False while self.running: - if self.send_queue.qsize(): + if self.send_queue.qsize(): try: # Check contents of message and do what it says # msg = self.send_queue.get(0) - Mower.write("{" + msg + "}" + "\n") + if msg == "connected": + connected = True + mower = self.Ardumower + elif msg == "disconnected": connected = False + elif connected: mower.write("{" + msg + "}" + "\n") except Queue.Empty: pass ## while self.running == False: @@ -942,7 +1002,7 @@ def endApplication(self): self.master.destroy() def close_com(self): - self.Ardumower.close() + if self.gui_com.connectbutton.cget("state") == tk.DISABLED: self.Ardumower.close() rand = random.Random() root = tk.Tk() From 932f6b8af6e9728aeb743ff7a93094313d6fc3a7 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Wed, 26 Aug 2015 23:32:27 +0200 Subject: [PATCH 11/37] connection gui bug fix --- ArdumowerDK.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 3713fe0..491fc4c 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -614,7 +614,7 @@ def __init__(self, master,initQueue): self.geometry('+300+10') self.connection_entry_var=tk.StringVar() self.connection_entry = tk.Entry(self, textvariable = self.connection_entry_var, width = 50) - self.connection_entry.grid(column = 3, row =4) + self.connection_entry.grid(column = 3, row =0) self.options_var=tk.StringVar() self.connection_options = [] def scan(): @@ -623,10 +623,10 @@ def scan(): ## self.connection_options.append("Network") self.connection_options.append("") self.options_var.set(self.connection_options[-1]) + self.options = apply(tk.OptionMenu,(self,self.options_var)+tuple(self.connection_options)) + self.options.grid(column = 3, row = 5, sticky = "w") scan() - self.options = apply(tk.OptionMenu,(self,self.options_var)+tuple(self.connection_options)) - self.options.grid(column = 3, row = 5, sticky = "w") ## self.___entry_in_var=tk.StringVar() ## self.___entry_in = tk.Entry(self, textvariable = self.___entry_in_var) ## self.___entry_in.grid(column = 3, row =5, sticky="nesw") @@ -643,7 +643,7 @@ def IPadress(): button = tk.Button(filewin, text="Do nothing button") button.pack() - if self.options_var.get() != "": self.connection_entry_var.set(str(self.options_var.get())) + self.connection_entry_var.set(str(self.options_var.get())) if self.autodetect_checkbutton_var.get() == 1: autodetect = True else: autodetect = False com_device = self.connection_entry_var.get() From d830f2602f70b8bb9a84146156159a1a6490ebfc Mon Sep 17 00:00:00 2001 From: Holoratte Date: Wed, 26 Aug 2015 23:41:10 +0200 Subject: [PATCH 12/37] bug fix initThread --- ArdumowerDK.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 491fc4c..dc6e5ce 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -871,7 +871,7 @@ def scan_comport(com_exclude): msg = "" self.gui_com.connectbutton.configure(state = tk.DISABLED) self.gui_com.disconnectbutton.configure(state = tk.NORMAL) - self.connected = True + connected = True ## else: print "Failed to connect to Device" except Queue.Empty: From 085a721ef6b55fa52057a40a894808dfad58d991 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 27 Aug 2015 21:59:39 +0200 Subject: [PATCH 13/37] more stable connection manager init_thread --- ArdumowerDK.py | 116 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 41 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index dc6e5ce..6d2ad3e 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------- # Name: Ardumower DK -# Purpose: Communication Ardumower - Windows computer via Bluetooth +# Purpose: Communication Ardumower - Windows computer via Bluetooth serial por # # Author: Holoratte # -# Created: 19.08.2015 +# Created: 27.08.2015 # Copyright: (c) Holoratte 2015 # Licence: Just use it. Selling this software might be prohibited. -# +# Version: 14 #------------------------------------------------------------------------------- """ @@ -47,15 +47,18 @@ class GuiPart: def __init__(self, master, receivedQueue, sendQueue, endCommand, Debug, Com): self.master = master + self.lastCommand = [] + for i in range(100): + self.lastCommand.append(".") + + # Set up the GUI + + #---------------Menu-------------------------------------------- def donothing(): filewin = tk.Toplevel(master) button = tk.Button(filewin, text="Do nothing button") button.pack() - self.lastCommand = [] - for i in range(100): - self.lastCommand.append(".") - ##---------------Menu-------------------------------------------- menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff = 0) filemenu.add_command(label="New", command=donothing) @@ -102,13 +105,11 @@ def donothing(): master.config(menu=menubar) - #---------------------Menu End---------------------------------------------------------- + #--------------------Buttons and scalebars---------------------------------------------- self.RQueue = receivedQueue self.SQueue = sendQueue - # Set up the GUI - self.console1 = tk.Button(master, text='Main', command= self.mainmenu) self.console1.grid(column = 0, row =0) self.console1.grid_remove() @@ -164,10 +165,12 @@ def donothing(): self.data = [0] self.lo = [] self.hi = [] + for i in range(50): self.lo.append(0.0) self.hi.append(0.0) self.plotnames.append("value") + self.canvas = [] self.backgrounds = [] self.c=FigureCanvasTkAgg(self.f, master=master) @@ -177,8 +180,8 @@ def donothing(): self.toolbar.grid(column=10, row=30, sticky="w") self.toolbar.update() self.canvas = [] - for i in range(self.canvasnumber): + for i in range(self.canvasnumber): self.backgrounds.append(None) self.plotxlabels.append("Time") self.plotylabels.append(self.plotnames[i]) @@ -191,8 +194,10 @@ def donothing(): self.ax[i].set_ylabel(self.plotylabels[i]) self.ax[i].yaxis.set_major_formatter(FormatStrFormatter('%d')) self.canvas.append(self.ax[i].figure.canvas) + self.c.mpl_connect('draw_event',self.update_background) self.f.subplots_adjust(hspace=0.1) + for a in self.f.axes[:-1]: a.set_xlabel("") a.set_xticks([]) @@ -208,7 +213,9 @@ def donothing(): self.idle_flag = True self.idle1_flag = True + # Add more GUI stuff here + master.bind('', self.sendoff) master.bind('', self.sendLeft) master.bind('', self.sendRight) @@ -606,7 +613,7 @@ def send_debug_command(): self.withdraw() class GuiConnect(tk.Toplevel): - def __init__(self, master,initQueue): + def __init__(self, master,initQueue, close_com): tk.Toplevel.__init__(self) self.initQueue = initQueue self.master = master @@ -643,7 +650,7 @@ def IPadress(): button = tk.Button(filewin, text="Do nothing button") button.pack() - self.connection_entry_var.set(str(self.options_var.get())) + if self.options_var.get() != "": self.connection_entry_var.set(str(self.options_var.get())) if self.autodetect_checkbutton_var.get() == 1: autodetect = True else: autodetect = False com_device = self.connection_entry_var.get() @@ -654,16 +661,14 @@ def IPadress(): else: self.initQueue.put(msg) - def disconnect_command(): - msg = True, "disconnect" - self.initQueue.put(msg) + self.scanbutton = tk.Button(self, text='Rescan', command = scan) self.scanbutton.grid(column = 3, row = 5, sticky = "e") self.connectbutton = tk.Button(self, text='Connect', command= connect_command) self.connectbutton.grid(column = 3, row =4, sticky = "w") - self.disconnectbutton = tk.Button(self, text='Disconnect', command= disconnect_command, state = tk.DISABLED) + self.disconnectbutton = tk.Button(self, text='Disconnect', command= close_com, state = tk.DISABLED) self.disconnectbutton.grid(column = 3, row =4, sticky = "e") self.autodetect_checkbutton_var = tk.IntVar() self.autodetect_checkbutton_var.set(1) @@ -693,6 +698,7 @@ def __init__(self, master): self.send_queue = Queue.Queue() self.init_Queue = Queue.Queue() self.receive_connected_queue = Queue.Queue() + self.connected_queue = Queue.Queue() # Set up the GUI part def openDebug(): self.gui_Debug.deiconify() @@ -715,7 +721,7 @@ def hide_Com(): self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug, openCom) self.gui_Debug = GuiDebug(master, self.received_queueDebug, self.send_queue) self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) - self.gui_com = GuiConnect(master, self.init_Queue) + self.gui_com = GuiConnect(master, self.init_Queue, self.close_com) self.gui_com.protocol("WM_DELETE_WINDOW", hide_Com) # Set up the thread to do asynchronous I/O # More can be made if necessary @@ -759,7 +765,24 @@ def processIncoming(self): self.gui_Debug.debug_text.see(tk.END) except Queue.Empty: pass - + while self.connected_queue.qsize(): + try: + msg = self.connected_queue.get() + if msg == "connected": + self.gui_com.connectbutton.configure(state = tk.DISABLED) + self.gui_com.disconnectbutton.configure(state = tk.NORMAL) + self.connected = True + self.master.title("ArdumowerDK " + msg) + elif msg == "disconnected": + self.gui_com.connectbutton.configure(state = tk.NORMAL) + self.gui_com.disconnectbutton.configure(state = tk.DISABLED) + self.connected = False + self.master.title("ArdumowerDK " + msg) + else: + self.gui_com.connection_entry_var.set(msg) + self.master.title("ArdumowerDK Connected: " + msg) + except Queue.Empty: + pass def initThread(self): """ This is where we handle the asynchronous I/O. For example, it may be @@ -810,8 +833,7 @@ def scan_comport(com_exclude): if (msg == "disconnect") and autodetect: self.receive_connected_queue.put("disconnected") - self.gui_com.connectbutton.configure(state = tk.NORMAL) - self.gui_com.disconnectbutton.configure(state = tk.DISABLED) + self.connected_queue.put("disconnected") connected = False try: self.Ardumower.close() @@ -842,13 +864,15 @@ def scan_comport(com_exclude): msg = "" autodetect = False com_exclude = [] + + self.connected_queue.put("connected") + com = "com" + str(com) + self.connected_queue.put(com) com = 0 - self.gui_com.connectbutton.configure(state = tk.DISABLED) - self.gui_com.disconnectbutton.configure(state = tk.NORMAL) connected = True com_device = "" com_exclude.append(com) - print com_exclude, self.connected + print com_exclude, connected print "com_device", com_device elif msg != "": @@ -857,7 +881,7 @@ def scan_comport(com_exclude): print com_device com_device.write("{.}") time.sleep(0.5) - while com_device.inWaiting() != 0 and self.connected == False: + while com_device.inWaiting() != 0 and connected == False: muC = com_device.readline() print muC if muC.find("Ardumower") >= 0: @@ -869,8 +893,7 @@ def scan_comport(com_exclude): self.send_queue.put("connected") self.received_queue.put(ms) msg = "" - self.gui_com.connectbutton.configure(state = tk.DISABLED) - self.gui_com.disconnectbutton.configure(state = tk.NORMAL) + self.connected_queue.put("connected") connected = True ## else: print "Failed to connect to Device" @@ -906,22 +929,26 @@ def receiveThread(self): pass if connected and mower.inWaiting() != 0: + try: - msg += mower.readline() + msg += mower.readline() - if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): - self.received_queueDebug.put(msg) - msg = "" - elif not msg.find("{")>= 0: - self.received_queue.put(msg) -## print msg - msg = "" + if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): + self.received_queueDebug.put(msg) + msg = "" + elif not msg.find("{")>= 0: + self.received_queue.put(msg) + ## print msg + msg = "" - elif msg.find("}")>= 0: - self.received_queue.put(msg) -## print msg - msg = "" + elif msg.find("}")>= 0: + self.received_queue.put(msg) + ## print msg + msg = "" + except SerialException: + self.connected_queue.put("disconnected") + pass if self.running == False: @@ -991,18 +1018,25 @@ def sendThread(self): def endApplication(self): - self.init_com = False + if self.running: if tkMessageBox.askokcancel("Quit", "Do you really wish to quit?"): self.running = False + self.init_com = False self.master.after(100, self.close_com) self.master.after(1000, self.master.destroy) + ## self.master.after(1000, sys.exit) else: self.master.destroy() def close_com(self): - if self.gui_com.connectbutton.cget("state") == tk.DISABLED: self.Ardumower.close() + if self.connected: + autodetect = True + ms = "disconnect" + msg = autodetect, ms + if self.init_com: self.init_Queue.put(msg) + else: self.Ardumower.close() rand = random.Random() root = tk.Tk() From 29eaa7e8d7762edf5534f203dea7886b5c200fd8 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 27 Aug 2015 22:25:52 +0200 Subject: [PATCH 14/37] serial exception handler --- ArdumowerDK.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 6d2ad3e..ce9fa2c 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -946,7 +946,7 @@ def receiveThread(self): self.received_queue.put(msg) ## print msg msg = "" - except SerialException: + except serial.SerialException: self.connected_queue.put("disconnected") pass @@ -1003,7 +1003,12 @@ def sendThread(self): connected = True mower = self.Ardumower elif msg == "disconnected": connected = False - elif connected: mower.write("{" + msg + "}" + "\n") + elif connected: + try: + mower.write("{" + msg + "}" + "\n") + except serial.SerialException: + self.connected_queue.put("disconnected") + pass except Queue.Empty: pass ## while self.running == False: From 43d47418550e7c48495793e42461225d4aa49019 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Thu, 27 Aug 2015 23:09:16 +0200 Subject: [PATCH 15/37] code cleanup --- ArdumowerDK.py | 56 ++++++++++---------------------------------------- 1 file changed, 11 insertions(+), 45 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index ce9fa2c..d88a1c6 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -257,7 +257,7 @@ def update_plots(self, tdata1=[], data=[], channel=0,dnumber=0, *args): else: self.ax[channel].draw_artist(self.lines[channel]) self.canvas[channel].blit(self.ax[channel].bbox) -## print time.time() - t0, "seconds" + self.toolbar.update() self.idle1_flag = True return True @@ -303,7 +303,7 @@ def send(self, command, value = None): else: command += "`" + str(value) self.SQueue.put(command) -## print "send", command + def mainmenu(self): self.plot = False @@ -324,14 +324,13 @@ def setplot(self,buttonpressed): else: self.plotnumbers.remove(buttonpressed) self.nav_buttons[buttonpressed].configure(relief = tk.RAISED) - ## print self.plotnumbers + for lo in self.lo: lo = 0.0 for hi in self.hi: hi = -1.0 self.plotnumbers.sort() - ## print self.plotnumbers self.idle_flag = False for i in range(self.canvasnumber): if len(self.plotnumbers)>= (i+1): @@ -367,14 +366,12 @@ def processIncoming(self): try: msg = self.RQueue.get(0) # Check contents of message and do what it says - # As a test, we simply print it if msg.find("init") >= 0: msg.strip("init") init = True msg = msg.strip("init") -## print init, "incomming" -## print msg + msg = msg.strip("\n") msg = msg.strip("\r") @@ -402,16 +399,13 @@ def processIncoming(self): ## if init: self.titles = [] -## print msg_list self.maincommand_list=[] self.maincomName_list = [] self.c.get_tk_widget().grid_remove() ## self.toolbar.grid_remove() for i in range(len(msg_list)-1): coma, comName = msg_list[i+1].split("~") - ## print coma self.maincommand_list.append(coma) - ## print self.command_list self.maincomName_list.append(comName) self.main_buttons[i].grid() self.main_buttons[i].configure(text=self.maincomName_list[i], command= lambda i=i: self.send(self.maincommand_list[i])) @@ -420,16 +414,12 @@ def processIncoming(self): ## self.console1.grid() elif self.plot: -## print data_list if len(msg_list)>=2: -## print msg_list - if msg_list[0].find("`")>=0: title,self.datasize = msg_list[0].split("`") if msg_list[1].find("`")>=0: for i in range(len(msg_list)-1): msg_list[i+1], num = msg_list[i+1].split("`") - print num for name in self.plotnames: name = "value" self.idle_flag = False @@ -445,17 +435,14 @@ def processIncoming(self): self.plotnumbers = [0] for i in range(len(self.main_buttons)): self.main_buttons[i].configure(relief = tk.RAISED) -## print msg_list -## print self.titles + for tiltle in self.titles: ti = tiltle if msg_list[0].find(ti) >= 0: tiltlenumber = self.titles.index(tiltle) self.main_buttons[tiltlenumber].configure(relief = tk.RIDGE) if msg_list[1].find("time")>=0: - msg_list = msg_list[1:] - print msg_list self.timeSent = True else: self.timeSent = False for i in range(len(msg_list)-1): @@ -475,13 +462,11 @@ def processIncoming(self): if i in self.plotnumbers: self.plotnumbers.remove(i) self.nav_buttons[i].configure(text=msg_list[i+1], relief = tk.RAISED,command=lambda i= i:self.setplot(i)) self.plotnames[i] = msg_list[i+1] -## print self.plotnames self.idle_flag = True elif len(data_list)>=1: -## print data_list t0 = time.time() if self.timeSent: data_list = data_list[1:] @@ -491,14 +476,12 @@ def processIncoming(self): try: if self.idle_flag and self.idle1_flag: self.idle1_flag = False -## print"number of data: ", self.datanumber tdata1 = [] if len(self.plotnumbers) >=1: for i in range(len(self.data_list[self.plotnumbers[0]])): tdata1.append(i) for i in range(self.canvasnumber): if len(self.plotnumbers)>= (i+1): - ## print len(self.plotnumbers), i self.channel = i ## if (len(self.data_list)-1) >= len(self.data_list[self.plotnumbers[i]]): @@ -535,14 +518,10 @@ def processIncoming(self): self.main_buttons[d].configure(relief = tk.RAISED) for i in range(len(msg_list)-1): coma, comName = msg_list[i+1].split("~") - ## print coma self.maincommand_list.append(coma) - ## print comName self.maincomName_list.append(comName) - self.main_buttons[i].configure(text=self.maincomName_list[i], command= lambda i=i: self.send(self.maincommand_list[i])) self.main_buttons[i].grid() - self.titles.append(comName) self.console1.grid() else: @@ -550,7 +529,7 @@ def processIncoming(self): for i in range(len(self.main_buttons)): self.main_buttons[i].configure(relief = tk.RAISED) self.main_buttons[tiltlenumber].configure(relief = tk.RIDGE) - ## print msg_list[0], tiltle + if not self.plot: for i in range(len(msg_list)-1): self.scaleActiv_list.append(False) @@ -560,9 +539,8 @@ def processIncoming(self): self.scaleActiv_list[i] = True else:coma, comName = msg_list[i+1].split("~") - ## print coma + self.command_list.append(coma) - ## print self.command_list self.comName_list.append(comName) self.multiplier_list.append(0.0) self.minimum_list.append(0) @@ -579,7 +557,7 @@ def processIncoming(self): self.scale[i].grid() self.scaleVar[i].set(self.ist_list[i]) self.nav_buttons[i].configure(text=comName, command= lambda i=i: self.send(self.command_list[i], self.scaleVar[i].get()/self.multiplier_list[i])) - ## print "scale ", i + except Queue.Empty: pass @@ -654,7 +632,6 @@ def IPadress(): if self.autodetect_checkbutton_var.get() == 1: autodetect = True else: autodetect = False com_device = self.connection_entry_var.get() -## print com_device msg = autodetect,com_device if self.options_var.get() == "Network": IPadress() @@ -801,12 +778,12 @@ def scan_comport(com_exclude): except: if int(comport) <= 49: comport += 1 - print comport +## print comport else: com_device = "" print "Failed to connect to Device" connected = False - print comport +## print comport comport ="51" else: comport += 1 @@ -828,7 +805,6 @@ def scan_comport(com_exclude): # Check contents of message and do what it says # msg = self.init_Queue.get(0) - print msg autodetect, msg = msg if (msg == "disconnect") and autodetect: @@ -842,22 +818,18 @@ def scan_comport(com_exclude): elif autodetect and (platform.system() == 'Windows'): - print "autodetect" while com_device == "" and connected == False and com <=49: com_device, com = scan_comport(com_exclude) - print com_device, com ## time.sleep(0.1) if com_device != "": com_device.write("{.}") time.sleep(0.5) while com_device.inWaiting() != 0 and connected == False: muC = com_device.readline() - print "muC",muC if muC.find("Ardumower") >= 0: print"found Ardumower" self.Ardumower = com_device ms = muC + "init" - print ms self.received_queue.put(ms) self.receive_connected_queue.put("connected") self.send_queue.put("connected") @@ -872,23 +844,19 @@ def scan_comport(com_exclude): connected = True com_device = "" com_exclude.append(com) - print com_exclude, connected - print "com_device", com_device + elif msg != "": com_device = serial.Serial(msg, baudrate=19200, writeTimeout = 10000) if com_device != "": - print com_device com_device.write("{.}") time.sleep(0.5) while com_device.inWaiting() != 0 and connected == False: muC = com_device.readline() - print muC if muC.find("Ardumower") >= 0: print"found Ardumower" self.Ardumower = com_device ms = muC + "init" - print ms self.receive_connected_queue.put("connected") self.send_queue.put("connected") self.received_queue.put(ms) @@ -939,12 +907,10 @@ def receiveThread(self): msg = "" elif not msg.find("{")>= 0: self.received_queue.put(msg) - ## print msg msg = "" elif msg.find("}")>= 0: self.received_queue.put(msg) - ## print msg msg = "" except serial.SerialException: self.connected_queue.put("disconnected") From c2d598e437fe9ebb0c3807a50939438a1c60a96b Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sat, 29 Aug 2015 20:21:31 +0200 Subject: [PATCH 16/37] Optimized CPU load added time.sleep(0.01) for each thread --- ArdumowerDK.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index d88a1c6..28b62aa 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -771,6 +771,7 @@ def scan_comport(com_exclude): com_device = "" comport = 1 while com_device == "" and comport <= 50: + if comport not in com_exclude: try: com_device = serial.Serial("com" + str(comport), baudrate=19200, writeTimeout = 100000) @@ -798,7 +799,7 @@ def scan_comport(com_exclude): com_exclude = [] connected = False while self.init_com: - + time.sleep(0.01) if self.init_Queue.qsize(): try: @@ -881,6 +882,7 @@ def receiveThread(self): msg = "" connected = False while self.running: + time.sleep(0.01) # To simulate asynchronous I/O, we create a random number at # random intervals. Replace the following 2 lines with the real # thing. @@ -960,6 +962,7 @@ def sendThread(self): """ connected = False while self.running: + time.sleep(0.01) if self.send_queue.qsize(): try: # Check contents of message and do what it says From 4d8ad3e3db011e4502c51673bee244b0beb2b624 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sun, 30 Aug 2015 11:20:39 +0200 Subject: [PATCH 17/37] change --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 96374c4..d6f5fa0 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,9 @@ $RECYCLE.BIN/ Network Trash Folder Temporary Items .apdisk + +# ========================= +# Python +# ========================= +.pyc +.pyo \ No newline at end of file From 901d4ffbc9ca7401b5aa3cd807f32c4609e2fe85 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sun, 30 Aug 2015 11:25:43 +0200 Subject: [PATCH 18/37] change --- .gitignore | 4 ++-- Ringbuffer.pyc | Bin 1413 -> 0 bytes serialenum.pyc | Bin 1472 -> 0 bytes 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 Ringbuffer.pyc delete mode 100644 serialenum.pyc diff --git a/.gitignore b/.gitignore index d6f5fa0..6e62547 100644 --- a/.gitignore +++ b/.gitignore @@ -45,5 +45,5 @@ Temporary Items # ========================= # Python # ========================= -.pyc -.pyo \ No newline at end of file +*.pyc +*.pyo \ No newline at end of file diff --git a/Ringbuffer.pyc b/Ringbuffer.pyc deleted file mode 100644 index 9d9aa21045b4c06394f90b5b0143d8e6af574a2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1413 zcmbVM-)q!B5T4EDa=qG0RqR74WgjDog7_dJqP0+=P%sMOQ3)}b^wQ?XHM?hP>0AAe z{R8xyO?rJ$kh4wd1fs3fWsO%$ojBUY3v z$_Dg<=#uF31V;nPd^+~1{YKf4CO$C^eY(V@A)P%T4k!y`yYpp>CL`h@9W4=$k;)bdk6(T7kHm?_k<#wzM5w}my@<$R=P&CF;!W!;n+8>_R#CfYW- zN{(5#O;fpBdDA+lnok!_r&F%ADb86JMz@@#Q_h@o>LJ;cyp`-5P?qRO(FM2#H5bl` zQ3HVysc=6WKt~X=!cZI+bz$S!`q)U8P$G6aF7rsdLrAC0Cam2T2XESJUNxuO?(7{1 zm0ul|k7wT_xxET85|7lXTA-9j4&@e%1xg^i^Z*p7J?WwPE7Aa0lG%*w%#L7!%#w5K zphl9&;VmpzH-Kty;bJ~7%eaet2iqR?n)fH_=aS}%+a9&`dZGpXzzy&-IXUu0$BJYY zubGz#am+_zSs|q4+EE-yFRtr}q{N@KFMwVK%yP zFb{FovYofJ(TOe#jAoPf;|4yB4*OXYcFlwCEeYk~>UORHH^A!ZK4iOzAV#o}7fQMP zIMzwU7)QYx$5oTfOWBG;9A`}$$8N+NU#{v%+IXGbS^pkW;bjS8Bv0T6YV41Pf&q5S=Bd&&u&f0t7Caq6G?6Xb>An+e;b*5hTKPZOaB#M2g{*V8X3SnIdKG zs+Iuhm0*qe8k$ahWb1 zDpJxFxnSX|8DK%Is0>(hb%f>StTz*%DpWspyhY3YmHXFkiSd{g!N*ir;DW znC3`b5pb2}4$TFRy0&i=DR?j+0@A-4+@<@C)16{rfYC>S-iqH+fnSuZ(XdX#4=9Ed ziV9y=8Y_36)x&3P=l2q@`M+pKo*Y+ZE}OUkd^2< z$-aCljWv(p?ze(YzZLlB9skuq+dpodp7;FVpmo$fIX+GhK#BC98=fZFWct)>!rYDZ zPrF7A!0y}GlO#6v+f{34y)T;g;aV4ynHgKf|2U284|y@N6*wVS6#7E!ld;YY^$cZ! z&7uD~JUVH&j>6+sd;g&8+Xj~VNfzhV#xIJzkdydbG0`{*M9~=N7_A`kv&raHl;Qzj zoZLv@II=%Vpq?hi8rd*~6(@zTDs&X1tV;{7tK7zIP?7UUPlTm)Hi_YQsQelnC zcE&TQl5Jf?R&&Yb1*4s^v+gz=S8b~`RZ?YDQ?7cX?!l`mPpzvh3|H;I``Wn=YXie` zHkIdkj$B`6&7#Tm{S?OZL%zE=gk!hP7a3Q059era|Ef-X+~Ho6!@GuidCDq0`$XOg z0UxQQ#nrq|aV(>GS0rQm6 Date: Sun, 30 Aug 2015 11:28:25 +0200 Subject: [PATCH 19/37] no need to share --- serialenum.pyc | Bin 1472 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 serialenum.pyc diff --git a/serialenum.pyc b/serialenum.pyc deleted file mode 100644 index 99c41ae09f4d514e61e0dad428547ed0efffcb3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1472 zcmb7EO>f&q5S=Bd&&u&f0t7Caq6G?6Xb>An+e;b*5hTKPZOaB#M2g{*V8X3SnIdKG zs+Iuhm0*qe8k$ahWb1 zDpJxFxnSX|8DK%Is0>(hb%f>StTz*%DpWspyhY3YmHXFkiSd{g!N*ir;DW znC3`b5pb2}4$TFRy0&i=DR?j+0@A-4+@<@C)16{rfYC>S-iqH+fnSuZ(XdX#4=9Ed ziV9y=8Y_36)x&3P=l2q@`M+pKo*Y+ZE}OUkd^2< z$-aCljWv(p?ze(YzZLlB9skuq+dpodp7;FVpmo$fIX+GhK#BC98=fZFWct)>!rYDZ zPrF7A!0y}GlO#6v+f{34y)T;g;aV4ynHgKf|2U284|y@N6*wVS6#7E!ld;YY^$cZ! z&7uD~JUVH&j>6+sd;g&8+Xj~VNfzhV#xIJzkdydbG0`{*M9~=N7_A`kv&raHl;Qzj zoZLv@II=%Vpq?hi8rd*~6(@zTDs&X1tV;{7tK7zIP?7UUPlTm)Hi_YQsQelnC zcE&TQl5Jf?R&&Yb1*4s^v+gz=S8b~`RZ?YDQ?7cX?!l`mPpzvh3|H;I``Wn=YXie` zHkIdkj$B`6&7#Tm{S?OZL%zE=gk!hP7a3Q059era|Ef-X+~Ho6!@GuidCDq0`$XOg z0UxQQ#nrq|aV(>GS0rQm6 Date: Sun, 30 Aug 2015 11:28:36 +0200 Subject: [PATCH 20/37] Delete Ringbuffer.pyc --- Ringbuffer.pyc | Bin 1413 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Ringbuffer.pyc diff --git a/Ringbuffer.pyc b/Ringbuffer.pyc deleted file mode 100644 index 9d9aa21045b4c06394f90b5b0143d8e6af574a2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1413 zcmbVM-)q!B5T4EDa=qG0RqR74WgjDog7_dJqP0+=P%sMOQ3)}b^wQ?XHM?hP>0AAe z{R8xyO?rJ$kh4wd1fs3fWsO%$ojBUY3v z$_Dg<=#uF31V;nPd^+~1{YKf4CO$C^eY(V@A)P%T4k!y`yYpp>CL`h@9W4=$k;)bdk6(T7kHm?_k<#wzM5w}my@<$R=P&CF;!W!;n+8>_R#CfYW- zN{(5#O;fpBdDA+lnok!_r&F%ADb86JMz@@#Q_h@o>LJ;cyp`-5P?qRO(FM2#H5bl` zQ3HVysc=6WKt~X=!cZI+bz$S!`q)U8P$G6aF7rsdLrAC0Cam2T2XESJUNxuO?(7{1 zm0ul|k7wT_xxET85|7lXTA-9j4&@e%1xg^i^Z*p7J?WwPE7Aa0lG%*w%#L7!%#w5K zphl9&;VmpzH-Kty;bJ~7%eaet2iqR?n)fH_=aS}%+a9&`dZGpXzzy&-IXUu0$BJYY zubGz#am+_zSs|q4+EE-yFRtr}q{N@KFMwVK%yP zFb{FovYofJ(TOe#jAoPf;|4yB4*OXYcFlwCEeYk~>UORHH^A!ZK4iOzAV#o}7fQMP zIMzwU7)QYx$5oTfOWBG;9A`}$$8N+NU#{v%+IXGbS^pkW;bjS8Bv0T6YV41P Date: Sun, 30 Aug 2015 21:42:59 +0200 Subject: [PATCH 21/37] new feature: choose what debug-window is displaying --- ArdumowerDK.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 28b62aa..0778943 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -586,8 +586,17 @@ def send_debug_command(): self.sendbutton = tk.Button(self, text='Send', command= send_debug_command) self.sendbutton.grid(column = 3, row =4, sticky = "e") self.autoscroll_checkbutton_var = tk.IntVar() + self.autoscroll_checkbutton_var.set(1) self.autoscroll_checkbutton = tk.Checkbutton(self, text = "Autoscroll", variable = self.autoscroll_checkbutton_var) - self.autoscroll_checkbutton.grid(column = 3, row = 7) + self.autoscroll_checkbutton.grid(column = 3, row = 7, sticky= "e") + self.sheepreply_checkbutton_var = tk.IntVar() + self.sheepreply_checkbutton_var.set(1) + self.sheepreply_checkbutton = tk.Checkbutton(self, text = "listen to sheep", variable = self.sheepreply_checkbutton_var) + self.sheepreply_checkbutton.grid(column = 3, row = 7, sticky = "w") + self.plotingdata_checkbutton_var = tk.IntVar() + self.plotingdata_checkbutton_var.set(1) + self.plotingdata_checkbutton = tk.Checkbutton(self, text = "plot data", variable = self.plotingdata_checkbutton_var) + self.plotingdata_checkbutton.grid(column = 3, row = 7) self.withdraw() class GuiConnect(tk.Toplevel): @@ -894,6 +903,7 @@ def receiveThread(self): if msg == "connected": connected = True mower = self.Ardumower + msg = "" elif msg == "disconnected": connected = False except Queue.Empty: pass @@ -905,14 +915,17 @@ def receiveThread(self): if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): - self.received_queueDebug.put(msg) + self.received_queueDebug.put("Sheep debug: " + msg) msg = "" elif not msg.find("{")>= 0: self.received_queue.put(msg) + if self.gui_Debug.plotingdata_checkbutton_var.get() == 1: self.received_queueDebug.put("Plot data: " + msg) msg = "" elif msg.find("}")>= 0: self.received_queue.put(msg) +## print self.gui_Debug.sheepreply_checkbutton_var + if self.gui_Debug.sheepreply_checkbutton_var.get() == 1: self.received_queueDebug.put("Sheep : " + msg) msg = "" except serial.SerialException: self.connected_queue.put("disconnected") @@ -975,6 +988,7 @@ def sendThread(self): elif connected: try: mower.write("{" + msg + "}" + "\n") + if self.gui_Debug.sheepreply_checkbutton_var.get() == 1: self.received_queueDebug.put("DK: "+ msg) except serial.SerialException: self.connected_queue.put("disconnected") pass From 1993c03917819d863690eb2db352f2fe1db8dc28 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Mon, 31 Aug 2015 23:36:44 +0200 Subject: [PATCH 22/37] added thread safety to the new debug features --- ArdumowerDK.py | 73 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 0778943..0a1bf66 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -563,7 +563,7 @@ def processIncoming(self): pass class GuiDebug(tk.Toplevel): - def __init__(self, master, receivedQueue1, sendQueue): + def __init__(self, master, receive_connected_queue, sendQueue): tk.Toplevel.__init__(self) self.master = master self.title("Debug") @@ -589,14 +589,28 @@ def send_debug_command(): self.autoscroll_checkbutton_var.set(1) self.autoscroll_checkbutton = tk.Checkbutton(self, text = "Autoscroll", variable = self.autoscroll_checkbutton_var) self.autoscroll_checkbutton.grid(column = 3, row = 7, sticky= "e") - self.sheepreply_checkbutton_var = tk.IntVar() - self.sheepreply_checkbutton_var.set(1) - self.sheepreply_checkbutton = tk.Checkbutton(self, text = "listen to sheep", variable = self.sheepreply_checkbutton_var) - self.sheepreply_checkbutton.grid(column = 3, row = 7, sticky = "w") + self.sheepReply_checkbutton_var = tk.IntVar() + self.sheepReply_checkbutton_var.set(0) + self.sheepReply_checkbutton = tk.Checkbutton(self, text = "listen to sheep", variable = self.sheepReply_checkbutton_var) + self.sheepReply_checkbutton.grid(column = 3, row = 8, sticky = "w") + self.sheepSend_checkbutton_var = tk.IntVar() + self.sheepSend_checkbutton_var.set(0) + self.sheepSend_checkbutton = tk.Checkbutton(self, text = "sent to sheep", variable = self.sheepSend_checkbutton_var) + self.sheepSend_checkbutton.grid(column = 3, row = 7, sticky = "w") self.plotingdata_checkbutton_var = tk.IntVar() - self.plotingdata_checkbutton_var.set(1) + self.plotingdata_checkbutton_var.set(0) self.plotingdata_checkbutton = tk.Checkbutton(self, text = "plot data", variable = self.plotingdata_checkbutton_var) self.plotingdata_checkbutton.grid(column = 3, row = 7) + def getDebug(a,b,c): + if self.plotingdata_checkbutton_var.get() == 1: receive_connected_queue.put("Data Debug") + if self.plotingdata_checkbutton_var.get() == 0: receive_connected_queue.put("Data noDebug") + if self.sheepReply_checkbutton_var.get() == 1: receive_connected_queue.put("Sheep Debug") + if self.sheepReply_checkbutton_var.get() == 0: receive_connected_queue.put("Sheep noDebug") + if self.sheepSend_checkbutton_var.get() == 1: sendQueue.put("Sent Debug") + if self.sheepSend_checkbutton_var.get() == 0: sendQueue.put("Sent noDebug") + self.sheepReply_checkbutton_var.trace("w",getDebug) + self.plotingdata_checkbutton_var.trace("w",getDebug) + self.sheepSend_checkbutton_var.trace("w",getDebug) self.withdraw() class GuiConnect(tk.Toplevel): @@ -647,9 +661,6 @@ def IPadress(): else: self.initQueue.put(msg) - - - self.scanbutton = tk.Button(self, text='Rescan', command = scan) self.scanbutton.grid(column = 3, row = 5, sticky = "e") self.connectbutton = tk.Button(self, text='Connect', command= connect_command) @@ -657,9 +668,12 @@ def IPadress(): self.disconnectbutton = tk.Button(self, text='Disconnect', command= close_com, state = tk.DISABLED) self.disconnectbutton.grid(column = 3, row =4, sticky = "e") self.autodetect_checkbutton_var = tk.IntVar() - self.autodetect_checkbutton_var.set(1) + if (platform.system() == 'Windows'):self.autodetect_checkbutton_var.set(1) + else: self.autodetect_checkbutton_var.set(0) self.autodetect_checkbutton = tk.Checkbutton(self, text = "Autodetect", variable = self.autodetect_checkbutton_var) if (platform.system() == 'Windows'):self.autodetect_checkbutton.grid(column = 3, row = 7) + + ## self.withdraw() @@ -680,7 +694,7 @@ def __init__(self, master): # Create the queue self.received_queue = Queue.Queue() - self.received_queueDebug = Queue.Queue() + self.receivedDebug_queue = Queue.Queue() self.send_queue = Queue.Queue() self.init_Queue = Queue.Queue() self.receive_connected_queue = Queue.Queue() @@ -705,7 +719,7 @@ def hide_Com(): master.deiconify() self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug, openCom) - self.gui_Debug = GuiDebug(master, self.received_queueDebug, self.send_queue) + self.gui_Debug = GuiDebug(master, self.receive_connected_queue, self.send_queue) self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) self.gui_com = GuiConnect(master, self.init_Queue, self.close_com) self.gui_com.protocol("WM_DELETE_WINDOW", hide_Com) @@ -718,8 +732,8 @@ def hide_Com(): self.master.after(1000,self.threadI.start) self.threadR = threading.Thread(target=self.receiveThread) self.threadS = threading.Thread(target=self.sendThread) - self.threadR.start() - self.threadS.start() + self.master.after(1000, self.threadR.start) + self.master.after(1000, self.threadS.start) # Start the periodic call in the GUI to check if the queue contains @@ -742,9 +756,9 @@ def periodicCall(self): self.master.after(100, self.periodicCall) def processIncoming(self): - while self.received_queueDebug.qsize(): + while self.receivedDebug_queue.qsize(): try: - msg = self.received_queueDebug.get() + msg = self.receivedDebug_queue.get() self.gui_Debug.debug_entry_in_var.set(msg) self.gui_Debug.debug_text.insert(tk.END, msg + "\n") if self.gui_Debug.autoscroll_checkbutton_var.get() == 1: @@ -890,6 +904,8 @@ def receiveThread(self): """ msg = "" connected = False + sheepReply_checkbutton_var = False + dataPlot_checkbutton_var = False while self.running: time.sleep(0.01) # To simulate asynchronous I/O, we create a random number at @@ -900,11 +916,17 @@ def receiveThread(self): # Check contents of message and do what it says # msg = self.receive_connected_queue.get(0) +## print msg if msg == "connected": connected = True mower = self.Ardumower - msg = "" + elif msg == "disconnected": connected = False + elif msg == "Sheep Debug": sheepReply_checkbutton_var = True + elif msg == "Sheep noDebug": sheepReply_checkbutton_var = False + elif msg == "Data Debug": dataPlot_checkbutton_var = True + elif msg == "Data noDebug": dataPlot_checkbutton_var = False + msg = "" except Queue.Empty: pass @@ -915,17 +937,16 @@ def receiveThread(self): if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): - self.received_queueDebug.put("Sheep debug: " + msg) + self.receivedDebug_queue.put("Sheep debug: " + msg) msg = "" elif not msg.find("{")>= 0: self.received_queue.put(msg) - if self.gui_Debug.plotingdata_checkbutton_var.get() == 1: self.received_queueDebug.put("Plot data: " + msg) + if dataPlot_checkbutton_var == True: self.receivedDebug_queue.put("Plot data: " + msg) msg = "" elif msg.find("}")>= 0: self.received_queue.put(msg) -## print self.gui_Debug.sheepreply_checkbutton_var - if self.gui_Debug.sheepreply_checkbutton_var.get() == 1: self.received_queueDebug.put("Sheep : " + msg) + if sheepReply_checkbutton_var == True: self.receivedDebug_queue.put("Sheep : " + msg) msg = "" except serial.SerialException: self.connected_queue.put("disconnected") @@ -955,7 +976,7 @@ def receiveThread(self): #### print "dbug:", msg ## ## if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): -## self.received_queueDebug.put(msg) +## self.receivedDebug_queue.put(msg) ## msg = "" ## elif not msg.find("{")>= 0: ## self.received_queue.put(msg) @@ -974,6 +995,7 @@ def sendThread(self): control. """ connected = False + sheepSent_checkbutton_var = False while self.running: time.sleep(0.01) if self.send_queue.qsize(): @@ -981,14 +1003,19 @@ def sendThread(self): # Check contents of message and do what it says # msg = self.send_queue.get(0) +## print msg if msg == "connected": connected = True mower = self.Ardumower + elif msg == "Sent Debug": sheepSent_checkbutton_var = True + elif msg == "Sent noDebug": sheepSent_checkbutton_var = False elif msg == "disconnected": connected = False + + elif connected: try: mower.write("{" + msg + "}" + "\n") - if self.gui_Debug.sheepreply_checkbutton_var.get() == 1: self.received_queueDebug.put("DK: "+ msg) + if sheepSent_checkbutton_var == True: self.receivedDebug_queue.put("DK: "+ msg) except serial.SerialException: self.connected_queue.put("disconnected") pass From 07b5c619df76da81e9938a22b4e858bbb64deb4e Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sun, 6 Sep 2015 18:21:59 +0200 Subject: [PATCH 23/37] update V15 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d7c5d81..34a9ea3 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,9 @@ Bluetooth Serial Communication to Ardumower ',' or '|' or '{' or '}' should not be used in the debug strings since these characters are used for filtering normal communication (commands/plot data) +#Save settings to file + it's now possible to save your mowers settings to ta txt file + Timer settings are ignored #use at your own risk From 28a5961e1272745fc8f636d985acad7f5bf28b47 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sun, 6 Sep 2015 18:28:50 +0200 Subject: [PATCH 24/37] V15 new features added -"log sensors" implemented -save mower settings to a txt file -helpmenu with about showing Version Nr --- ArdumowerDK.py | 283 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 249 insertions(+), 34 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 0a1bf66..01adab5 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------- # Name: Ardumower DK -# Purpose: Communication Ardumower - Windows computer via Bluetooth serial por +# Purpose: Communication Ardumower - Windows computer via Bluetooth serial port # # Author: Holoratte # -# Created: 27.08.2015 +# Created: 06.09.2015 # Copyright: (c) Holoratte 2015 # Licence: Just use it. Selling this software might be prohibited. -# Version: 14 +# Version: 15 #------------------------------------------------------------------------------- """ @@ -35,6 +35,7 @@ import Ringbuffer import serial import tkMessageBox +import tkFileDialog import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg @@ -43,31 +44,52 @@ from matplotlib.ticker import MultipleLocator, FormatStrFormatter import platform import serialenum +import csv +import datetime class GuiPart: - def __init__(self, master, receivedQueue, sendQueue, endCommand, Debug, Com): + def __init__(self, master, receivedQueue, sendQueue, receiveConnected_Queue, + saveToFile_Queue, logToFile_Queue, endCommand, Debug, Com): + self.master = master self.lastCommand = [] for i in range(100): self.lastCommand.append(".") - + self.settingsfname = "" + self.logFileName= "" + self.settingsToFile = False + self.settingsFromFile = False + self.logToFile = False + self.mainSettingsComand_list = [] + self.mainSettingsName_list = [] + self.snl_index = 0 + self.numberOfSetting = 0 + self.RQueue = receivedQueue + self.SQueue = sendQueue + self.sTfQueue = saveToFile_Queue + self.rCQueue = receiveConnected_Queue + self.lTfQueue = logToFile_Queue # Set up the GUI #---------------Menu-------------------------------------------- def donothing(): filewin = tk.Toplevel(master) - button = tk.Button(filewin, text="Do nothing button") + button = tk.Button(filewin, text="not yet implemented ;-(") + button.pack() + def showversion(): + filewin = tk.Toplevel(master) + button = tk.Button(filewin, text="ArdumowerDK V15") button.pack() menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff = 0) - filemenu.add_command(label="New", command=donothing) +## filemenu.add_command(label="New", command=donothing) ## filemenu.add_command(label="Open", command=donothing) ## filemenu.add_command(label="Save", command=donothing) ## filemenu.add_command(label="Save as...", command=donothing) ## filemenu.add_command(label="Close", command=donothing) ## - filemenu.add_separator() +## filemenu.add_separator() filemenu.add_command(label="Exit", command=endCommand) menubar.add_cascade(label="File", menu=filemenu) @@ -94,21 +116,23 @@ def donothing(): settingsmenu = tk.Menu(menubar, tearoff=0) settingsmenu.add_command(label="save", command=lambda: self.send("sz")) + settingsmenu.add_command(label="save to file", command= self.save_settings_toFile) + settingsmenu.add_command(label="load from file", command=donothing) +## settingsmenu.add_command(label="load from file", command=self.load_settings_fromFile) settingsmenu.add_command(label="load fatory settings", command=lambda: self.send("sx")) settingsmenu.add_command(label="Edit", command=lambda: self.send("s")) menubar.add_cascade(label="Settings", menu=settingsmenu) -## helpmenu = tk.Menu(menubar, tearoff=0) -## helpmenu.add_command(label="Help Index", command=donothing) -## helpmenu.add_command(label="About...", command=donothing) -## menubar.add_cascade(label="Help", menu=helpmenu) + helpmenu = tk.Menu(menubar, tearoff=0) + helpmenu.add_command(label="Help Index", command=donothing) + helpmenu.add_command(label="About...", command=showversion) + menubar.add_cascade(label="Help", menu=helpmenu) master.config(menu=menubar) #--------------------Buttons and scalebars---------------------------------------------- - self.RQueue = receivedQueue - self.SQueue = sendQueue + self.console1 = tk.Button(master, text='Main', command= self.mainmenu) self.console1.grid(column = 0, row =0) @@ -152,7 +176,7 @@ def donothing(): self.scale[i].grid_remove() # -----------------------------------Plot--------------------------- - self.canvasnumber =5 + self.canvasnumber =9 #number of subsubplots (1-9) self.plot = False self.channel = 0 self.f = Figure() @@ -202,7 +226,6 @@ def donothing(): a.set_xlabel("") a.set_xticks([]) - self.channel += 1 self.channel = 0 self.plotnumbers = [0] @@ -228,6 +251,57 @@ def donothing(): master.bind('', self.sendAutomode) + def create_csv(self): +## print'doing' + date= str(datetime.datetime.now().replace(microsecond=0)) + date, time= date.split() +## time , gmt= time.split('+') + + hh,mm,ss=time.split(':') + self.logFileName += "_" + date+' '+hh+'-'+mm+'-'+ss+'.csv' + with open(self.logFileName, "wb" ) as f: + writer = csv.writer(f) + writer.writerow( ("ARDUMOWER SENSOR LOG FILE") ) + return True +## print 'done' + + + def write_csv(self,datetime,data): + datetime=str(datetime.replace(microsecond=0)) + date, time= datetime.split() + if data[0].find("time") >= 0: + data.insert(0,"Time") + data.insert(0,"Date") + else: + data.insert(0,time) + data.insert(0,date) +## time , gmt= time.split('+') + try: + with open(self.logFileName, 'ab' ) as f: + writer = csv.writer(f, dialect='excel') + writer.writerow(data) + except: + print "cannot write so fast" + pass + + def save_settings_toFile(self,fname = ""): + if fname == "": fname = tkFileDialog.asksaveasfilename( title='Save to file', filetypes=[("Ardumower settings","*.ardm" ),],defaultextension="*.ardm") + if fname != "": + self.settingsfname = fname + msg = "settings_toFile" + self.settingsToFile = True + self.rCQueue.put(msg) + self.send("s") + + def load_settings_fromFile(self,fname = ""): + if fname == "": fname = tkFileDialog.askopenfilename( title='Load from file', filetypes=[("Ardumower settings","*.ardm" ),("all files", "*.*")],defaultextension="*.ardm") + if fname != "": + self.settingsfname = fname + msg = "settings_fromFile" + self.settingsFromFile = True + self.rCQueue.put(msg) + self.send("s") + def update_background(self,event): for i in range(len(self.backgrounds)): @@ -293,16 +367,40 @@ def sendAutomode(self,event): self.send("ra") def send(self, command, value = None): - - if value == None and command!= "sz" and command!= "sx": self.lastCommand.append(command) - if value != None: - if value == "back": - if len(self.lastCommand) >= 1: del self.lastCommand[-1] - elif value== "refresh": - pass + if command == "sx": + if tkMessageBox.askokcancel("Factory Reset", "Do You really want to reset all setting to factory default?"): + self.SQueue.put(command) + elif command == "sz": + if tkMessageBox.askokcancel("Save Setting", "Do You really want to save the settings to the eeprom?"): + self.SQueue.put(command) + elif command =="m1": + fname = "" + fname = tkFileDialog.asksaveasfilename( title='Save Sensor log to file', filetypes=[("comma separated value","*.csv" )]) + if fname != "": + self.logFileName = fname + if self.create_csv(): + self.rCQueue.put("log") + self.logToFile = True + self.SQueue.put(command) + else: + self.rCQueue.put("no log") + self.logToFile = False else: - command += "`" + str(value) - self.SQueue.put(command) + self.rCQueue.put("no log") + self.logToFile = False + + else: + self.rCQueue.put("no log") + self.logToFile = False + if value == None and command!= "sz" and command!= "sx": self.lastCommand.append(command) + if value != None: + if value == "back": + if len(self.lastCommand) >= 1: del self.lastCommand[-1] + elif value== "refresh": + pass + else: + command += "`" + str(value) + self.SQueue.put(command) def mainmenu(self): @@ -366,7 +464,7 @@ def processIncoming(self): try: msg = self.RQueue.get(0) # Check contents of message and do what it says - +## print "r msg: ",msg if msg.find("init") >= 0: msg.strip("init") init = True @@ -382,13 +480,20 @@ def processIncoming(self): msg = msg.strip("=") msg_list = msg.rsplit("|") + elif msg.find("Log sensors") >= 0: + msg = msg.strip("{") + msg = msg.strip("}") + msg = msg.strip(".") + msg = msg.strip("=") + msg_list.append(msg) + - elif msg.find(",") >= 0: + elif msg.find(",") >= 0 and not self.logToFile: data_list = msg.rsplit(",") for i in range(len(data_list)): data_list[i] = float(data_list[i]) else: -## print"msg error" + print"msg error:" , msg pass if not self.plot: for i in range(len(self.nav_buttons)): @@ -504,7 +609,8 @@ def processIncoming(self): tiltlenumber = self.titles.index(tiltle) if tiltlenumber == 6: - + self.rCQueue.put("no log") + self.logToFile = False for button in self.main_buttons: button.grid_remove() self.titles=[] @@ -524,7 +630,16 @@ def processIncoming(self): self.main_buttons[i].grid() self.titles.append(comName) self.console1.grid() + elif tiltlenumber == 5: + self.plot = False + for i in range(len(self.main_buttons)): + self.main_buttons[i].configure(relief = tk.RAISED) + self.main_buttons[tiltlenumber].configure(relief = tk.RIDGE) + + else: + self.rCQueue.put("no log") + self.logToFile = False self.plot = False for i in range(len(self.main_buttons)): self.main_buttons[i].configure(relief = tk.RAISED) @@ -558,10 +673,94 @@ def processIncoming(self): self.scaleVar[i].set(self.ist_list[i]) self.nav_buttons[i].configure(text=comName, command= lambda i=i: self.send(self.command_list[i], self.scaleVar[i].get()/self.multiplier_list[i])) - except Queue.Empty: pass + if self.logToFile: + while self.lTfQueue.qsize(): + try: + msg = self.lTfQueue.get(0) + msg = msg.strip("\n") + msg = msg.strip("\r") + datalist = msg.rsplit(",") + self.write_csv(datetime.datetime.now(),datalist) +## print msg + msg = "" + except Queue.Empty: + pass + + if self.settingsToFile: + while self.sTfQueue.qsize(): + + try: + msg = self.sTfQueue.get(0) + msg = msg.strip("\n") + msg = msg.strip("\r") + settings_list = [] + + if msg.find("|") >= 0: + msg = msg.strip("{") + msg = msg.strip("}") + msg = msg.strip(".") + msg = msg.strip("=") + + msg_list = msg.rsplit("|") + + # Check contents of message and do what it says + for i in range(len(msg_list)-1): + if msg_list[i+1].find("~ ~") >= 0: + coma, comName, a, multiplier = msg_list[i+1].split("~") + comName, ist , maximum, minimum = comName.split("`") + tabubaltor = "\t" + descriptor = comName +" (maximum:"+ maximum + " minimum:"+ minimum + ") " + " X " + multiplier + numberOfTabs = int((75 - len(descriptor))/4)+1 + for j in range(numberOfTabs): tabubaltor += "\t" + setting = descriptor + tabubaltor + "|" + coma + "`" + ist + else: + coma, comName = msg_list[i+1].split("~") + tabubaltor = "\t" + descriptor = comName + numberOfTabs = int((75 - len(descriptor))/4)+1 + for j in range(numberOfTabs): tabubaltor += "\t" + setting = descriptor + tabubaltor + "|" + coma + + if msg_list[0].find("Settings") >= 0: + if (coma.find("sz") == -1) and (coma.find("sx") == -1): + comName = comName.upper() + self.mainSettingsName_list.append(comName) + self.mainSettingsComand_list.append(coma) + else: + if setting.find("\n") == -1: + settings_list.append(setting) + + if msg_list[0].find("Settings") >= 0: + self.snl_index = 0 + with open(self.settingsfname,"w") as settingsFile: + settingsFile.write("SETTINGS ARDUMOWER"+ time.strftime("%Y-%m-%d %H:%M:%S") + "\n\n\n\n") + else: + tabubaltor = "\t" + descriptor = self.mainSettingsName_list[self.snl_index] + numberOfTabs = int((75 - len(descriptor))/4)+1 + for j in range(numberOfTabs): tabubaltor += "\t" + mainSet = descriptor + tabubaltor + "|" + self.mainSettingsComand_list[self.snl_index] + "\n" + + with open(self.settingsfname,"a") as settingsFile: + settingsFile.write(mainSet) + for setting in settings_list: + settingsFile.write(setting + "\n") + settingsFile.write("\n\n\n") + self.snl_index += 1 + + if self.snl_index +1 <= (len(self.mainSettingsComand_list)): self.send(self.mainSettingsComand_list[self.snl_index]) + else: + self.rCQueue.put("not_settingsToFile") + self.settingsToFile = False + self.snl_index = 0 + + + except Queue.Empty: + pass + class GuiDebug(tk.Toplevel): def __init__(self, master, receive_connected_queue, sendQueue): tk.Toplevel.__init__(self) @@ -699,6 +898,9 @@ def __init__(self, master): self.init_Queue = Queue.Queue() self.receive_connected_queue = Queue.Queue() self.connected_queue = Queue.Queue() + self.saveToFile_Queue = Queue.Queue() + self.logToFile_Queue = Queue.Queue() + # Set up the GUI part def openDebug(): self.gui_Debug.deiconify() @@ -718,7 +920,9 @@ def hide_Com(): self.gui_com.withdraw() master.deiconify() - self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug, openCom) + self.gui = GuiPart(master, self.received_queue, self.send_queue, + self.receive_connected_queue, self.saveToFile_Queue, self.logToFile_Queue, + self.endApplication, openDebug, openCom) self.gui_Debug = GuiDebug(master, self.receive_connected_queue, self.send_queue) self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) self.gui_com = GuiConnect(master, self.init_Queue, self.close_com) @@ -906,6 +1110,8 @@ def receiveThread(self): connected = False sheepReply_checkbutton_var = False dataPlot_checkbutton_var = False + settings_toFile = False + logToFile = False while self.running: time.sleep(0.01) # To simulate asynchronous I/O, we create a random number at @@ -914,7 +1120,6 @@ def receiveThread(self): if self.receive_connected_queue.qsize(): try: # Check contents of message and do what it says - # msg = self.receive_connected_queue.get(0) ## print msg if msg == "connected": @@ -926,10 +1131,16 @@ def receiveThread(self): elif msg == "Sheep noDebug": sheepReply_checkbutton_var = False elif msg == "Data Debug": dataPlot_checkbutton_var = True elif msg == "Data noDebug": dataPlot_checkbutton_var = False + elif msg == "settings_toFile": settings_toFile = True + elif msg == "not_settingsToFile": settings_toFile = False + elif msg == "log": logToFile = True + elif msg == "no log": logToFile = False msg = "" + except Queue.Empty: pass + if connected and mower.inWaiting() != 0: try: @@ -940,12 +1151,16 @@ def receiveThread(self): self.receivedDebug_queue.put("Sheep debug: " + msg) msg = "" elif not msg.find("{")>= 0: - self.received_queue.put(msg) + if not logToFile: self.received_queue.put(msg) + else: self.logToFile_Queue.put(msg) if dataPlot_checkbutton_var == True: self.receivedDebug_queue.put("Plot data: " + msg) msg = "" elif msg.find("}")>= 0: - self.received_queue.put(msg) + if settings_toFile: self.saveToFile_Queue.put(msg) +## elif logToFile: self.logToFile_Queue.put(msg) + else: self.received_queue.put(msg) + if sheepReply_checkbutton_var == True: self.receivedDebug_queue.put("Sheep : " + msg) msg = "" except serial.SerialException: From 7338a9c5206f8a171dde23039d0f6e4190e8b991 Mon Sep 17 00:00:00 2001 From: Sebastian Held Date: Wed, 9 Sep 2015 21:06:21 +0200 Subject: [PATCH 25/37] python3 and linux compatibility --- ArdumowerDK.py | 51 ++++++++++++++++++++++++++-------------------- Ringbuffer.py | 2 +- toy.xbm => Toy.xbm | 0 serialenum.py | 5 +++-- 4 files changed, 33 insertions(+), 25 deletions(-) rename toy.xbm => Toy.xbm (100%) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 01adab5..7360852 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -24,18 +24,25 @@ Created by Jacob Hallén, AB Strakt, Sweden. 2001-10-17 """ - - -import Tkinter as tk +import pdb + +import sys +if (sys.version_info > (3, 0)): + import tkinter as tk + import queue as Queue + import tkinter.messagebox as tkMessageBox + import tkinter.filedialog as tkFileDialog +else: + import Tkinter as tk + import Queue + import tkMessageBox + import tkFileDialog import time import threading import random -import Queue ##import statusbar import Ringbuffer import serial -import tkMessageBox -import tkFileDialog import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg @@ -281,7 +288,7 @@ def write_csv(self,datetime,data): writer = csv.writer(f, dialect='excel') writer.writerow(data) except: - print "cannot write so fast" + print( "cannot write so fast" ) pass def save_settings_toFile(self,fname = ""): @@ -493,7 +500,7 @@ def processIncoming(self): for i in range(len(data_list)): data_list[i] = float(data_list[i]) else: - print"msg error:" , msg + print( "msg error:" , msg ) pass if not self.plot: for i in range(len(self.nav_buttons)): @@ -830,7 +837,7 @@ def scan(): ## self.connection_options.append("Network") self.connection_options.append("") self.options_var.set(self.connection_options[-1]) - self.options = apply(tk.OptionMenu,(self,self.options_var)+tuple(self.connection_options)) + self.options = tk.OptionMenu(*(self,self.options_var)+tuple(self.connection_options)) self.options.grid(column = 3, row = 5, sticky = "w") scan() @@ -932,7 +939,7 @@ def hide_Com(): self.running = True self.connected = False self.init_com = True - self.threadI = threading.Thread(target=self.initThread) + self.threadI = threading.Thread(target=self.initThread) self.master.after(1000,self.threadI.start) self.threadR = threading.Thread(target=self.receiveThread) self.threadS = threading.Thread(target=self.sendThread) @@ -1002,20 +1009,20 @@ def scan_comport(com_exclude): if comport not in com_exclude: try: com_device = serial.Serial("com" + str(comport), baudrate=19200, writeTimeout = 100000) - print "Testing com:",comport + print( "Testing com:", comport ) except: if int(comport) <= 49: comport += 1 ## print comport else: com_device = "" - print "Failed to connect to Device" + print( "Failed to connect to Device" ) connected = False ## print comport comport ="51" else: comport += 1 - print "Testing com:",comport + print( "Testing com:", comport ) ## comport =1 return com_device, comport @@ -1042,7 +1049,7 @@ def scan_comport(com_exclude): try: self.Ardumower.close() except: - print "port cannot close" + print( "port cannot close" ) elif autodetect and (platform.system() == 'Windows'): @@ -1050,12 +1057,12 @@ def scan_comport(com_exclude): com_device, com = scan_comport(com_exclude) ## time.sleep(0.1) if com_device != "": - com_device.write("{.}") + com_device.write(b"{.}") time.sleep(0.5) while com_device.inWaiting() != 0 and connected == False: - muC = com_device.readline() + muC = com_device.readline().decode('ASCII') if muC.find("Ardumower") >= 0: - print"found Ardumower" + print( "found Ardumower" ) self.Ardumower = com_device ms = muC + "init" self.received_queue.put(ms) @@ -1077,12 +1084,12 @@ def scan_comport(com_exclude): elif msg != "": com_device = serial.Serial(msg, baudrate=19200, writeTimeout = 10000) if com_device != "": - com_device.write("{.}") + com_device.write( b'{.}' ) time.sleep(0.5) while com_device.inWaiting() != 0 and connected == False: - muC = com_device.readline() + muC = com_device.readline().decode('ASCII') if muC.find("Ardumower") >= 0: - print"found Ardumower" + print( "found Ardumower" ) self.Ardumower = com_device ms = muC + "init" self.receive_connected_queue.put("connected") @@ -1144,7 +1151,7 @@ def receiveThread(self): if connected and mower.inWaiting() != 0: try: - msg += mower.readline() + msg += mower.readline().decode('ASCII') if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): @@ -1229,7 +1236,7 @@ def sendThread(self): elif connected: try: - mower.write("{" + msg + "}" + "\n") + mower.write( b'{' + msg.encode('ASCII') + b"}\n") if sheepSent_checkbutton_var == True: self.receivedDebug_queue.put("DK: "+ msg) except serial.SerialException: self.connected_queue.put("disconnected") diff --git a/Ringbuffer.py b/Ringbuffer.py index 3ab2dd7..d8fdd57 100644 --- a/Ringbuffer.py +++ b/Ringbuffer.py @@ -36,5 +36,5 @@ def get(self): ring = RingBuffer(size) for x in range(9): ring.append(x) - print ring.get() # test + print( ring.get() ) # test diff --git a/toy.xbm b/Toy.xbm similarity index 100% rename from toy.xbm rename to Toy.xbm diff --git a/serialenum.py b/serialenum.py index 95f44f8..0bb8916 100644 --- a/serialenum.py +++ b/serialenum.py @@ -27,7 +27,7 @@ def enumerate(): except WindowsError: break return ports - elif sys.platform == 'linux2': + elif sys.platform.startswith('linux'): if os.path.exists('/dev/serial/by-id'): entries = os.listdir('/dev/serial/by-id') dirs = [os.readlink(os.path.join('/dev/serial/by-id', x)) @@ -38,6 +38,7 @@ def enumerate(): for dev in glob('/dev/ttyS*'): try: port = Serial(dev) + port.close() except: pass else: @@ -51,7 +52,7 @@ def enumerate(): def script(): for port in enumerate(): - print "Ports: ", port + print( "Ports: " + port ) if __name__ == "__main__": script() \ No newline at end of file From 641caed525b6fa1ed43c339054c228194a5094e0 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sat, 12 Sep 2015 00:08:15 +0200 Subject: [PATCH 26/37] Revert "V15 new features added" This reverts commit 28a5961e1272745fc8f636d985acad7f5bf28b47. --- ArdumowerDK.py | 283 ++++++------------------------------------------- 1 file changed, 34 insertions(+), 249 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 01adab5..0a1bf66 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------- # Name: Ardumower DK -# Purpose: Communication Ardumower - Windows computer via Bluetooth serial port +# Purpose: Communication Ardumower - Windows computer via Bluetooth serial por # # Author: Holoratte # -# Created: 06.09.2015 +# Created: 27.08.2015 # Copyright: (c) Holoratte 2015 # Licence: Just use it. Selling this software might be prohibited. -# Version: 15 +# Version: 14 #------------------------------------------------------------------------------- """ @@ -35,7 +35,6 @@ import Ringbuffer import serial import tkMessageBox -import tkFileDialog import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg @@ -44,52 +43,31 @@ from matplotlib.ticker import MultipleLocator, FormatStrFormatter import platform import serialenum -import csv -import datetime class GuiPart: - def __init__(self, master, receivedQueue, sendQueue, receiveConnected_Queue, - saveToFile_Queue, logToFile_Queue, endCommand, Debug, Com): - + def __init__(self, master, receivedQueue, sendQueue, endCommand, Debug, Com): self.master = master self.lastCommand = [] for i in range(100): self.lastCommand.append(".") - self.settingsfname = "" - self.logFileName= "" - self.settingsToFile = False - self.settingsFromFile = False - self.logToFile = False - self.mainSettingsComand_list = [] - self.mainSettingsName_list = [] - self.snl_index = 0 - self.numberOfSetting = 0 - self.RQueue = receivedQueue - self.SQueue = sendQueue - self.sTfQueue = saveToFile_Queue - self.rCQueue = receiveConnected_Queue - self.lTfQueue = logToFile_Queue + # Set up the GUI #---------------Menu-------------------------------------------- def donothing(): filewin = tk.Toplevel(master) - button = tk.Button(filewin, text="not yet implemented ;-(") - button.pack() - def showversion(): - filewin = tk.Toplevel(master) - button = tk.Button(filewin, text="ArdumowerDK V15") + button = tk.Button(filewin, text="Do nothing button") button.pack() menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff = 0) -## filemenu.add_command(label="New", command=donothing) + filemenu.add_command(label="New", command=donothing) ## filemenu.add_command(label="Open", command=donothing) ## filemenu.add_command(label="Save", command=donothing) ## filemenu.add_command(label="Save as...", command=donothing) ## filemenu.add_command(label="Close", command=donothing) ## -## filemenu.add_separator() + filemenu.add_separator() filemenu.add_command(label="Exit", command=endCommand) menubar.add_cascade(label="File", menu=filemenu) @@ -116,23 +94,21 @@ def showversion(): settingsmenu = tk.Menu(menubar, tearoff=0) settingsmenu.add_command(label="save", command=lambda: self.send("sz")) - settingsmenu.add_command(label="save to file", command= self.save_settings_toFile) - settingsmenu.add_command(label="load from file", command=donothing) -## settingsmenu.add_command(label="load from file", command=self.load_settings_fromFile) settingsmenu.add_command(label="load fatory settings", command=lambda: self.send("sx")) settingsmenu.add_command(label="Edit", command=lambda: self.send("s")) menubar.add_cascade(label="Settings", menu=settingsmenu) - helpmenu = tk.Menu(menubar, tearoff=0) - helpmenu.add_command(label="Help Index", command=donothing) - helpmenu.add_command(label="About...", command=showversion) - menubar.add_cascade(label="Help", menu=helpmenu) +## helpmenu = tk.Menu(menubar, tearoff=0) +## helpmenu.add_command(label="Help Index", command=donothing) +## helpmenu.add_command(label="About...", command=donothing) +## menubar.add_cascade(label="Help", menu=helpmenu) master.config(menu=menubar) #--------------------Buttons and scalebars---------------------------------------------- - + self.RQueue = receivedQueue + self.SQueue = sendQueue self.console1 = tk.Button(master, text='Main', command= self.mainmenu) self.console1.grid(column = 0, row =0) @@ -176,7 +152,7 @@ def showversion(): self.scale[i].grid_remove() # -----------------------------------Plot--------------------------- - self.canvasnumber =9 #number of subsubplots (1-9) + self.canvasnumber =5 self.plot = False self.channel = 0 self.f = Figure() @@ -226,6 +202,7 @@ def showversion(): a.set_xlabel("") a.set_xticks([]) + self.channel += 1 self.channel = 0 self.plotnumbers = [0] @@ -251,57 +228,6 @@ def showversion(): master.bind('', self.sendAutomode) - def create_csv(self): -## print'doing' - date= str(datetime.datetime.now().replace(microsecond=0)) - date, time= date.split() -## time , gmt= time.split('+') - - hh,mm,ss=time.split(':') - self.logFileName += "_" + date+' '+hh+'-'+mm+'-'+ss+'.csv' - with open(self.logFileName, "wb" ) as f: - writer = csv.writer(f) - writer.writerow( ("ARDUMOWER SENSOR LOG FILE") ) - return True -## print 'done' - - - def write_csv(self,datetime,data): - datetime=str(datetime.replace(microsecond=0)) - date, time= datetime.split() - if data[0].find("time") >= 0: - data.insert(0,"Time") - data.insert(0,"Date") - else: - data.insert(0,time) - data.insert(0,date) -## time , gmt= time.split('+') - try: - with open(self.logFileName, 'ab' ) as f: - writer = csv.writer(f, dialect='excel') - writer.writerow(data) - except: - print "cannot write so fast" - pass - - def save_settings_toFile(self,fname = ""): - if fname == "": fname = tkFileDialog.asksaveasfilename( title='Save to file', filetypes=[("Ardumower settings","*.ardm" ),],defaultextension="*.ardm") - if fname != "": - self.settingsfname = fname - msg = "settings_toFile" - self.settingsToFile = True - self.rCQueue.put(msg) - self.send("s") - - def load_settings_fromFile(self,fname = ""): - if fname == "": fname = tkFileDialog.askopenfilename( title='Load from file', filetypes=[("Ardumower settings","*.ardm" ),("all files", "*.*")],defaultextension="*.ardm") - if fname != "": - self.settingsfname = fname - msg = "settings_fromFile" - self.settingsFromFile = True - self.rCQueue.put(msg) - self.send("s") - def update_background(self,event): for i in range(len(self.backgrounds)): @@ -367,40 +293,16 @@ def sendAutomode(self,event): self.send("ra") def send(self, command, value = None): - if command == "sx": - if tkMessageBox.askokcancel("Factory Reset", "Do You really want to reset all setting to factory default?"): - self.SQueue.put(command) - elif command == "sz": - if tkMessageBox.askokcancel("Save Setting", "Do You really want to save the settings to the eeprom?"): - self.SQueue.put(command) - elif command =="m1": - fname = "" - fname = tkFileDialog.asksaveasfilename( title='Save Sensor log to file', filetypes=[("comma separated value","*.csv" )]) - if fname != "": - self.logFileName = fname - if self.create_csv(): - self.rCQueue.put("log") - self.logToFile = True - self.SQueue.put(command) - else: - self.rCQueue.put("no log") - self.logToFile = False - else: - self.rCQueue.put("no log") - self.logToFile = False - else: - self.rCQueue.put("no log") - self.logToFile = False - if value == None and command!= "sz" and command!= "sx": self.lastCommand.append(command) - if value != None: - if value == "back": - if len(self.lastCommand) >= 1: del self.lastCommand[-1] - elif value== "refresh": - pass - else: - command += "`" + str(value) - self.SQueue.put(command) + if value == None and command!= "sz" and command!= "sx": self.lastCommand.append(command) + if value != None: + if value == "back": + if len(self.lastCommand) >= 1: del self.lastCommand[-1] + elif value== "refresh": + pass + else: + command += "`" + str(value) + self.SQueue.put(command) def mainmenu(self): @@ -464,7 +366,7 @@ def processIncoming(self): try: msg = self.RQueue.get(0) # Check contents of message and do what it says -## print "r msg: ",msg + if msg.find("init") >= 0: msg.strip("init") init = True @@ -480,20 +382,13 @@ def processIncoming(self): msg = msg.strip("=") msg_list = msg.rsplit("|") - elif msg.find("Log sensors") >= 0: - msg = msg.strip("{") - msg = msg.strip("}") - msg = msg.strip(".") - msg = msg.strip("=") - msg_list.append(msg) - - elif msg.find(",") >= 0 and not self.logToFile: + elif msg.find(",") >= 0: data_list = msg.rsplit(",") for i in range(len(data_list)): data_list[i] = float(data_list[i]) else: - print"msg error:" , msg +## print"msg error" pass if not self.plot: for i in range(len(self.nav_buttons)): @@ -609,8 +504,7 @@ def processIncoming(self): tiltlenumber = self.titles.index(tiltle) if tiltlenumber == 6: - self.rCQueue.put("no log") - self.logToFile = False + for button in self.main_buttons: button.grid_remove() self.titles=[] @@ -630,16 +524,7 @@ def processIncoming(self): self.main_buttons[i].grid() self.titles.append(comName) self.console1.grid() - elif tiltlenumber == 5: - self.plot = False - for i in range(len(self.main_buttons)): - self.main_buttons[i].configure(relief = tk.RAISED) - self.main_buttons[tiltlenumber].configure(relief = tk.RIDGE) - - else: - self.rCQueue.put("no log") - self.logToFile = False self.plot = False for i in range(len(self.main_buttons)): self.main_buttons[i].configure(relief = tk.RAISED) @@ -673,94 +558,10 @@ def processIncoming(self): self.scaleVar[i].set(self.ist_list[i]) self.nav_buttons[i].configure(text=comName, command= lambda i=i: self.send(self.command_list[i], self.scaleVar[i].get()/self.multiplier_list[i])) + except Queue.Empty: pass - if self.logToFile: - while self.lTfQueue.qsize(): - try: - msg = self.lTfQueue.get(0) - msg = msg.strip("\n") - msg = msg.strip("\r") - datalist = msg.rsplit(",") - self.write_csv(datetime.datetime.now(),datalist) -## print msg - msg = "" - except Queue.Empty: - pass - - if self.settingsToFile: - while self.sTfQueue.qsize(): - - try: - msg = self.sTfQueue.get(0) - msg = msg.strip("\n") - msg = msg.strip("\r") - settings_list = [] - - if msg.find("|") >= 0: - msg = msg.strip("{") - msg = msg.strip("}") - msg = msg.strip(".") - msg = msg.strip("=") - - msg_list = msg.rsplit("|") - - # Check contents of message and do what it says - for i in range(len(msg_list)-1): - if msg_list[i+1].find("~ ~") >= 0: - coma, comName, a, multiplier = msg_list[i+1].split("~") - comName, ist , maximum, minimum = comName.split("`") - tabubaltor = "\t" - descriptor = comName +" (maximum:"+ maximum + " minimum:"+ minimum + ") " + " X " + multiplier - numberOfTabs = int((75 - len(descriptor))/4)+1 - for j in range(numberOfTabs): tabubaltor += "\t" - setting = descriptor + tabubaltor + "|" + coma + "`" + ist - else: - coma, comName = msg_list[i+1].split("~") - tabubaltor = "\t" - descriptor = comName - numberOfTabs = int((75 - len(descriptor))/4)+1 - for j in range(numberOfTabs): tabubaltor += "\t" - setting = descriptor + tabubaltor + "|" + coma - - if msg_list[0].find("Settings") >= 0: - if (coma.find("sz") == -1) and (coma.find("sx") == -1): - comName = comName.upper() - self.mainSettingsName_list.append(comName) - self.mainSettingsComand_list.append(coma) - else: - if setting.find("\n") == -1: - settings_list.append(setting) - - if msg_list[0].find("Settings") >= 0: - self.snl_index = 0 - with open(self.settingsfname,"w") as settingsFile: - settingsFile.write("SETTINGS ARDUMOWER"+ time.strftime("%Y-%m-%d %H:%M:%S") + "\n\n\n\n") - else: - tabubaltor = "\t" - descriptor = self.mainSettingsName_list[self.snl_index] - numberOfTabs = int((75 - len(descriptor))/4)+1 - for j in range(numberOfTabs): tabubaltor += "\t" - mainSet = descriptor + tabubaltor + "|" + self.mainSettingsComand_list[self.snl_index] + "\n" - - with open(self.settingsfname,"a") as settingsFile: - settingsFile.write(mainSet) - for setting in settings_list: - settingsFile.write(setting + "\n") - settingsFile.write("\n\n\n") - self.snl_index += 1 - - if self.snl_index +1 <= (len(self.mainSettingsComand_list)): self.send(self.mainSettingsComand_list[self.snl_index]) - else: - self.rCQueue.put("not_settingsToFile") - self.settingsToFile = False - self.snl_index = 0 - - - except Queue.Empty: - pass - class GuiDebug(tk.Toplevel): def __init__(self, master, receive_connected_queue, sendQueue): tk.Toplevel.__init__(self) @@ -898,9 +699,6 @@ def __init__(self, master): self.init_Queue = Queue.Queue() self.receive_connected_queue = Queue.Queue() self.connected_queue = Queue.Queue() - self.saveToFile_Queue = Queue.Queue() - self.logToFile_Queue = Queue.Queue() - # Set up the GUI part def openDebug(): self.gui_Debug.deiconify() @@ -920,9 +718,7 @@ def hide_Com(): self.gui_com.withdraw() master.deiconify() - self.gui = GuiPart(master, self.received_queue, self.send_queue, - self.receive_connected_queue, self.saveToFile_Queue, self.logToFile_Queue, - self.endApplication, openDebug, openCom) + self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug, openCom) self.gui_Debug = GuiDebug(master, self.receive_connected_queue, self.send_queue) self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) self.gui_com = GuiConnect(master, self.init_Queue, self.close_com) @@ -1110,8 +906,6 @@ def receiveThread(self): connected = False sheepReply_checkbutton_var = False dataPlot_checkbutton_var = False - settings_toFile = False - logToFile = False while self.running: time.sleep(0.01) # To simulate asynchronous I/O, we create a random number at @@ -1120,6 +914,7 @@ def receiveThread(self): if self.receive_connected_queue.qsize(): try: # Check contents of message and do what it says + # msg = self.receive_connected_queue.get(0) ## print msg if msg == "connected": @@ -1131,16 +926,10 @@ def receiveThread(self): elif msg == "Sheep noDebug": sheepReply_checkbutton_var = False elif msg == "Data Debug": dataPlot_checkbutton_var = True elif msg == "Data noDebug": dataPlot_checkbutton_var = False - elif msg == "settings_toFile": settings_toFile = True - elif msg == "not_settingsToFile": settings_toFile = False - elif msg == "log": logToFile = True - elif msg == "no log": logToFile = False msg = "" - except Queue.Empty: pass - if connected and mower.inWaiting() != 0: try: @@ -1151,16 +940,12 @@ def receiveThread(self): self.receivedDebug_queue.put("Sheep debug: " + msg) msg = "" elif not msg.find("{")>= 0: - if not logToFile: self.received_queue.put(msg) - else: self.logToFile_Queue.put(msg) + self.received_queue.put(msg) if dataPlot_checkbutton_var == True: self.receivedDebug_queue.put("Plot data: " + msg) msg = "" elif msg.find("}")>= 0: - if settings_toFile: self.saveToFile_Queue.put(msg) -## elif logToFile: self.logToFile_Queue.put(msg) - else: self.received_queue.put(msg) - + self.received_queue.put(msg) if sheepReply_checkbutton_var == True: self.receivedDebug_queue.put("Sheep : " + msg) msg = "" except serial.SerialException: From deebe1b749ddbfe6bb09fa6fc3351dba099bb158 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sat, 12 Sep 2015 00:09:34 +0200 Subject: [PATCH 27/37] Revert "Revert "V15 new features added"" This reverts commit 641caed525b6fa1ed43c339054c228194a5094e0. --- ArdumowerDK.py | 283 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 249 insertions(+), 34 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 0a1bf66..01adab5 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -1,13 +1,13 @@ #------------------------------------------------------------------------------- # Name: Ardumower DK -# Purpose: Communication Ardumower - Windows computer via Bluetooth serial por +# Purpose: Communication Ardumower - Windows computer via Bluetooth serial port # # Author: Holoratte # -# Created: 27.08.2015 +# Created: 06.09.2015 # Copyright: (c) Holoratte 2015 # Licence: Just use it. Selling this software might be prohibited. -# Version: 14 +# Version: 15 #------------------------------------------------------------------------------- """ @@ -35,6 +35,7 @@ import Ringbuffer import serial import tkMessageBox +import tkFileDialog import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg @@ -43,31 +44,52 @@ from matplotlib.ticker import MultipleLocator, FormatStrFormatter import platform import serialenum +import csv +import datetime class GuiPart: - def __init__(self, master, receivedQueue, sendQueue, endCommand, Debug, Com): + def __init__(self, master, receivedQueue, sendQueue, receiveConnected_Queue, + saveToFile_Queue, logToFile_Queue, endCommand, Debug, Com): + self.master = master self.lastCommand = [] for i in range(100): self.lastCommand.append(".") - + self.settingsfname = "" + self.logFileName= "" + self.settingsToFile = False + self.settingsFromFile = False + self.logToFile = False + self.mainSettingsComand_list = [] + self.mainSettingsName_list = [] + self.snl_index = 0 + self.numberOfSetting = 0 + self.RQueue = receivedQueue + self.SQueue = sendQueue + self.sTfQueue = saveToFile_Queue + self.rCQueue = receiveConnected_Queue + self.lTfQueue = logToFile_Queue # Set up the GUI #---------------Menu-------------------------------------------- def donothing(): filewin = tk.Toplevel(master) - button = tk.Button(filewin, text="Do nothing button") + button = tk.Button(filewin, text="not yet implemented ;-(") + button.pack() + def showversion(): + filewin = tk.Toplevel(master) + button = tk.Button(filewin, text="ArdumowerDK V15") button.pack() menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff = 0) - filemenu.add_command(label="New", command=donothing) +## filemenu.add_command(label="New", command=donothing) ## filemenu.add_command(label="Open", command=donothing) ## filemenu.add_command(label="Save", command=donothing) ## filemenu.add_command(label="Save as...", command=donothing) ## filemenu.add_command(label="Close", command=donothing) ## - filemenu.add_separator() +## filemenu.add_separator() filemenu.add_command(label="Exit", command=endCommand) menubar.add_cascade(label="File", menu=filemenu) @@ -94,21 +116,23 @@ def donothing(): settingsmenu = tk.Menu(menubar, tearoff=0) settingsmenu.add_command(label="save", command=lambda: self.send("sz")) + settingsmenu.add_command(label="save to file", command= self.save_settings_toFile) + settingsmenu.add_command(label="load from file", command=donothing) +## settingsmenu.add_command(label="load from file", command=self.load_settings_fromFile) settingsmenu.add_command(label="load fatory settings", command=lambda: self.send("sx")) settingsmenu.add_command(label="Edit", command=lambda: self.send("s")) menubar.add_cascade(label="Settings", menu=settingsmenu) -## helpmenu = tk.Menu(menubar, tearoff=0) -## helpmenu.add_command(label="Help Index", command=donothing) -## helpmenu.add_command(label="About...", command=donothing) -## menubar.add_cascade(label="Help", menu=helpmenu) + helpmenu = tk.Menu(menubar, tearoff=0) + helpmenu.add_command(label="Help Index", command=donothing) + helpmenu.add_command(label="About...", command=showversion) + menubar.add_cascade(label="Help", menu=helpmenu) master.config(menu=menubar) #--------------------Buttons and scalebars---------------------------------------------- - self.RQueue = receivedQueue - self.SQueue = sendQueue + self.console1 = tk.Button(master, text='Main', command= self.mainmenu) self.console1.grid(column = 0, row =0) @@ -152,7 +176,7 @@ def donothing(): self.scale[i].grid_remove() # -----------------------------------Plot--------------------------- - self.canvasnumber =5 + self.canvasnumber =9 #number of subsubplots (1-9) self.plot = False self.channel = 0 self.f = Figure() @@ -202,7 +226,6 @@ def donothing(): a.set_xlabel("") a.set_xticks([]) - self.channel += 1 self.channel = 0 self.plotnumbers = [0] @@ -228,6 +251,57 @@ def donothing(): master.bind('', self.sendAutomode) + def create_csv(self): +## print'doing' + date= str(datetime.datetime.now().replace(microsecond=0)) + date, time= date.split() +## time , gmt= time.split('+') + + hh,mm,ss=time.split(':') + self.logFileName += "_" + date+' '+hh+'-'+mm+'-'+ss+'.csv' + with open(self.logFileName, "wb" ) as f: + writer = csv.writer(f) + writer.writerow( ("ARDUMOWER SENSOR LOG FILE") ) + return True +## print 'done' + + + def write_csv(self,datetime,data): + datetime=str(datetime.replace(microsecond=0)) + date, time= datetime.split() + if data[0].find("time") >= 0: + data.insert(0,"Time") + data.insert(0,"Date") + else: + data.insert(0,time) + data.insert(0,date) +## time , gmt= time.split('+') + try: + with open(self.logFileName, 'ab' ) as f: + writer = csv.writer(f, dialect='excel') + writer.writerow(data) + except: + print "cannot write so fast" + pass + + def save_settings_toFile(self,fname = ""): + if fname == "": fname = tkFileDialog.asksaveasfilename( title='Save to file', filetypes=[("Ardumower settings","*.ardm" ),],defaultextension="*.ardm") + if fname != "": + self.settingsfname = fname + msg = "settings_toFile" + self.settingsToFile = True + self.rCQueue.put(msg) + self.send("s") + + def load_settings_fromFile(self,fname = ""): + if fname == "": fname = tkFileDialog.askopenfilename( title='Load from file', filetypes=[("Ardumower settings","*.ardm" ),("all files", "*.*")],defaultextension="*.ardm") + if fname != "": + self.settingsfname = fname + msg = "settings_fromFile" + self.settingsFromFile = True + self.rCQueue.put(msg) + self.send("s") + def update_background(self,event): for i in range(len(self.backgrounds)): @@ -293,16 +367,40 @@ def sendAutomode(self,event): self.send("ra") def send(self, command, value = None): - - if value == None and command!= "sz" and command!= "sx": self.lastCommand.append(command) - if value != None: - if value == "back": - if len(self.lastCommand) >= 1: del self.lastCommand[-1] - elif value== "refresh": - pass + if command == "sx": + if tkMessageBox.askokcancel("Factory Reset", "Do You really want to reset all setting to factory default?"): + self.SQueue.put(command) + elif command == "sz": + if tkMessageBox.askokcancel("Save Setting", "Do You really want to save the settings to the eeprom?"): + self.SQueue.put(command) + elif command =="m1": + fname = "" + fname = tkFileDialog.asksaveasfilename( title='Save Sensor log to file', filetypes=[("comma separated value","*.csv" )]) + if fname != "": + self.logFileName = fname + if self.create_csv(): + self.rCQueue.put("log") + self.logToFile = True + self.SQueue.put(command) + else: + self.rCQueue.put("no log") + self.logToFile = False else: - command += "`" + str(value) - self.SQueue.put(command) + self.rCQueue.put("no log") + self.logToFile = False + + else: + self.rCQueue.put("no log") + self.logToFile = False + if value == None and command!= "sz" and command!= "sx": self.lastCommand.append(command) + if value != None: + if value == "back": + if len(self.lastCommand) >= 1: del self.lastCommand[-1] + elif value== "refresh": + pass + else: + command += "`" + str(value) + self.SQueue.put(command) def mainmenu(self): @@ -366,7 +464,7 @@ def processIncoming(self): try: msg = self.RQueue.get(0) # Check contents of message and do what it says - +## print "r msg: ",msg if msg.find("init") >= 0: msg.strip("init") init = True @@ -382,13 +480,20 @@ def processIncoming(self): msg = msg.strip("=") msg_list = msg.rsplit("|") + elif msg.find("Log sensors") >= 0: + msg = msg.strip("{") + msg = msg.strip("}") + msg = msg.strip(".") + msg = msg.strip("=") + msg_list.append(msg) + - elif msg.find(",") >= 0: + elif msg.find(",") >= 0 and not self.logToFile: data_list = msg.rsplit(",") for i in range(len(data_list)): data_list[i] = float(data_list[i]) else: -## print"msg error" + print"msg error:" , msg pass if not self.plot: for i in range(len(self.nav_buttons)): @@ -504,7 +609,8 @@ def processIncoming(self): tiltlenumber = self.titles.index(tiltle) if tiltlenumber == 6: - + self.rCQueue.put("no log") + self.logToFile = False for button in self.main_buttons: button.grid_remove() self.titles=[] @@ -524,7 +630,16 @@ def processIncoming(self): self.main_buttons[i].grid() self.titles.append(comName) self.console1.grid() + elif tiltlenumber == 5: + self.plot = False + for i in range(len(self.main_buttons)): + self.main_buttons[i].configure(relief = tk.RAISED) + self.main_buttons[tiltlenumber].configure(relief = tk.RIDGE) + + else: + self.rCQueue.put("no log") + self.logToFile = False self.plot = False for i in range(len(self.main_buttons)): self.main_buttons[i].configure(relief = tk.RAISED) @@ -558,10 +673,94 @@ def processIncoming(self): self.scaleVar[i].set(self.ist_list[i]) self.nav_buttons[i].configure(text=comName, command= lambda i=i: self.send(self.command_list[i], self.scaleVar[i].get()/self.multiplier_list[i])) - except Queue.Empty: pass + if self.logToFile: + while self.lTfQueue.qsize(): + try: + msg = self.lTfQueue.get(0) + msg = msg.strip("\n") + msg = msg.strip("\r") + datalist = msg.rsplit(",") + self.write_csv(datetime.datetime.now(),datalist) +## print msg + msg = "" + except Queue.Empty: + pass + + if self.settingsToFile: + while self.sTfQueue.qsize(): + + try: + msg = self.sTfQueue.get(0) + msg = msg.strip("\n") + msg = msg.strip("\r") + settings_list = [] + + if msg.find("|") >= 0: + msg = msg.strip("{") + msg = msg.strip("}") + msg = msg.strip(".") + msg = msg.strip("=") + + msg_list = msg.rsplit("|") + + # Check contents of message and do what it says + for i in range(len(msg_list)-1): + if msg_list[i+1].find("~ ~") >= 0: + coma, comName, a, multiplier = msg_list[i+1].split("~") + comName, ist , maximum, minimum = comName.split("`") + tabubaltor = "\t" + descriptor = comName +" (maximum:"+ maximum + " minimum:"+ minimum + ") " + " X " + multiplier + numberOfTabs = int((75 - len(descriptor))/4)+1 + for j in range(numberOfTabs): tabubaltor += "\t" + setting = descriptor + tabubaltor + "|" + coma + "`" + ist + else: + coma, comName = msg_list[i+1].split("~") + tabubaltor = "\t" + descriptor = comName + numberOfTabs = int((75 - len(descriptor))/4)+1 + for j in range(numberOfTabs): tabubaltor += "\t" + setting = descriptor + tabubaltor + "|" + coma + + if msg_list[0].find("Settings") >= 0: + if (coma.find("sz") == -1) and (coma.find("sx") == -1): + comName = comName.upper() + self.mainSettingsName_list.append(comName) + self.mainSettingsComand_list.append(coma) + else: + if setting.find("\n") == -1: + settings_list.append(setting) + + if msg_list[0].find("Settings") >= 0: + self.snl_index = 0 + with open(self.settingsfname,"w") as settingsFile: + settingsFile.write("SETTINGS ARDUMOWER"+ time.strftime("%Y-%m-%d %H:%M:%S") + "\n\n\n\n") + else: + tabubaltor = "\t" + descriptor = self.mainSettingsName_list[self.snl_index] + numberOfTabs = int((75 - len(descriptor))/4)+1 + for j in range(numberOfTabs): tabubaltor += "\t" + mainSet = descriptor + tabubaltor + "|" + self.mainSettingsComand_list[self.snl_index] + "\n" + + with open(self.settingsfname,"a") as settingsFile: + settingsFile.write(mainSet) + for setting in settings_list: + settingsFile.write(setting + "\n") + settingsFile.write("\n\n\n") + self.snl_index += 1 + + if self.snl_index +1 <= (len(self.mainSettingsComand_list)): self.send(self.mainSettingsComand_list[self.snl_index]) + else: + self.rCQueue.put("not_settingsToFile") + self.settingsToFile = False + self.snl_index = 0 + + + except Queue.Empty: + pass + class GuiDebug(tk.Toplevel): def __init__(self, master, receive_connected_queue, sendQueue): tk.Toplevel.__init__(self) @@ -699,6 +898,9 @@ def __init__(self, master): self.init_Queue = Queue.Queue() self.receive_connected_queue = Queue.Queue() self.connected_queue = Queue.Queue() + self.saveToFile_Queue = Queue.Queue() + self.logToFile_Queue = Queue.Queue() + # Set up the GUI part def openDebug(): self.gui_Debug.deiconify() @@ -718,7 +920,9 @@ def hide_Com(): self.gui_com.withdraw() master.deiconify() - self.gui = GuiPart(master, self.received_queue, self.send_queue, self.endApplication, openDebug, openCom) + self.gui = GuiPart(master, self.received_queue, self.send_queue, + self.receive_connected_queue, self.saveToFile_Queue, self.logToFile_Queue, + self.endApplication, openDebug, openCom) self.gui_Debug = GuiDebug(master, self.receive_connected_queue, self.send_queue) self.gui_Debug.protocol("WM_DELETE_WINDOW", hide_Debug) self.gui_com = GuiConnect(master, self.init_Queue, self.close_com) @@ -906,6 +1110,8 @@ def receiveThread(self): connected = False sheepReply_checkbutton_var = False dataPlot_checkbutton_var = False + settings_toFile = False + logToFile = False while self.running: time.sleep(0.01) # To simulate asynchronous I/O, we create a random number at @@ -914,7 +1120,6 @@ def receiveThread(self): if self.receive_connected_queue.qsize(): try: # Check contents of message and do what it says - # msg = self.receive_connected_queue.get(0) ## print msg if msg == "connected": @@ -926,10 +1131,16 @@ def receiveThread(self): elif msg == "Sheep noDebug": sheepReply_checkbutton_var = False elif msg == "Data Debug": dataPlot_checkbutton_var = True elif msg == "Data noDebug": dataPlot_checkbutton_var = False + elif msg == "settings_toFile": settings_toFile = True + elif msg == "not_settingsToFile": settings_toFile = False + elif msg == "log": logToFile = True + elif msg == "no log": logToFile = False msg = "" + except Queue.Empty: pass + if connected and mower.inWaiting() != 0: try: @@ -940,12 +1151,16 @@ def receiveThread(self): self.receivedDebug_queue.put("Sheep debug: " + msg) msg = "" elif not msg.find("{")>= 0: - self.received_queue.put(msg) + if not logToFile: self.received_queue.put(msg) + else: self.logToFile_Queue.put(msg) if dataPlot_checkbutton_var == True: self.receivedDebug_queue.put("Plot data: " + msg) msg = "" elif msg.find("}")>= 0: - self.received_queue.put(msg) + if settings_toFile: self.saveToFile_Queue.put(msg) +## elif logToFile: self.logToFile_Queue.put(msg) + else: self.received_queue.put(msg) + if sheepReply_checkbutton_var == True: self.receivedDebug_queue.put("Sheep : " + msg) msg = "" except serial.SerialException: From da39107c8f35116c55f685c09057dbc369f67a01 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sat, 12 Sep 2015 20:59:53 +0200 Subject: [PATCH 28/37] Pushalot Push-notification for windows phone --- Pushalot.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Pushalot.py diff --git a/Pushalot.py b/Pushalot.py new file mode 100644 index 0000000..6fee851 --- /dev/null +++ b/Pushalot.py @@ -0,0 +1,38 @@ + +from urllib import urlencode +from httplib import HTTPSConnection, HTTPException +from ssl import SSLError + + +def send(pushalot_authorizationtoken, pushalot_body = 'something happend', pushalot_title = 'Sheep Sheep'): + + pushalot_body = pushalot_body + pushalot_title = pushalot_title + http_handler = HTTPSConnection("pushalot.com") + data = {'AuthorizationToken': pushalot_authorizationtoken, + 'Title': pushalot_title.encode('utf-8'), + 'Body': pushalot_body.encode('utf-8') } + + try: + + http_handler.request("POST", + "/api/sendmessage", + headers = {'Content-type': "application/x-www-form-urlencoded"}, + body = urlencode(data)) + except (SSLError, HTTPException): + print("Pushalot notification failed.") + + response = http_handler.getresponse() + + + return response + + + + +# testing +if __name__ == '__main__': + send('xxxxxxxxxxx', "this is a test", "test") +## response = send('xxxxxxxxxxxxxxx', "this is a test", "test") +## print(response.status, response.reason) + From 05cead9e8e07b971f2d384cf84066450bd11725e Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sat, 12 Sep 2015 21:26:49 +0200 Subject: [PATCH 29/37] Windows phone Push notification service --- Pushalot.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Pushalot.py b/Pushalot.py index 6fee851..71467d1 100644 --- a/Pushalot.py +++ b/Pushalot.py @@ -6,8 +6,6 @@ def send(pushalot_authorizationtoken, pushalot_body = 'something happend', pushalot_title = 'Sheep Sheep'): - pushalot_body = pushalot_body - pushalot_title = pushalot_title http_handler = HTTPSConnection("pushalot.com") data = {'AuthorizationToken': pushalot_authorizationtoken, 'Title': pushalot_title.encode('utf-8'), From fb8c13b184d949f53bf654af3d483f157febcf6c Mon Sep 17 00:00:00 2001 From: Holoratte Date: Sat, 12 Sep 2015 23:57:26 +0200 Subject: [PATCH 30/37] Select all debug text --- ArdumowerDK.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 01adab5..03c2750 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -764,6 +764,9 @@ def processIncoming(self): class GuiDebug(tk.Toplevel): def __init__(self, master, receive_connected_queue, sendQueue): tk.Toplevel.__init__(self) + def selectall(event): + event.widget.tag_add("sel","1.0","end") + self.master = master self.title("Debug") self.geometry('+70+10') @@ -810,6 +813,7 @@ def getDebug(a,b,c): self.sheepReply_checkbutton_var.trace("w",getDebug) self.plotingdata_checkbutton_var.trace("w",getDebug) self.sheepSend_checkbutton_var.trace("w",getDebug) + self.master.bind_class("Text","", selectall) self.withdraw() class GuiConnect(tk.Toplevel): From 1081322436feeb1360d4cc3742deb58e473dcd13 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Mon, 14 Sep 2015 21:49:08 +0200 Subject: [PATCH 31/37] Workaround for unstable (high latency) wifi connection also changed encoding to "UTF-8" --- ArdumowerDK.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 8bc4881..3f118e1 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -498,7 +498,10 @@ def processIncoming(self): elif msg.find(",") >= 0 and not self.logToFile: data_list = msg.rsplit(",") for i in range(len(data_list)): - data_list[i] = float(data_list[i]) + try: + data_list[i] = float(data_list[i]) + except: + print( data_list[i] ) else: print( "msg error:" , msg ) pass @@ -583,7 +586,10 @@ def processIncoming(self): if self.timeSent: data_list = data_list[1:] for i in range(len(data_list)): - self.data_list[i].append(data_list[i]) + try: + self.data_list[i].append(data_list[i]) + except: + print ( data_list[i] ) self.datanumber +=1 try: if self.idle_flag and self.idle1_flag: @@ -1061,10 +1067,12 @@ def scan_comport(com_exclude): com_device, com = scan_comport(com_exclude) ## time.sleep(0.1) if com_device != "": - com_device.write(b"{.}") + com_device.write( b"{.}" ) + time.sleep(0.1) + com_device.write( b"\n" ) time.sleep(0.5) while com_device.inWaiting() != 0 and connected == False: - muC = com_device.readline().decode('ASCII') + muC = com_device.readline().decode('UTF-8') if muC.find("Ardumower") >= 0: print( "found Ardumower" ) self.Ardumower = com_device @@ -1088,10 +1096,12 @@ def scan_comport(com_exclude): elif msg != "": com_device = serial.Serial(msg, baudrate=19200, writeTimeout = 10000) if com_device != "": - com_device.write( b'{.}' ) + com_device.write( b"{.}" ) + time.sleep(0.1) + com_device.write( b"\n" ) time.sleep(0.5) while com_device.inWaiting() != 0 and connected == False: - muC = com_device.readline().decode('ASCII') + muC = com_device.readline().decode('UTF-8') if muC.find("Ardumower") >= 0: print( "found Ardumower" ) self.Ardumower = com_device @@ -1124,7 +1134,7 @@ def receiveThread(self): settings_toFile = False logToFile = False while self.running: - time.sleep(0.01) + time.sleep(0.005) # To simulate asynchronous I/O, we create a random number at # random intervals. Replace the following 2 lines with the real # thing. @@ -1155,7 +1165,7 @@ def receiveThread(self): if connected and mower.inWaiting() != 0: try: - msg += mower.readline().decode('ASCII') + msg += mower.readline().decode('UTF-8') if (msg.find("|") == -1) and (msg.find(",") == -1) and (msg.find("{") == -1) and (msg.find("}") == -1): @@ -1240,7 +1250,7 @@ def sendThread(self): elif connected: try: - mower.write( b'{' + msg.encode('ASCII') + b"}\n") + mower.write( b'{' + msg.encode('UTF-8') + b"}\n") if sheepSent_checkbutton_var == True: self.receivedDebug_queue.put("DK: "+ msg) except serial.SerialException: self.connected_queue.put("disconnected") From 735e2d99f678f4b1f51733bae85aa8962dd6fcd8 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Mon, 14 Sep 2015 22:06:40 +0200 Subject: [PATCH 32/37] some updates --- README.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 34a9ea3..fec859f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,21 @@ # ArdumowerDK -Bluetooth Serial Communication to Ardumower +Bluetooth/WIFI Serial Communication to Ardumower #Dependencies: - Win XP, Win Vista, Win 7, Win 8, Win 10, (Linux) + Win XP, Win Vista, Win 7, Win 8, Win 10, Linux Bluetooth Serial emulation *COM port installed (outgoing) - ArdumowerDK will scan all available comports and send {.}, - while listening to an "Ardumower" reply to determine if talking to Ardumower or not - if no Ardumower is found some debug messages (kind of simulation mode) - will be sent to the program and the plot will automatically load and plot some data. - No comport has to be set. - Python 2.7 32bit + WIFI serial connection + by using HW "VSP3 - Virtual Serial Port" + from http://www.hw-group.com/products/hw_vsp/index_en.html#download + Single-port version of HW VSP3 is available freely... + + ArdumowerDK will scan all available comports and send {.} (or you just choose one) + while listening to an "Ardumower" reply to determine if talking to Ardumower or not + + Python 2.7 32bit / Python 3 Pyserial Matplotlib @@ -38,6 +41,8 @@ Bluetooth Serial Communication to Ardumower it's now possible to save your mowers settings to ta txt file Timer settings are ignored + + #use at your own risk From 2b49c799858aae582e91a517837a9828e531a8e3 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Tue, 15 Sep 2015 01:02:39 +0200 Subject: [PATCH 33/37] settings file write encoded utf-8 --- ArdumowerDK.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 3f118e1..8c8e9eb 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -748,7 +748,7 @@ def processIncoming(self): if msg_list[0].find("Settings") >= 0: self.snl_index = 0 - with open(self.settingsfname,"w") as settingsFile: + with open(self.settingsfname, "w") as settingsFile: settingsFile.write("SETTINGS ARDUMOWER"+ time.strftime("%Y-%m-%d %H:%M:%S") + "\n\n\n\n") else: tabubaltor = "\t" @@ -760,6 +760,7 @@ def processIncoming(self): with open(self.settingsfname,"a") as settingsFile: settingsFile.write(mainSet) for setting in settings_list: + setting = setting.encode('utf-8') settingsFile.write(setting + "\n") settingsFile.write("\n\n\n") self.snl_index += 1 From a448c882f44d0c932d6581ff1de92206d8e86633 Mon Sep 17 00:00:00 2001 From: Holoratte Date: Tue, 15 Sep 2015 01:05:05 +0200 Subject: [PATCH 34/37] no need in this branch --- Pushalot.py | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 Pushalot.py diff --git a/Pushalot.py b/Pushalot.py deleted file mode 100644 index 71467d1..0000000 --- a/Pushalot.py +++ /dev/null @@ -1,36 +0,0 @@ - -from urllib import urlencode -from httplib import HTTPSConnection, HTTPException -from ssl import SSLError - - -def send(pushalot_authorizationtoken, pushalot_body = 'something happend', pushalot_title = 'Sheep Sheep'): - - http_handler = HTTPSConnection("pushalot.com") - data = {'AuthorizationToken': pushalot_authorizationtoken, - 'Title': pushalot_title.encode('utf-8'), - 'Body': pushalot_body.encode('utf-8') } - - try: - - http_handler.request("POST", - "/api/sendmessage", - headers = {'Content-type': "application/x-www-form-urlencoded"}, - body = urlencode(data)) - except (SSLError, HTTPException): - print("Pushalot notification failed.") - - response = http_handler.getresponse() - - - return response - - - - -# testing -if __name__ == '__main__': - send('xxxxxxxxxxx', "this is a test", "test") -## response = send('xxxxxxxxxxxxxxx', "this is a test", "test") -## print(response.status, response.reason) - From 17d6d6547536b6657701f5cdc3c9a421bcb5758d Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 8 May 2016 15:31:01 +0200 Subject: [PATCH 35/37] RF24 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index fec859f..8773073 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ Bluetooth/WIFI Serial Communication to Ardumower from http://www.hw-group.com/products/hw_vsp/index_en.html#download Single-port version of HW VSP3 is available freely... + nRF24 Modules connected to Arduino Uno's can be Interfaced using RF24 Branch of this repo and the RF24 Arduino librarry from TMRH20 + + ArdumowerDK will scan all available comports and send {.} (or you just choose one) while listening to an "Ardumower" reply to determine if talking to Ardumower or not From f6d51f9bab80e27c6a833dc11baf429ce0c71f7d Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 9 May 2016 16:38:30 +0200 Subject: [PATCH 36/37] cleanup --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8773073..221460b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ Bluetooth/WIFI Serial Communication to Ardumower from http://www.hw-group.com/products/hw_vsp/index_en.html#download Single-port version of HW VSP3 is available freely... - nRF24 Modules connected to Arduino Uno's can be Interfaced using RF24 Branch of this repo and the RF24 Arduino librarry from TMRH20 + nRF24 Modules connected to Arduino Uno's can be interfaced using + RF24 branch of this repo and the RF24 Arduino librarry from TMRH20 ArdumowerDK will scan all available comports and send {.} (or you just choose one) From dd73c3606eebc6084fe6017dd38c680df2e78cf3 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 15 Aug 2016 07:01:17 +0200 Subject: [PATCH 37/37] Bug Linux Debug Window --- ArdumowerDK.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArdumowerDK.py b/ArdumowerDK.py index 8c8e9eb..1ce8416 100644 --- a/ArdumowerDK.py +++ b/ArdumowerDK.py @@ -796,7 +796,7 @@ def selectall(event): self.debug_text.config(yscrollcommand=self.debug_text_scrollbar.set) self.debug_text_scrollbar.config(command=self.debug_text.yview) self.debug_text.grid(row=6,column=3,sticky="nesw") - self.debug_text_scrollbar.grid(row=6,column=3,sticky="nesw") + self.debug_text_scrollbar.grid(row=6,column=3,sticky="nes") def send_debug_command(): sendQueue.put(self.debug_entry_var.get()) self.sendbutton = tk.Button(self, text='Send', command= send_debug_command)