diff --git a/measurement.py b/measurement.py
index 852e794..529fda6 100644
--- a/measurement.py
+++ b/measurement.py
@@ -2,7 +2,7 @@ import os
class Measurement:
- def __init__(self, name, sensors, path=None, comment=None):
+ def __init__(self, name, path=None, comment=None):
self.name = name
self.path = os.path.join(path or "./meas_values", self.name)
os.makedirs(self.path)
@@ -18,8 +18,8 @@ class Measurement:
data: list of tuples: (timestamp, value)
"""
if sensor_name not in self.data_files:
- self.data_files[sensor_name] = open(os.path.join(self.path, f"{sensor_name}_data.csv"))
- for timestamp, value in data:
+ self.data_files[sensor_name] = open(os.path.join(self.path, f"{sensor_name}_data.csv"), "w")
+ for timestamp, value in zip(data[0], data[1]):
self.data_files[sensor_name].write(f"{timestamp.isoformat()}, {timestamp.timestamp()}, {value}\n")
def save_version_text(self, comment):
diff --git a/model.py b/model.py
index 19b5a68..a33ecaa 100644
--- a/model.py
+++ b/model.py
@@ -5,34 +5,58 @@ Data:
- dict with sensor data (temp, pressure, current)
- dict with drivers (magnetic field control)
"""
+from datetime import datetime
+from threading import Event, Thread
+from time import sleep
from sensor import Sensor
+from measurement import Measurement
+from plot_data import PlotData
+
+class DataGrabber(Thread):
+ def __init__(self, sensors, drivers, plot_data):
+ super().__init__()
+ self.measurement = None
+ self.sensors = sensors
+ self.drivers = drivers
+ self.plot_data = plot_data
+ self.exit_request = Event()
+
+ def run(self):
+ while not self.exit_request.is_set():
+ for name, sens in self.sensors.items():
+ dat = sens.get_data
+ self.plot_data.append_data(name,dat)
+ if self.measurement is not None:
+ self.measurement.append_data(name, dat)
+ sleep(1)
class Model:
def __init__(self):
+ self.plot_data = PlotData()
self.sensors = {"temp": Sensor(), "keks": Sensor()}
self.drivers = []
self.measurement = None
- self.plot_data = None
- pass
+ self.data_grabber = DataGrabber(self.sensors, self.drivers, self.plot_data)
+ self.data_grabber.start()
- def start_measuring(self):
- for sens in self.sensors.values():
- sens.start_measuring()
+ def start_measuring(self, meas_name=""):
+ name = meas_name or f"meas_{datetime.utcnow().isoformat().replace(':', '-')}"
+ self.measurement = Measurement(name)
+ self.data_grabber.measurement = self.measurement
def save_measuring(self, path="temp_temp.csv"):
- for sens in self.sensors.values():
- sens.save_measuring()
+ print("Has no use delete me maybe")
def stop_measuring(self):
- for sens in self.sensors.values():
- sens.stop_measuring()
+ self.measurement = None
+ self.data_grabber.measurement = None
def clear(self):
- for sens in self.sensors.values():
- sens.clear()
+ self.plot_data.clear()
def exit(self):
+ self.data_grabber.exit_request.set()
for sens in self.sensors.values():
sens.exit()
diff --git a/plot_data.py b/plot_data.py
index 3e8abfa..bf8f672 100644
--- a/plot_data.py
+++ b/plot_data.py
@@ -1,15 +1,21 @@
import numpy as np
-from datetime import datetime
+from datetime import datetime, timedelta
+
class PlotData():
def __init__(self):
- self.refresh_rate = 1 # ms
- self.timeout = 100 # cycles
+ self.refresh_rate = 1 # ms
+ self.timeout = 100 # cycles
self.data = {"time": np.array([0])}
self.start_time = datetime.utcnow()
self.queues = {}
+ def clear(self):
+ for key in self.data:
+ self.data[key] = np.array([])
+ def get(self, key):
+ return self.data.get(key, np.full_like(self.data["time"], np.nan, dtype=np.double))
def append_data(self, sensor_name, data):
"""
@@ -17,25 +23,37 @@ class PlotData():
"""
if sensor_name not in self.data:
self.queues[sensor_name] = []
- self.data[sensor_name] = np.full_like(self.data["time"], np.nan)
-
- for data_tuple in data.values():
- self.queues[sensor_name].append(data_tuple)
+ self.data[sensor_name] = np.full_like(self.data["time"], np.nan, dtype=np.double)
+ for time, dat in zip(data[0], data[1]):
+ self.queues[sensor_name].append((time, dat))
running = True
while running:
- #TODO timeout clean
+ # TODO timeout clean and time clean
+ for sensor, que in self.queues.items():
+ index = -1
+ for time, _ in que:
+ if time < self.start_time \
+ + timedelta(milliseconds=int(self.data["time"][-1]) + self.refresh_rate):
+ index += 1
+ if index >= 0:
+ self.queues[sensor] = que[index:]
+ #TODO timeout not working as intended
+ #if timeout is reached add empty values on sensors
+ #if self.start_time + timedelta(milliseconds=int(self.data["time"][-1])+self.timeout) < datetime.utcnow():
+ # for sensor, que in self.queues.items():
+ # if len(que) == 0:
+ # que.append((self.start_time,np.nan))
+
for que in self.queues.values():
if len(que) == 0:
running = False
- break
-
- for sensor,que in self.queues.items():
- self.data[sensor] = np.append(self.data[sensor], que[0])
- que = que[1:]
-
-
+ return
+ for sensor, que in self.queues.items():
+ self.data[sensor] = np.append(self.data[sensor], que[0][1])
+ self.queues[sensor] = que[1:]
+ self.data["time"] = np.append(self.data["time"],self.data["time"][-1]+self.refresh_rate)
"""
TODO
@@ -46,4 +64,3 @@ class PlotData():
return
update np array
"""
-
diff --git a/sensor.py b/sensor.py
index ca0e838..d2b1ca1 100644
--- a/sensor.py
+++ b/sensor.py
@@ -14,18 +14,16 @@ class SensorWorker(Thread):
self.message_queue = message_queue
self.produceData = Event()
self.exit_request = Event()
- self.file = open("temp.csv", "w")
def run(self):
""" Worker method of a python Thread. Called when the Thread is started. """
while not self.exit_request.is_set():
if self.produceData.is_set():
temp = random()
- ts = datetime.now()
+ ts = datetime.utcnow()
self.message_queue.put((ts, temp))
- self.file.write(f"{ts} - {temp}\n")
else:
- self.file.flush()
+ pass
sleep(1)
@@ -34,38 +32,44 @@ class Sensor(object):
def __init__(self):
super(Sensor, self).__init__()
- self.data = []
- self.t = []
self.measureQueue = Queue()
self.measureThread = SensorWorker(self.measureQueue)
self.measureThread.start()
+ self.measureThread.produceData.set()
+
def start_measuring(self):
self.measureThread.produceData.set()
print("I started meas")
- def save_measuring(self, path="temp_temp.csv"):
- print("I saved meas")
- np.savetxt(path, np.array(self.data))
def stop_measuring(self):
self.measureThread.produceData.clear()
print("I stopped meas")
- def clear(self):
- self.data = []
- self.t = []
- print("I cleared meas")
-
def exit(self):
self.stop_measuring()
self.measureThread.exit_request.set()
@property
def get_data(self):
+ time = []
+ val = []
while not self.measureQueue.empty():
t, data = self.measureQueue.get()
- self.data.append(data)
- self.t.append(t)
- print(self.data)
- return self.t, self.data
+ time.append(t)
+ val.append(data)
+ return time, val
+
+
+
+
+ # def clear(self):
+ # self.data = []
+ # self.t = []
+ # print("I cleared meas")
+ #
+ # def save_measuring(self, path="temp_temp.csv"):
+ # print("I saved meas")
+ # np.savetxt(path, np.array(self.data))
+
diff --git a/trial2/wxglade.wxg b/trial2/wxglade.wxg
new file mode 100644
index 0000000..3ec5da6
--- /dev/null
+++ b/trial2/wxglade.wxg
@@ -0,0 +1,190 @@
+
+
+
+
+
+
diff --git a/trial2/wxglade.wxg~ b/trial2/wxglade.wxg~
new file mode 100644
index 0000000..69defe0
--- /dev/null
+++ b/trial2/wxglade.wxg~
@@ -0,0 +1,174 @@
+
+
+
+
+
+ 474, 290
+ frame
+
+ 1
+
+
+
+ 2
+ 3
+ 0
+ 0
+
+ 2, 1
+ 0
+ wxEXPAND
+
+ wxVERTICAL
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+ 0
+ wxEXPAND
+
+
+
+ notebook_1_pane_1
+ notebook_1_pane_2
+ notebook_1_pane_3
+ notebook_1_pane_4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2, 1
+ 0
+ wxEXPAND
+
+ 2
+ 1
+ 10
+ 0
+
+ 0
+ wxEXPAND
+
+ 3
+ 1
+ 0
+ 0
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+ 0
+ wxEXPAND
+
+ 3
+ 1
+ 0
+ 0
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+ 0
+ wxEXPAND
+
+ 1
+ 3
+ 0
+ 0
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trial2/wxglade_out.py b/trial2/wxglade_out.py
new file mode 100644
index 0000000..6745c19
--- /dev/null
+++ b/trial2/wxglade_out.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+#
+# generated by wxGlade 1.0.2 on Sun Jul 4 21:29:50 2021
+#
+
+import wx
+
+# begin wxGlade: dependencies
+# end wxGlade
+
+# begin wxGlade: extracode
+# end wxGlade
+
+
+class MyFrame(wx.Frame):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: MyFrame.__init__
+ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
+ wx.Frame.__init__(self, *args, **kwds)
+ self.SetSize((1920, 1080))
+ self.SetTitle("frame")
+
+ # Menu Bar
+ self.frame_menubar = wx.MenuBar()
+ wxglade_tmp_menu = wx.Menu()
+ wxglade_tmp_menu.Append(wx.ID_ANY, "Quit", "")
+ self.frame_menubar.Append(wxglade_tmp_menu, "File")
+ self.SetMenuBar(self.frame_menubar)
+ # Menu Bar end
+
+ self.frame_statusbar = self.CreateStatusBar(1)
+ self.frame_statusbar.SetStatusWidths([-1])
+ # statusbar fields
+ frame_statusbar_fields = ["frame_statusbar"]
+ for i in range(len(frame_statusbar_fields)):
+ self.frame_statusbar.SetStatusText(frame_statusbar_fields[i], i)
+
+ # Tool Bar
+ self.frame_toolbar = wx.ToolBar(self, -1)
+ self.SetToolBar(self.frame_toolbar)
+ self.frame_toolbar.Realize()
+ # Tool Bar end
+
+ self.panel_1 = wx.Panel(self, wx.ID_ANY)
+
+ grid_sizer_1 = wx.GridBagSizer(0, 0)
+
+ sizer_1 = wx.BoxSizer(wx.VERTICAL)
+ grid_sizer_1.Add(sizer_1, (0, 0), (2, 1), wx.EXPAND, 0)
+
+ label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, "Text1")
+ sizer_1.Add(label_1, 0, 0, 0)
+
+ label_2 = wx.StaticText(self.panel_1, wx.ID_ANY, u"Für")
+ sizer_1.Add(label_2, 0, 0, 0)
+
+ label_3 = wx.StaticText(self.panel_1, wx.ID_ANY, "Statis")
+ sizer_1.Add(label_3, 0, 0, 0)
+
+ self.notebook_1 = wx.Notebook(self.panel_1, wx.ID_ANY)
+ grid_sizer_1.Add(self.notebook_1, (0, 1), (1, 1), wx.EXPAND, 0)
+
+ self.notebook_1_pane_1 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_1, "notebook_1_pane_1")
+
+ self.notebook_1_pane_2 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_2, "notebook_1_pane_2")
+
+ self.notebook_1_pane_3 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_3, "notebook_1_pane_3")
+
+ self.notebook_1_pane_4 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_4, "notebook_1_pane_4")
+
+ grid_sizer_3 = wx.GridBagSizer(10, 0)
+ grid_sizer_1.Add(grid_sizer_3, (0, 2), (2, 1), wx.EXPAND, 0)
+
+ grid_sizer_4 = wx.GridBagSizer(0, 0)
+ grid_sizer_3.Add(grid_sizer_4, (0, 0), (1, 1), wx.EXPAND, 0)
+
+ self.button_1 = wx.Button(self.panel_1, wx.ID_ANY, "button_1")
+ grid_sizer_4.Add(self.button_1, (0, 0), (1, 1), 0, 0)
+
+ self.button_2 = wx.Button(self.panel_1, wx.ID_ANY, "button_2")
+ grid_sizer_4.Add(self.button_2, (1, 0), (1, 1), 0, 0)
+
+ self.button_3 = wx.Button(self.panel_1, wx.ID_ANY, "button_3")
+ grid_sizer_4.Add(self.button_3, (2, 0), (1, 1), 0, 0)
+
+ grid_sizer_5 = wx.GridBagSizer(0, 0)
+ grid_sizer_3.Add(grid_sizer_5, (1, 0), (1, 1), wx.EXPAND, 0)
+
+ self.button_7 = wx.Button(self.panel_1, wx.ID_ANY, "button_7")
+ grid_sizer_5.Add(self.button_7, (0, 0), (1, 1), 0, 0)
+
+ self.button_8 = wx.Button(self.panel_1, wx.ID_ANY, "button_8")
+ grid_sizer_5.Add(self.button_8, (1, 0), (1, 1), 0, 0)
+
+ self.button_9 = wx.Button(self.panel_1, wx.ID_ANY, "button_9")
+ grid_sizer_5.Add(self.button_9, (2, 0), (1, 1), 0, 0)
+
+ grid_sizer_2 = wx.GridBagSizer(0, 0)
+ grid_sizer_1.Add(grid_sizer_2, (1, 1), (1, 1), wx.EXPAND, 0)
+
+ self.button_4 = wx.Button(self.panel_1, wx.ID_ANY, "button_4")
+ grid_sizer_2.Add(self.button_4, (0, 0), (1, 1), 0, 0)
+
+ self.button_5 = wx.Button(self.panel_1, wx.ID_ANY, "button_5")
+ grid_sizer_2.Add(self.button_5, (0, 1), (1, 1), 0, 0)
+
+ self.button_6 = wx.Button(self.panel_1, wx.ID_ANY, "button_6")
+ grid_sizer_2.Add(self.button_6, (0, 2), (1, 1), 0, 0)
+
+ self.panel_1.SetSizer(grid_sizer_1)
+
+ self.Layout()
+
+ # end wxGlade
+
+ def test(self, event): # wxGlade: MyFrame.
+ print("Event handler 'test' not implemented!")
+ event.Skip()
+
+# end of class MyFrame
+
+class MyApp(wx.App):
+ def OnInit(self):
+ self.frame = MyFrame(None, wx.ID_ANY, "")
+ self.SetTopWindow(self.frame)
+ self.frame.Show()
+ return True
+
+# end of class MyApp
+
+if __name__ == "__main__":
+ app = MyApp(0)
+ app.MainLoop()
diff --git a/trial2/wxglade_out.py~ b/trial2/wxglade_out.py~
new file mode 100644
index 0000000..25b140a
--- /dev/null
+++ b/trial2/wxglade_out.py~
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+# -*- coding: UTF-8 -*-
+#
+# generated by wxGlade 1.0.2 on Sun Jul 4 21:20:06 2021
+#
+
+import wx
+
+# begin wxGlade: dependencies
+# end wxGlade
+
+# begin wxGlade: extracode
+# end wxGlade
+
+
+class MyFrame(wx.Frame):
+ def __init__(self, *args, **kwds):
+ # begin wxGlade: MyFrame.__init__
+ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
+ wx.Frame.__init__(self, *args, **kwds)
+ self.SetSize((474, 290))
+ self.SetTitle("frame")
+
+ # Menu Bar
+ self.frame_menubar = wx.MenuBar()
+ self.SetMenuBar(self.frame_menubar)
+ # Menu Bar end
+
+ self.panel_1 = wx.Panel(self, wx.ID_ANY)
+
+ grid_sizer_1 = wx.GridBagSizer(0, 0)
+
+ sizer_1 = wx.BoxSizer(wx.VERTICAL)
+ grid_sizer_1.Add(sizer_1, (0, 0), (2, 1), wx.EXPAND, 0)
+
+ label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, "Text1")
+ sizer_1.Add(label_1, 0, 0, 0)
+
+ label_2 = wx.StaticText(self.panel_1, wx.ID_ANY, u"Für")
+ sizer_1.Add(label_2, 0, 0, 0)
+
+ label_3 = wx.StaticText(self.panel_1, wx.ID_ANY, "Statis")
+ sizer_1.Add(label_3, 0, 0, 0)
+
+ self.notebook_1 = wx.Notebook(self.panel_1, wx.ID_ANY)
+ grid_sizer_1.Add(self.notebook_1, (0, 1), (1, 1), wx.EXPAND, 0)
+
+ self.notebook_1_pane_1 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_1, "notebook_1_pane_1")
+
+ self.notebook_1_pane_2 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_2, "notebook_1_pane_2")
+
+ self.notebook_1_pane_3 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_3, "notebook_1_pane_3")
+
+ self.notebook_1_pane_4 = wx.Panel(self.notebook_1, wx.ID_ANY)
+ self.notebook_1.AddPage(self.notebook_1_pane_4, "notebook_1_pane_4")
+
+ grid_sizer_3 = wx.GridBagSizer(10, 0)
+ grid_sizer_1.Add(grid_sizer_3, (0, 2), (2, 1), wx.EXPAND, 0)
+
+ grid_sizer_4 = wx.GridBagSizer(0, 0)
+ grid_sizer_3.Add(grid_sizer_4, (0, 0), (1, 1), wx.EXPAND, 0)
+
+ self.button_1 = wx.Button(self.panel_1, wx.ID_ANY, "button_1")
+ grid_sizer_4.Add(self.button_1, (0, 0), (1, 1), 0, 0)
+
+ self.button_2 = wx.Button(self.panel_1, wx.ID_ANY, "button_2")
+ grid_sizer_4.Add(self.button_2, (1, 0), (1, 1), 0, 0)
+
+ self.button_3 = wx.Button(self.panel_1, wx.ID_ANY, "button_3")
+ grid_sizer_4.Add(self.button_3, (2, 0), (1, 1), 0, 0)
+
+ grid_sizer_5 = wx.GridBagSizer(0, 0)
+ grid_sizer_3.Add(grid_sizer_5, (1, 0), (1, 1), wx.EXPAND, 0)
+
+ self.button_7 = wx.Button(self.panel_1, wx.ID_ANY, "button_7")
+ grid_sizer_5.Add(self.button_7, (0, 0), (1, 1), 0, 0)
+
+ self.button_8 = wx.Button(self.panel_1, wx.ID_ANY, "button_8")
+ grid_sizer_5.Add(self.button_8, (1, 0), (1, 1), 0, 0)
+
+ self.button_9 = wx.Button(self.panel_1, wx.ID_ANY, "button_9")
+ grid_sizer_5.Add(self.button_9, (2, 0), (1, 1), 0, 0)
+
+ grid_sizer_2 = wx.GridBagSizer(0, 0)
+ grid_sizer_1.Add(grid_sizer_2, (1, 1), (1, 1), wx.EXPAND, 0)
+
+ self.button_4 = wx.Button(self.panel_1, wx.ID_ANY, "button_4")
+ grid_sizer_2.Add(self.button_4, (0, 0), (1, 1), 0, 0)
+
+ self.button_5 = wx.Button(self.panel_1, wx.ID_ANY, "button_5")
+ grid_sizer_2.Add(self.button_5, (0, 1), (1, 1), 0, 0)
+
+ self.button_6 = wx.Button(self.panel_1, wx.ID_ANY, "button_6")
+ grid_sizer_2.Add(self.button_6, (0, 2), (1, 1), 0, 0)
+
+ self.panel_1.SetSizer(grid_sizer_1)
+
+ self.Layout()
+ # end wxGlade
+
+# end of class MyFrame
+
+class MyApp(wx.App):
+ def OnInit(self):
+ self.frame = MyFrame(None, wx.ID_ANY, "")
+ self.SetTopWindow(self.frame)
+ self.frame.Show()
+ return True
+
+# end of class MyApp
+
+if __name__ == "__main__":
+ app = MyApp(0)
+ app.MainLoop()
diff --git a/view.py b/view.py
index 93da7d1..771e9ba 100644
--- a/view.py
+++ b/view.py
@@ -53,8 +53,8 @@ class PlotPanel(wx.Panel):
def init_plot_data(self):
self.ax = self.fig.add_subplot()
self.fig.legend()
- self.x, self.y = self.model.sensors["temp"].get_data
- (self.im,) = self.ax.plot(self.x, self.y, "-.",label="temp")
+ dat = self.model.plot_data
+ (self.im,) = self.ax.plot(dat.get("time"), dat.get("temp"), "-.",label="temp")
self.toolbar.update() # Not sure why this is needed - ADS
def get_toolbar(self):
@@ -63,9 +63,10 @@ class PlotPanel(wx.Panel):
return self.toolbar
def on_paint(self, event):
- self.x, self.y = self.model.sensors["temp"].get_data
+ dat = self.model.plot_data.data
# print(self.x)
- self.im.set_data(self.x, self.y)
+
+ self.im.set_data(dat.get("time"), dat.get("temp"))
self.ax.relim()
self.ax.autoscale_view()
self.canvas.draw()