From 290fb94a9d788e92b3110b3859b13fd3631c9770 Mon Sep 17 00:00:00 2001 From: Kienan Stewart Date: Wed, 10 Dec 2014 17:22:52 -0500 Subject: [PATCH] initial pass at having a ui update at regular intervales --- main.kv | 21 ++++++++++++++++ main.py | 72 +++++++++++++++++++++++++++++++++++++++++++++-------- temp_log.py | 44 +++++++++++++++++++++++++++++--- 3 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 main.kv diff --git a/main.kv b/main.kv new file mode 100644 index 0000000..f533aa0 --- /dev/null +++ b/main.kv @@ -0,0 +1,21 @@ +: + text: 'Current Temperature: n/a' +# on_lastTemperature: self.update_current_temperature_label() + +: + label_wid: "Temperature Monitor" + BoxLayout: + orientation: 'vertical' + BoxLayout: + size_hint_y: 0.1 + orientation: 'horizontal' + MyLabel: + id: 'current_temperature' + Button: + text: 'Start/Stop' + Label: + text: 'No File Chosen' + Label: + text: 'Data Source' + Label: + text: 'Graph placeholder' diff --git a/main.py b/main.py index 72478fa..b681894 100644 --- a/main.py +++ b/main.py @@ -1,21 +1,71 @@ import kivy from kivy.app import App -from kivy.uix.label import Label +from kivy.clock import Clock +from kivy.logger import Logger +from kivy.properties import ObjectProperty, StringProperty from kivy.uix.boxlayout import BoxLayout +from kivy.uix.floatlayout import FloatLayout +from kivy.uix.label import Label +import kivy.lang +import Queue +import temp_log +import threading -class MyApp(App): +dataThread = None +dataThreadDataQueue = Queue.Queue() +dataThreadCommandQueue = Queue.Queue() + +class MainApp(App): def build(self): - return Label(text=unicode('Temperature Logger')) + mainWindow = MainWindow() + Clock.schedule_interval(mainWindow.update_last_temperature, 0.25) + return mainWindow -class MainScreen(BoxLayout): - def __init__(self, **kwargs): - super(MainScreen, self).__init__(**kwargs) - self.orientation = 'vertical' - top = new BoxLayout(orientation = 'horizontal') - self.add_widget(top) - pass + def on_stop(self): + global dataThreadCommandQueue + dataThreadCommandQueue.put_nowait('stop') + + + def on_start(self): + global dataThread + dataThread.start() + + +class MainWindow(FloatLayout): + """Main Window class""" + dataSource = StringProperty('/dev/ttyACM0') + lastTemperature = StringProperty('n/a') + + def update_last_temperature(self, dt): + global dataThreadDataQueue + # This breaks if there are more updates in the queue than the frequency of update_last_temperature - it pulls old data out of the queue, and not the most recent. + try: + data = dataThreadDataQueue.get_nowait() + if data is not None: + self.lastTemperature = str(data['data']['temperature']) + except Queue.Empty: + pass + + def on_lastTemperature(self, instance, value): + Logger.debug('lastTemperature has changed to: ' + str(value)) + children = self.children[:] + while children: + child = children.pop() + try: + child.on_lastTemperature(instance, value) + except Exception, e: + pass + children.extend(child.children) + + +class MyLabel(Label): + + def on_lastTemperature(self, instance, value): + self.text = 'Current temperature: ' + str(value) + if __name__ == '__main__': - MyApp().run() + dataThread = threading.Thread(None, temp_log.threaded_reader, None, ['/dev/ttyACM0', dataThreadDataQueue, dataThreadCommandQueue]) + MainApp().run() diff --git a/temp_log.py b/temp_log.py index e98fa62..a8e8cfb 100755 --- a/temp_log.py +++ b/temp_log.py @@ -1,5 +1,10 @@ #! /usr/bin/env python -import serial, sys, time, io +import io +import Queue +import serial +import sys +import threading +import time defaultSerialPort = '/dev/ttyACM0' defaultVersion = 0 @@ -14,12 +19,42 @@ def parse_line(line, version = defaultVersion): data = {} if (version == 0): line = line.split(' ') - data['temperature'] = float(line[-2]) + try: + data['temperature'] = float(line[-2]) + except Exception, e: + pass else: raise ParseException('Unimplemented line version', version) return data +def threaded_reader(source, dataQueue, commandQueue): + import kivy.logger + ser = serial.Serial(source, baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS) + sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) + ser.isOpen() + buffer = '' + runTime = '' + cmd = '' + while True: + try: + cmd = commandQueue.get_nowait() + except Queue.Empty: + pass + if cmd == 'stop': + break + try: + data = parse_line(ser.readline(), defaultVersion) + runTime = time.time() + except Exception, e: + kivy.logger.Logger.exception(e) + continue + if data and runTime: + item = {'time' : runTime, 'data' : data} + kivy.logger.Logger.debug(str(item)) + dataQueue.put(item) + + def main(args = sys.argv): # @TODO switch to parse args or similar # @TODO parse of temperature logger line version @@ -37,8 +72,9 @@ def main(args = sys.argv): try: buffer = ser.readline() data = parse_line(buffer, lineVersion) - print unicode(time.time()) + ',' + unicode(data['temperature']) - sys.stdout.flush() + if data: + print unicode(time.time()) + ',' + unicode(data['temperature']) + sys.stdout.flush() except Exception, e: sys.stderr.write(str(e) + '\n') continue