Group models meta model, execute script
This commit is contained in:
parent
323572fd99
commit
9ea39f4f54
71
measurement.py
Normal file
71
measurement.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import numpy as np
|
||||||
|
from datetime import datetime
|
||||||
|
from threading import Thread, Event
|
||||||
|
from time import sleep, time
|
||||||
|
from queue import Queue
|
||||||
|
from random import random
|
||||||
|
|
||||||
|
|
||||||
|
class MeasureWork(Thread):
|
||||||
|
""" Communicates with the measuring hardware. Here we only produce random data. """
|
||||||
|
|
||||||
|
def __init__(self, message_queue):
|
||||||
|
super().__init__(name="Measure")
|
||||||
|
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()
|
||||||
|
self.message_queue.put((ts, temp))
|
||||||
|
self.file.write(f"{ts} - {temp}\n")
|
||||||
|
else:
|
||||||
|
self.file.flush()
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
class Measurement(object):
|
||||||
|
"""docstring for Model."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(Measurement, self).__init__()
|
||||||
|
self.data = []
|
||||||
|
self.t = []
|
||||||
|
self.measureQueue = Queue()
|
||||||
|
self.measureThread = MeasureWork(self.measureQueue)
|
||||||
|
self.measureThread.start()
|
||||||
|
|
||||||
|
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):
|
||||||
|
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
|
96
model.py
96
model.py
@ -1,63 +1,51 @@
|
|||||||
import numpy as np
|
"""
|
||||||
from datetime import datetime
|
API for scripting measurements and drivers
|
||||||
from threading import Thread, Event
|
|
||||||
from time import sleep, time
|
Data:
|
||||||
from queue import Queue
|
- dict with sensor data (temp, pressure, current)
|
||||||
from random import random
|
- dict with drivers (magnetic field control)
|
||||||
|
"""
|
||||||
|
from measurement import Measurement
|
||||||
|
|
||||||
|
|
||||||
class MeasureWork(Thread):
|
class Model:
|
||||||
def __init__(self, message_queue):
|
|
||||||
super().__init__(name="Measure")
|
|
||||||
self.message_queue = message_queue
|
|
||||||
self.produceData = Event()
|
|
||||||
self.file = open("temp.csv", "w")
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
if self.produceData.is_set():
|
|
||||||
temp = random()
|
|
||||||
ts = datetime.now()
|
|
||||||
self.message_queue.put((ts, temp))
|
|
||||||
self.file.write(f"{ts} - {temp}\n")
|
|
||||||
else:
|
|
||||||
self.file.flush()
|
|
||||||
sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
class Model(object):
|
|
||||||
"""docstring for Model."""
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Model, self).__init__()
|
self.sensors = {"temp": Measurement()}
|
||||||
self.data = []
|
self.drivers = []
|
||||||
self.t = []
|
pass
|
||||||
self.measureQueue = Queue()
|
|
||||||
self.measureThread = MeasureWork(self.measureQueue)
|
|
||||||
self.measureThread.start()
|
|
||||||
|
|
||||||
def startMeasureing(self):
|
def start_measuring(self):
|
||||||
self.measureThread.produceData.set()
|
for sens in self.sensors.values():
|
||||||
print("I started meas")
|
sens.start_measuring()
|
||||||
|
|
||||||
def saveMeasureing(self, path='temp_temp.csv'):
|
def save_measuring(self, path="temp_temp.csv"):
|
||||||
print("I saved meas")
|
for sens in self.sensors.values():
|
||||||
np.savetxt(path, np.array(self.data))
|
sens.save_measuring()
|
||||||
|
|
||||||
def stopMeasureing(self):
|
def stop_measuring(self):
|
||||||
self.measureThread.produceData.clear()
|
for sens in self.sensors.values():
|
||||||
print("I started meas")
|
sens.stop_measuring()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.data = []
|
for sens in self.sensors.values():
|
||||||
self.t = []
|
sens.clear()
|
||||||
print("I started meas")
|
|
||||||
|
|
||||||
@property
|
def exit(self):
|
||||||
def getData(self):
|
for sens in self.sensors.values():
|
||||||
while not self.measureQueue.empty():
|
sens.exit()
|
||||||
t, data = self.measureQueue.get()
|
|
||||||
self.data.append(data)
|
|
||||||
self.t.append(t)
|
"""
|
||||||
print(self.data)
|
init()
|
||||||
return self.t, self.data
|
sensoren = []
|
||||||
|
|
||||||
|
|
||||||
|
for mag in range(10):
|
||||||
|
drive_to_value("MagnetFelied1", mag)
|
||||||
|
start_measuring("volt", "filename")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
17
my_control_script.py
Normal file
17
my_control_script.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from time import sleep
|
||||||
|
import model
|
||||||
|
|
||||||
|
|
||||||
|
def main(param_model):
|
||||||
|
param_model.start_measuring()
|
||||||
|
with open("script_output.log", "w") as my_file:
|
||||||
|
for i in range(20):
|
||||||
|
sleep(0.5)
|
||||||
|
x, y = param_model.sensors["temp"].get_data
|
||||||
|
my_file.write(f"x: {x}, y: {y}\n")
|
||||||
|
param_model.stop_measuring()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("wrong call")
|
||||||
|
# main(model.Model())
|
@ -3,7 +3,8 @@
|
|||||||
#
|
#
|
||||||
# generated by wxGlade 1.0.2 on Sun Jun 20 19:31:43 2021
|
# generated by wxGlade 1.0.2 on Sun Jun 20 19:31:43 2021
|
||||||
#
|
#
|
||||||
|
import importlib.machinery
|
||||||
|
from threading import Thread
|
||||||
import wx
|
import wx
|
||||||
from model import Model
|
from model import Model
|
||||||
|
|
||||||
@ -38,23 +39,25 @@ class PlotPanel(wx.Panel):
|
|||||||
sizer.Add(self.toolbar, 0, wx.GROW)
|
sizer.Add(self.toolbar, 0, wx.GROW)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
self.Fit()
|
self.Fit()
|
||||||
self.Bind(wx.EVT_PAINT, self.OnPaint, self)
|
self.Bind(wx.EVT_PAINT, self.on_paint, self)
|
||||||
|
self.ax = None
|
||||||
|
self.im = None
|
||||||
self.init_plot_data()
|
self.init_plot_data()
|
||||||
|
self.x = self.y = None
|
||||||
|
|
||||||
def init_plot_data(self):
|
def init_plot_data(self):
|
||||||
self.ax = self.fig.add_subplot()
|
self.ax = self.fig.add_subplot()
|
||||||
self.x, self.y = self.model.getData
|
self.x, self.y = self.model.sensors["temp"].get_data
|
||||||
(self.im,) = self.ax.plot(self.x, self.y, "-.")
|
(self.im,) = self.ax.plot(self.x, self.y, "-.")
|
||||||
self.toolbar.update() # Not sure why this is needed - ADS
|
self.toolbar.update() # Not sure why this is needed - ADS
|
||||||
|
|
||||||
def GetToolBar(self):
|
def get_toolbar(self):
|
||||||
# You will need to override GetToolBar if you are using an
|
# You will need to override GetToolBar if you are using an
|
||||||
# unmanaged toolbar in your frame
|
# unmanaged toolbar in your frame
|
||||||
return self.toolbar
|
return self.toolbar
|
||||||
|
|
||||||
def OnPaint(self, event):
|
def on_paint(self, event):
|
||||||
print("Paint")
|
self.x, self.y = self.model.sensors["temp"].get_data
|
||||||
self.x, self.y = self.model.getData
|
|
||||||
# print(self.x)
|
# print(self.x)
|
||||||
self.im.set_data(self.x, self.y)
|
self.im.set_data(self.x, self.y)
|
||||||
self.ax.relim()
|
self.ax.relim()
|
||||||
@ -70,7 +73,7 @@ class MyFrame(wx.Frame):
|
|||||||
|
|
||||||
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
|
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
|
||||||
wx.Frame.__init__(self, *args, **kwds)
|
wx.Frame.__init__(self, *args, **kwds)
|
||||||
self.SetSize((400, 300))
|
self.SetSize((500, 400))
|
||||||
self.SetTitle("frame")
|
self.SetTitle("frame")
|
||||||
|
|
||||||
self.panel_1 = wx.Panel(self, wx.ID_ANY)
|
self.panel_1 = wx.Panel(self, wx.ID_ANY)
|
||||||
@ -86,9 +89,12 @@ class MyFrame(wx.Frame):
|
|||||||
self.b_clear = wx.Button(self.panel_1, wx.ID_ANY, "Clear")
|
self.b_clear = wx.Button(self.panel_1, wx.ID_ANY, "Clear")
|
||||||
grid_sizer_1.Add(self.b_clear, (0, 2), (1, 1), 0, 0)
|
grid_sizer_1.Add(self.b_clear, (0, 2), (1, 1), 0, 0)
|
||||||
|
|
||||||
self.b_save = wx.Button(self.panel_1, wx.ID_ANY, "Speichern")
|
self.b_save = wx.Button(self.panel_1, wx.ID_ANY, "Save")
|
||||||
grid_sizer_1.Add(self.b_save, (0, 3), (1, 1), 0, 0)
|
grid_sizer_1.Add(self.b_save, (0, 3), (1, 1), 0, 0)
|
||||||
|
|
||||||
|
self.b_run = wx.Button(self.panel_1, wx.ID_ANY, "Run")
|
||||||
|
grid_sizer_1.Add(self.b_run, (0, 4), (1, 1), 0, 0)
|
||||||
|
|
||||||
self.plot = PlotPanel(self.panel_1, self.model)
|
self.plot = PlotPanel(self.panel_1, self.model)
|
||||||
self.plot.SetMinSize((300, 300))
|
self.plot.SetMinSize((300, 300))
|
||||||
grid_sizer_1.Add(self.plot, (1, 0), (1, 3), wx.EXPAND, 0)
|
grid_sizer_1.Add(self.plot, (1, 0), (1, 3), wx.EXPAND, 0)
|
||||||
@ -100,24 +106,44 @@ class MyFrame(wx.Frame):
|
|||||||
self.timer = wx.Timer(self, wx.ID_ANY)
|
self.timer = wx.Timer(self, wx.ID_ANY)
|
||||||
self.Layout()
|
self.Layout()
|
||||||
|
|
||||||
self.Bind(wx.EVT_BUTTON, self.onBstart, self.b_start)
|
self.Bind(wx.EVT_CLOSE, self.on_close_window)
|
||||||
self.Bind(wx.EVT_BUTTON, self.offBstop, self.b_stop)
|
self.Bind(wx.EVT_BUTTON, self.on_b_start, self.b_start)
|
||||||
self.Bind(wx.EVT_BUTTON, self.delBclear, self.b_clear)
|
self.Bind(wx.EVT_BUTTON, self.on_b_stop, self.b_stop)
|
||||||
self.Bind(wx.EVT_BUTTON, self.onBsave, self.b_save)
|
self.Bind(wx.EVT_BUTTON, self.on_b_clear, self.b_clear)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.on_b_save, self.b_save)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.on_b_run, self.b_run)
|
||||||
self.Bind(wx.EVT_TIMER, self.update, self.timer)
|
self.Bind(wx.EVT_TIMER, self.update, self.timer)
|
||||||
self.timer.Start(100, False)
|
self.timer.Start(100, False)
|
||||||
|
self.runner_thread = None
|
||||||
# end wxGlade
|
# end wxGlade
|
||||||
|
|
||||||
|
def on_close_window(self, event):
|
||||||
|
self.model.exit()
|
||||||
|
print("Closing")
|
||||||
|
wx.Exit()
|
||||||
|
|
||||||
def update(self, event):
|
def update(self, event):
|
||||||
self.plot.Refresh()
|
self.plot.Refresh()
|
||||||
|
if self.runner_thread is not None:
|
||||||
|
if not self.runner_thread.is_alive():
|
||||||
|
self.unlock()
|
||||||
|
self.runner_thread = None
|
||||||
|
|
||||||
def onBstart(self, event): # wxGlade: MyFrame.<event_handler>
|
def lock(self):
|
||||||
print("Event handler 'onBstart'")
|
self.b_run.Disable()
|
||||||
self.model.startMeasureing()
|
self.b_start.Disable()
|
||||||
|
|
||||||
|
def unlock(self):
|
||||||
|
self.b_run.Enable()
|
||||||
|
self.b_start.Enable()
|
||||||
|
|
||||||
|
def on_b_start(self, event): # wxGlade: MyFrame.<event_handler>
|
||||||
|
print("Event handler 'on_b_start'")
|
||||||
|
self.model.start_measuring()
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def onBsave(self, event): # wxGlade: MyFrame.<event_handler>
|
def on_b_save(self, event): # wxGlade: MyFrame.<event_handler>
|
||||||
print("Event handler 'onBsave'")
|
print("Event handler 'on_b_save'")
|
||||||
with wx.FileDialog(
|
with wx.FileDialog(
|
||||||
self,
|
self,
|
||||||
"Save csv file",
|
"Save csv file",
|
||||||
@ -130,17 +156,33 @@ class MyFrame(wx.Frame):
|
|||||||
|
|
||||||
# save the current contents in the file
|
# save the current contents in the file
|
||||||
pathname = fileDialog.GetPath()
|
pathname = fileDialog.GetPath()
|
||||||
self.model.saveMeasureing(path=pathname)
|
self.model.save_measuring(path=pathname)
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def offBstop(self, event): # wxGlade: MyFrame.<event_handler>
|
def on_b_run(self, event): # wxGlade: MyFrame.<event_handler>
|
||||||
self.model.stopMeasureing()
|
print("Event handler 'on_b_run'")
|
||||||
print("Event handler 'offBstop'")
|
with wx.FileDialog(self, "Open PY file", wildcard="PY files (*.py)|*.py",
|
||||||
|
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
|
||||||
|
|
||||||
|
if fileDialog.ShowModal() == wx.ID_CANCEL:
|
||||||
|
return # the user changed their mind
|
||||||
|
|
||||||
|
# Proceed loading the file chosen by the user
|
||||||
|
pathname = fileDialog.GetPath()
|
||||||
|
script = importlib.machinery.SourceFileLoader("ghf", pathname).load_module()
|
||||||
|
self.runner_thread = Thread(target=script.main, args=(self.model,))
|
||||||
|
self.lock()
|
||||||
|
self.runner_thread.start()
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def delBclear(self, event): # wxGlade: MyFrame.<event_handler>
|
def on_b_stop(self, event): # wxGlade: MyFrame.<event_handler>
|
||||||
|
self.model.stop_measuring()
|
||||||
|
print("Event handler 'on_b_stop'")
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
def on_b_clear(self, event): # wxGlade: MyFrame.<event_handler>
|
||||||
self.model.clear()
|
self.model.clear()
|
||||||
print("Event handler 'delBclear'")
|
print("Event handler 'on_b_clear'")
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +190,10 @@ class MyFrame(wx.Frame):
|
|||||||
|
|
||||||
|
|
||||||
class MeinErsterMessApp(wx.App):
|
class MeinErsterMessApp(wx.App):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.frame = None
|
||||||
|
|
||||||
def OnInit(self):
|
def OnInit(self):
|
||||||
self.frame = MyFrame(None, wx.ID_ANY, "")
|
self.frame = MyFrame(None, wx.ID_ANY, "")
|
||||||
self.SetTopWindow(self.frame)
|
self.SetTopWindow(self.frame)
|
||||||
@ -157,6 +203,7 @@ class MeinErsterMessApp(wx.App):
|
|||||||
|
|
||||||
# end of class MeinErsterMessApp
|
# end of class MeinErsterMessApp
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = MeinErsterMessApp(0)
|
app = MeinErsterMessApp()
|
||||||
app.MainLoop()
|
app.MainLoop()
|
||||||
|
Loading…
Reference in New Issue
Block a user