From 65ec111c8e7bd3ac18e250b4ffd924e63a297e49 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sun, 28 Nov 2021 23:13:31 +0100 Subject: [PATCH] BIG REWORK NOTHING WORKS --- CoreLibrary/Driver.py | 34 +++ CoreLibrary/ExampleCombined.py | 81 +++++++ .../ExampleDriver.py | 6 +- .../ExampleSensor.py | 2 +- measurement.py => CoreLibrary/Measurement.py | 12 +- CoreLibrary/Param_Model.py | 59 +++++ plot_data.py => CoreLibrary/Plot_Data.py | 7 +- sensor.py => CoreLibrary/Sensor.py | 0 CoreLibrary/mess.py | 29 +++ Diagramm1.dia.autosave | Bin 0 -> 2147 bytes FemtoDLPVA100F.py | 212 ------------------ driver.py | 21 -- model.py | 80 ------- my_control_script.py | 17 -- plotView.py | 8 +- view.py | 20 +- 16 files changed, 236 insertions(+), 352 deletions(-) create mode 100644 CoreLibrary/Driver.py create mode 100644 CoreLibrary/ExampleCombined.py rename ExampleDriver.py => CoreLibrary/ExampleDriver.py (91%) rename ExampleSensor.py => CoreLibrary/ExampleSensor.py (97%) rename measurement.py => CoreLibrary/Measurement.py (87%) create mode 100644 CoreLibrary/Param_Model.py rename plot_data.py => CoreLibrary/Plot_Data.py (97%) rename sensor.py => CoreLibrary/Sensor.py (100%) create mode 100644 CoreLibrary/mess.py create mode 100644 Diagramm1.dia.autosave delete mode 100644 FemtoDLPVA100F.py delete mode 100644 driver.py delete mode 100644 model.py delete mode 100644 my_control_script.py diff --git a/CoreLibrary/Driver.py b/CoreLibrary/Driver.py new file mode 100644 index 0000000..3ba5193 --- /dev/null +++ b/CoreLibrary/Driver.py @@ -0,0 +1,34 @@ +from abc import ABC, abstractmethod + + +class Driver(ABC): + """docstring for Model.""" + + + + @abstractmethod + def exit(self): + """ + disconnecting device + """ + pass + + @abstractmethod + def set_config(self, config: dict) -> None: + """ + Setzen von Parameter die sich nie ändern Addresse usw. + """ + pass + + @abstractmethod + def get_config(self) -> dict: + pass + + + @abstractmethod + def get_status(self) -> dict: + """ + Returns a dict from status information. These values are not needed for analysis + """ + pass + diff --git a/CoreLibrary/ExampleCombined.py b/CoreLibrary/ExampleCombined.py new file mode 100644 index 0000000..8cb6b91 --- /dev/null +++ b/CoreLibrary/ExampleCombined.py @@ -0,0 +1,81 @@ +import logging +from datetime import datetime +from queue import Queue +from random import random +from threading import Thread, Event +from time import sleep + +from Driver import Driver +from Sensor import Sensor + +LOGGER = logging.getLogger() + + +class ExampleDriverWorker(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.prev = 0 + + 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 = self.prev + random() / 100.0 + self.prev = temp + ts = datetime.utcnow() + self.message_queue.put((ts, temp)) + else: + pass + sleep(1) + +class ExampleDriver(Driver, Sensor): + """docstring for Model.""" + + def __init__(self): + super(Driver, self).__init__() + self.measureQueue = Queue() + self.measureThread = ExampleDriverWorker(self.measureQueue) + self.measureThread.start() + self.measureThread.produceData.set() + self.speed = 10 + self.running = False + + def exit(self): + self.measureThread.exit_request.set() + + def set_config(self, config: dict): + self.speed = config["speed"] + + def get_config(self): + return {"speed": self.speed} + pass + + def get_status(self): + return {"running": self.running} + + def start_measuring(self): + self.measureThread.produceData.set() + logging.info("I started meas") + + def stop_measuring(self): + self.measureThread.produceData.clear() + logging.info("I stopped 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() + time.append(t) + val.append(data) + return time, val diff --git a/ExampleDriver.py b/CoreLibrary/ExampleDriver.py similarity index 91% rename from ExampleDriver.py rename to CoreLibrary/ExampleDriver.py index 9db1c68..3d8119c 100644 --- a/ExampleDriver.py +++ b/CoreLibrary/ExampleDriver.py @@ -2,7 +2,7 @@ from abc import abstractmethod from threading import Thread, Event from time import sleep from queue import Queue -from driver import Driver +from CoreLibrary.Driver import Driver import logging LOGGER = logging.getLogger() @@ -13,6 +13,7 @@ class ExampleDriverWorker(Thread): def __init__(self, message_queue): super().__init__(name="Driver") + self.produceData = Event() self.exit_request = Event() def run(self): @@ -36,12 +37,11 @@ class ExampleDriver(Driver): def exit(self): self.measureThread.exit_request.set() - def set_config(self, config): + def set_config(self, config: dict): self.speed = config["speed"] def get_status(self): return {"running": self.running} - @abstractmethod def get_config(self): pass diff --git a/ExampleSensor.py b/CoreLibrary/ExampleSensor.py similarity index 97% rename from ExampleSensor.py rename to CoreLibrary/ExampleSensor.py index 3b76dd5..03d364a 100644 --- a/ExampleSensor.py +++ b/CoreLibrary/ExampleSensor.py @@ -3,7 +3,7 @@ from threading import Thread, Event from time import sleep from queue import Queue from random import random -from sensor import Sensor +from CoreLibrary.Sensor import Sensor import logging LOGGER = logging.getLogger() diff --git a/measurement.py b/CoreLibrary/Measurement.py similarity index 87% rename from measurement.py rename to CoreLibrary/Measurement.py index b53309e..487732e 100644 --- a/measurement.py +++ b/CoreLibrary/Measurement.py @@ -1,8 +1,14 @@ import os - class Measurement: - def __init__(self, name, path=None, comment=None): + """ + Handle data and write it in a file + """ + + def attach(self, sensor): + pass + + def __init__(self, name, path=None, comment=None, writer=None): self.name = name self.path = os.path.join(path or "./meas_values", self.name) os.makedirs(self.path) @@ -31,4 +37,4 @@ class Measurement: file.write("Version 0.1\n") if comment: file.write(comment + "\n") - file.write("More descriptions of relevant parameters\n") + file.write("More descriptions of relevant parameters\n") \ No newline at end of file diff --git a/CoreLibrary/Param_Model.py b/CoreLibrary/Param_Model.py new file mode 100644 index 0000000..40f1691 --- /dev/null +++ b/CoreLibrary/Param_Model.py @@ -0,0 +1,59 @@ +from time import sleep +from threading import Thread, Event + +from CoreLibrary.ExampleDriver import ExampleDriver +from CoreLibrary.ExampleSensor import ExampleSensor +from CoreLibrary.Measurement import Measurement +from CoreLibrary.Plot_Data import Plot_Data + + +class ExampleDriverWorker(Thread): + """Communicates with the measuring hardware. Here we only produce random data.""" + + def __init__(self, pd): + super().__init__(name="Data_Worker") + self.exit_request = Event() + self.pd = pd + + def run(self): + """Worker method of a python Thread. Called when the Thread is started.""" + while not self.exit_request.is_set(): + self.pd.refresh() + sleep(1) + + +class Param_Model: + def __init__(self): + self.drivers = {"treib1": ExampleDriver()} + self.sensors = {"mess1": ExampleSensor()} + self.__plot_data = [] + self.__measurement = [] + + def new_measurement(self, name=None, writer=None) -> Measurement: + mess = Measurement(name=name) + self.__measurement.append(mess) + return mess + + def get_plot_data(self): + plot_data = Plot_Data() + self.__plot_data.append(plot_data) + return plot_data + + def refresh(self): + for name, sens in self.sensors: + data = sens.get_data + for meas in self.__measurement: + meas.append_data(name, data) + for pd in self.__plot_data: + pd.append_data(name, data) + + def stop_measuring(self): + for sens in self.sensors.items(): + sens.stop_measuring() + pass + + def start_measuring(self): + pass + + def exit(self): + pass diff --git a/plot_data.py b/CoreLibrary/Plot_Data.py similarity index 97% rename from plot_data.py rename to CoreLibrary/Plot_Data.py index 710e52a..e2eb81e 100644 --- a/plot_data.py +++ b/CoreLibrary/Plot_Data.py @@ -1,8 +1,9 @@ -import numpy as np from datetime import datetime, timedelta +import numpy as np -class PlotData: + +class Plot_Data: def __init__(self): # resolution * timeout must be at least 2-3 times higher then the slowest refresh rate @@ -60,7 +61,7 @@ class PlotData: def drop_old(self): for key in self.queues: time = np.array(self.queues[key][0]) - old = self.data["time"][-1] - (self.timeout) + old = self.data["time"][-1] - self.timeout if time.size > 2: drop_index = np.where(time < old)[0] if len(drop_index) is not 0: diff --git a/sensor.py b/CoreLibrary/Sensor.py similarity index 100% rename from sensor.py rename to CoreLibrary/Sensor.py diff --git a/CoreLibrary/mess.py b/CoreLibrary/mess.py new file mode 100644 index 0000000..59b4c23 --- /dev/null +++ b/CoreLibrary/mess.py @@ -0,0 +1,29 @@ +from time import sleep + +from CoreLibrary.Param_Model import Param_Model +from CoreLibrary.Measurement import Measurement + + +def main(param_model: Param_Model): + sensor = param_model.sensors["mess1"] + driver = param_model.drivers["treib1"] + driver.set_config({"speed": 2}) + status = driver.get_status() + + for speed in [1.0, 2.0, 3.0]: + print(speed) + driver.set_config({"speed": speed}) + + measurement = param_model.new_measurement(name=f"penis_{speed}", writer="CSV") + measurement.attach("mess1") + + sensor.start_measuring() + sleep(1) + sensor.stop_measuring() + print("test") + sensor.exit() + driver.exit() + +if __name__ == '__main__': + pd = Param_Model() + main(pd) \ No newline at end of file diff --git a/Diagramm1.dia.autosave b/Diagramm1.dia.autosave new file mode 100644 index 0000000000000000000000000000000000000000..513ab4d8d0b32ebc9e56740977a186765184b75c GIT binary patch literal 2147 zcmV-p2%PsHiwFP!000021MOW~lbbdae$TI9oL5H%8;r?jH9mOdjB z%^d2x*Ml#g-#wcRUfw);;ZXcs{?K)r~l|{rRC={uvC;t7QOj;_G zg?#ts=_~zd(xmjjzOJ%{R)UB%<}US%IMOy=Vu&%CjmKkY48xjPs;QgWy-kjXTbvip zJ1-nRFB}c$0po&WDvFQ`#yo=k1Xb{ew8sf;?8zZ^s9PO+v7|z1~ z2jPT$+M;Z!q}Z<=jZBbbcBy|wsJjx?00xQ|!UwN$JFuLilyQ?j5FAE)O?*-6E*%3C z%27^OJY=iDIzz}Q88@}6{!am+_KI+!NS~T0zxqoiT@E3q3-OiZfB$lYP@gEj#WRU? zZVX&JhxZ4z_B}q)zx;T&_D)$CTQ4cys)wr(`_sMwUj z5kFd|gXdv9=XjXnEo6UPD!D^!7{5Ipi~91$mkR9LWL|a6_C_3c1CuKZ-<+dYTk@KR zHY@MYso?_57E8m4ujI%XCZxk@-E$CVc*ss%ndYWW=R zANMQuohr~u0;>fpjYfZmf%%E}A>-d=XeNJQbY9lztWHi~ztxrwV zXC~6enG}lIrxNY-!m~rm-DRoH&Lbpiujm0C8R*DBM+Q1F(2;?T40L3mBLf{7=*U1v zR;44Wj{xoppClP6qA-a7{t=OgTwpk^B!}J)(m5k?X9_Z&Gw|0}i0lMWukWSKbcsl2 z;A0KCzooW-z&ixqA&J);hlE5Vc|70{;1J*t;E;BH2yh5+2yh4p04`7fFzzY?yNPofFQq-*_lb_$1}%hVhlAEP5OL5Q-Z`8W8=y&kYx=u zqg&>r{t3;F-D>y^0fu$qUl4F$*DuJ)z+;+_l7W;Aq+}o^11T9u$v{d5QZkT|ft1Y8 zyWPJ_#ADv;{}tzWqp+p&nXbtvL4qL&yFu6u4~O*ofEjF94J-mI0xZ&zMPS2fAQ2!D zAdwCvLcUR;4xkR84tPBE#}h#OLVQVd9{oEZyS)-ZOO+6MS0%)D>uA*&PI{F>#3&Pq zqQy_D>d3GxbEqS&r5Hkv0$djZbEur!?K;H8YQDA5(RM2-HbdIf(3%#L_Aw5Xi*2V% z+hxlg-8;r6fvRD{& z`;rRcsCB_2_n#;$>^o`xQn2mr`^x@PIpU^;Ay;y;mYzJ$om|Lp6q?jsk7jh?vDt0`(-`5(RMB)|8bb@|z3vszu}e*~Xp#*lrrtdV(@2;$Mw)esFDE!Og+D}| zpj#&g#A&c$0I1VIod)VOP^W=94b*9%P6KrssMA25b^+?N(W8yFPCG|iA8#0_A^OEDOrIsrRJ7{QP#gWv8<)n!YM_glEX})YZh`2(; z^)W?UCtV`0M)u^{2?MURjBH+3{%eeMW5>v|wvd;V|C(8<*0dO~F|aYPvG!frIC<~k Z4dFLWk~i|l<#>Jb 4: - exp_a = 4 - - if (exp_a % 2) == 0: - self.femtoThread.lsbA.set() - else: - self.femtoThread.lsbA.clear() - - if (floor((exp_a - 1) / 2) - 1) == 0: - self.femtoThread.msbA.set() - else: - self.femtoThread.msbA.clear() - - LOGGER.debug("(%s) exponent a = %i" % (self.name, exp_a)) - - def set_exponent_b( - self, - exp_b=1, - ): - if exp_b < 1: - exp_b = 1 - if exp_b > 4: - exp_b = 4 - - if (exp_b % 2) == 0: - self.femtoThread.lsbB.set() - else: - self.femtoThread.lsbB.clear() - - if (floor((exp_b - 1) / 2) - 1) == 0: - self.femtoThread.msbB.set() - else: - self.femtoThread.msbB.clear() - - LOGGER.debug("(%s) exponent a = %i" % (self.name, exp_b)) diff --git a/driver.py b/driver.py deleted file mode 100644 index bc49c35..0000000 --- a/driver.py +++ /dev/null @@ -1,21 +0,0 @@ -from abc import ABC, abstractmethod - - -class Driver(ABC): - """docstring for Model.""" - - @abstractmethod - def exit(self): - pass - - @abstractmethod - def set_config(self, config): - pass - - @abstractmethod - def get_status(self): - pass - - @abstractmethod - def get_config(self): - pass diff --git a/model.py b/model.py deleted file mode 100644 index 9921382..0000000 --- a/model.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -API for scripting measurements and drivers - -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 FemtoDLPVA100F import FemtoDLPVA100F -from measurement import Measurement -from plot_data import PlotData -from ExampleSensor import ExampleSensor - - -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() - a = ExampleSensor() - self.sensors = {"temp": a, "multi": ExampleSensor()} - self.drivers = [] - self.measurement = None - self.data_grabber = DataGrabber(self.sensors, self.drivers, self.plot_data) - self.data_grabber.start() - - 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"): - print("Has no use delete me maybe") - - def stop_measuring(self): - self.measurement = None - self.data_grabber.measurement = None - - def clear(self): - self.plot_data.clear() - - def exit(self): - self.data_grabber.exit_request.set() - for sens in self.sensors.values(): - sens.exit() - - -""" - init() - sensoren = [] - - - for mag in range(10): - drive_to_value("MagnetFelied1", mag) - start_measuring("volt", "filename") - - - - - -""" diff --git a/my_control_script.py b/my_control_script.py deleted file mode 100644 index 425c6f7..0000000 --- a/my_control_script.py +++ /dev/null @@ -1,17 +0,0 @@ -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()) diff --git a/plotView.py b/plotView.py index 442176a..ad7b60f 100644 --- a/plotView.py +++ b/plotView.py @@ -24,13 +24,13 @@ LOGGER = logging.getLogger("mylogger") class PlotPanel(wx.Panel): - def __init__(self, parent, model, plotLambda, updateLambda): + def __init__(self, parent, pd, plotLambda, updateLambda): super().__init__(parent, -1) self.plotLambda = plotLambda self.updateLambda = updateLambda - self.model = model + self.pd = pd self.fig = Figure((15, 10), 75) self.canvas = FigureCanvas(self, -1, self.fig) self.toolbar = NavigationToolbar(self.canvas) # matplotlib toolbar @@ -46,7 +46,7 @@ class PlotPanel(wx.Panel): self.Bind(wx.EVT_PAINT, self.on_paint, self) self.ax = self.fig.add_subplot() self.fig.legend() - (self.im,) = self.plotLambda(self.ax,self.model.plot_data.data) + (self.im,) = self.plotLambda(self.ax,self.pd.data) self.toolbar.update() # Not sure why this is needed - ADS def get_toolbar(self): @@ -55,7 +55,7 @@ class PlotPanel(wx.Panel): return self.toolbar def on_paint(self, event): - dat = self.model.plot_data.data + dat = self.pd.data self.updateLambda(self.im, dat) self.ax.relim() self.ax.autoscale_view() diff --git a/view.py b/view.py index dccabc4..fcf051d 100644 --- a/view.py +++ b/view.py @@ -8,7 +8,6 @@ import importlib.machinery import logging from threading import Thread import wx -from model import Model # begin wxGlade: dependencies # end wxGlade @@ -22,6 +21,9 @@ from matplotlib.backends.backend_wxagg import ( NavigationToolbar2WxAgg as NavigationToolbar, ) from matplotlib.figure import Figure + +from CoreLibrary.Param_Model import Param_Model +#from plotView import PlotPanel from plotView import PlotPanel LOGGER = logging.getLogger("myLogger") @@ -36,7 +38,8 @@ LOGGER = logging.getLogger("myLogger") class MyFrame(wx.Frame): def __init__(self, *args, **kwds): - self.model = Model() + self.model = Param_Model() + self.pd = self.model.get_plot_data() # begin wxGlade: MyFrame.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE @@ -100,14 +103,14 @@ class MyFrame(wx.Frame): self.tabs = wx.Notebook(self.panel_1, wx.ID_ANY) grid_sizer_main.Add(self.tabs, (0, 1), (1, 1), wx.EXPAND, 0) - plot = lambda ax, dat: ax.plot(dat["time"], dat["temp"]) - update = lambda im, dat: im.set_data(dat["time"], dat["temp"]) - self.plot_1 = PlotPanel(self.tabs, self.model, plot, update) + plot = lambda ax, dat: ax.plot(dat["time"], dat["mess1"]) + update = lambda im, dat: im.set_data(dat["time"], dat["mess1"]) + self.plot_1 = PlotPanel(self.tabs, self.pd, plot, update) self.tabs.AddPage(self.plot_1, "Temp") - plot = lambda ax, dat: ax.plot(dat["time"], dat["multi"]) - update = lambda im, dat: im.set_data(dat["time"], dat["multi"]) - self.plot_2 = PlotPanel(self.tabs, self.model, plot, update) + plot = lambda ax, dat: ax.plot(dat["time"], dat["mess1"]) + update = lambda im, dat: im.set_data(dat["time"], dat["mess1"]) + self.plot_2 = PlotPanel(self.tabs, self.pd, plot, update) self.tabs.AddPage(self.plot_2, "Multi") @@ -171,6 +174,7 @@ class MyFrame(wx.Frame): def update(self, event): #Repaint gui self.tabs.Refresh() + self.model.refresh() #Unlock if script is finished if self.runner_thread is not None: if not self.runner_thread.is_alive():