Unified Sensors and Drivers --> Device
This commit is contained in:
parent
90b0983160
commit
3b9b0fc06c
@ -1,16 +1,12 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
|
||||||
class Driver(ABC):
|
class Device(ABC):
|
||||||
"""docstring for Model."""
|
"""docstring for Model."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_data(self) -> Tuple[List, List]:
|
||||||
@abstractmethod
|
|
||||||
def exit(self):
|
|
||||||
"""
|
|
||||||
disconnecting device
|
|
||||||
"""
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -24,7 +20,6 @@ class Driver(ABC):
|
|||||||
def get_config(self) -> dict:
|
def get_config(self) -> dict:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_status(self) -> dict:
|
def get_status(self) -> dict:
|
||||||
"""
|
"""
|
||||||
@ -32,3 +27,14 @@ class Driver(ABC):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def start_measuring(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def stop_measuring(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def exit(self):
|
||||||
|
pass
|
@ -5,13 +5,12 @@ from random import random
|
|||||||
from threading import Thread, Event
|
from threading import Thread, Event
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
from Driver import Driver
|
from Device import Device
|
||||||
from Sensor import Sensor
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger("my_logger")
|
LOGGER = logging.getLogger("my_logger")
|
||||||
|
|
||||||
|
|
||||||
class ExampleDriverWorker(Thread):
|
class ExampleDeviceWorker(Thread):
|
||||||
"""Communicates with the measuring hardware. Here we only produce random data."""
|
"""Communicates with the measuring hardware. Here we only produce random data."""
|
||||||
|
|
||||||
def __init__(self, message_queue):
|
def __init__(self, message_queue):
|
||||||
@ -31,21 +30,23 @@ class ExampleDriverWorker(Thread):
|
|||||||
self.message_queue.put((ts, temp))
|
self.message_queue.put((ts, temp))
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
sleep(1)
|
sleep(0.2)
|
||||||
|
|
||||||
class ExampleDriver(Driver, Sensor):
|
|
||||||
"""docstring for Model."""
|
class ExampleDeviceScalar(Device):
|
||||||
|
"""Communicates with the measuring hardware. Here we only produce random data."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Driver, self).__init__()
|
super(Device, self).__init__()
|
||||||
self.measureQueue = Queue()
|
self.measureQueue = Queue()
|
||||||
self.measureThread = ExampleDriverWorker(self.measureQueue)
|
self.measureThread = ExampleDeviceWorker(self.measureQueue)
|
||||||
self.measureThread.start()
|
self.measureThread.start()
|
||||||
self.measureThread.produceData.set()
|
self.measureThread.produceData.set()
|
||||||
self.speed = 10
|
self.speed = 10
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
|
self.stop_measuring()
|
||||||
self.measureThread.exit_request.set()
|
self.measureThread.exit_request.set()
|
||||||
|
|
||||||
def set_config(self, config: dict):
|
def set_config(self, config: dict):
|
||||||
@ -53,7 +54,6 @@ class ExampleDriver(Driver, Sensor):
|
|||||||
|
|
||||||
def get_config(self):
|
def get_config(self):
|
||||||
return {"speed": self.speed}
|
return {"speed": self.speed}
|
||||||
pass
|
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
return {"running": self.running}
|
return {"running": self.running}
|
||||||
@ -66,10 +66,6 @@ class ExampleDriver(Driver, Sensor):
|
|||||||
self.measureThread.produceData.clear()
|
self.measureThread.produceData.clear()
|
||||||
LOGGER.info("I stopped meas")
|
LOGGER.info("I stopped meas")
|
||||||
|
|
||||||
def exit(self):
|
|
||||||
self.stop_measuring()
|
|
||||||
self.measureThread.exit_request.set()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
time = []
|
time = []
|
@ -1,47 +0,0 @@
|
|||||||
from abc import abstractmethod
|
|
||||||
from threading import Thread, Event
|
|
||||||
from time import sleep
|
|
||||||
from queue import Queue
|
|
||||||
from CoreLibrary.Driver import Driver
|
|
||||||
import logging
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger("my_logger")
|
|
||||||
|
|
||||||
|
|
||||||
class ExampleDriverWorker(Thread):
|
|
||||||
"""Communicates with the measuring hardware. Here we only produce random data."""
|
|
||||||
|
|
||||||
def __init__(self, message_queue):
|
|
||||||
super().__init__(name="Driver")
|
|
||||||
self.produceData = Event()
|
|
||||||
self.exit_request = Event()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
"""Worker method of a python Thread. Called when the Thread is started."""
|
|
||||||
while not self.exit_request.is_set():
|
|
||||||
sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
class ExampleDriver(Driver):
|
|
||||||
"""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_status(self):
|
|
||||||
return {"running": self.running}
|
|
||||||
|
|
||||||
def get_config(self):
|
|
||||||
pass
|
|
@ -1,65 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
from threading import Thread, Event
|
|
||||||
from time import sleep
|
|
||||||
from queue import Queue
|
|
||||||
from random import random
|
|
||||||
from CoreLibrary.Sensor import Sensor
|
|
||||||
import logging
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger("my_logger")
|
|
||||||
|
|
||||||
|
|
||||||
class ExampleSensorWorker(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 ExampleSensor(Sensor):
|
|
||||||
"""docstring for Model."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Sensor, self).__init__()
|
|
||||||
self.measureQueue = Queue()
|
|
||||||
self.measureThread = ExampleSensorWorker(self.measureQueue)
|
|
||||||
self.measureThread.start()
|
|
||||||
self.measureThread.produceData.set()
|
|
||||||
|
|
||||||
def start_measuring(self):
|
|
||||||
self.measureThread.produceData.set()
|
|
||||||
LOGGER.info("I started meas")
|
|
||||||
|
|
||||||
def stop_measuring(self):
|
|
||||||
self.measureThread.produceData.clear()
|
|
||||||
LOGGER.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
|
|
@ -3,8 +3,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from CoreLibrary.Driver import Driver
|
from CoreLibrary.Device import Device
|
||||||
from CoreLibrary.Sensor import Sensor
|
|
||||||
|
|
||||||
LOGGER = logging.getLogger("my_logger")
|
LOGGER = logging.getLogger("my_logger")
|
||||||
|
|
||||||
@ -19,42 +18,33 @@ class Measurement:
|
|||||||
self.path = os.path.join(path or "./meas_values", self.name)
|
self.path = os.path.join(path or "./meas_values", self.name)
|
||||||
os.makedirs(self.path)
|
os.makedirs(self.path)
|
||||||
self.save_version_text(comment)
|
self.save_version_text(comment)
|
||||||
self.sensors = {}
|
self.devices = {}
|
||||||
self.drivers = {}
|
self.data_files = {"log": self.create_file("log")}
|
||||||
self.data_files = {}
|
|
||||||
self.data_files["log"] = self.create_file("log")
|
|
||||||
|
|
||||||
def create_file(self, name: str):
|
def create_file(self, name: str):
|
||||||
return open(os.path.join(self.path, name), "w")
|
return open(os.path.join(self.path, name), "w")
|
||||||
|
|
||||||
def attach_sensor(self, sensor: Sensor, name: str):
|
def attach_device(self, device: Device, name: str):
|
||||||
self.sensors[name] = sensor
|
self.devices[name] = device
|
||||||
|
|
||||||
def attach_driver(self, driver: Driver, name: str):
|
|
||||||
self.drivers[name] = driver
|
|
||||||
|
|
||||||
def attach_combined(self, comb, name: str):
|
|
||||||
self.attach_sensor(comb, name)
|
|
||||||
self.attach_driver(comb, name)
|
|
||||||
|
|
||||||
def write_log(self, text: str):
|
def write_log(self, text: str):
|
||||||
self.data_files["log"].write(str(datetime.datetime.utcnow()) + ":\t" + text + "\n")
|
self.data_files["log"].write(str(datetime.datetime.utcnow()) + ":\t" + text + "\n")
|
||||||
|
|
||||||
def append_data(self, sensor_name, data):
|
def append_data(self, device_name, data):
|
||||||
"""
|
"""
|
||||||
Save data from a sensor. Write it into the corresponding file.
|
Save data from a device. Write it into the corresponding file.
|
||||||
|
|
||||||
TODO: file size limit, zip?
|
TODO: file size limit, zip?
|
||||||
data: list of tuples: (timestamp, value)
|
data: list of tuples: (timestamp, value)
|
||||||
"""
|
"""
|
||||||
if sensor_name not in self.sensors:
|
if device_name not in self.devices:
|
||||||
return
|
return
|
||||||
|
|
||||||
LOGGER.info("append-data: " + sensor_name)
|
LOGGER.info("append-data: " + device_name)
|
||||||
if sensor_name not in self.data_files:
|
if device_name not in self.data_files:
|
||||||
self.data_files[sensor_name] = self.create_file(sensor_name)
|
self.data_files[device_name] = self.create_file(device_name)
|
||||||
for timestamp, value in zip(data[0], data[1]):
|
for timestamp, value in zip(data[0], data[1]):
|
||||||
self.data_files[sensor_name].write(
|
self.data_files[device_name].write(
|
||||||
f"{timestamp.isoformat()}, {timestamp.timestamp()}, {value}\n"
|
f"{timestamp.isoformat()}, {timestamp.timestamp()}, {value}\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@ from logging.handlers import RotatingFileHandler
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from threading import Thread, Event
|
from threading import Thread, Event
|
||||||
|
|
||||||
from CoreLibrary.ExampleDriver import ExampleDriver
|
from CoreLibrary.ExampleDeviceScalar import ExampleDeviceScalar
|
||||||
from CoreLibrary.ExampleSensor import ExampleSensor
|
|
||||||
from CoreLibrary.Measurement import Measurement
|
from CoreLibrary.Measurement import Measurement
|
||||||
from CoreLibrary.Plot_Data import Plot_Data
|
from CoreLibrary.Plot_Data import Plot_Data
|
||||||
|
|
||||||
@ -43,8 +42,7 @@ class DataWorker(Thread):
|
|||||||
|
|
||||||
class Param_Model:
|
class Param_Model:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.drivers = {"treib1": ExampleDriver()}
|
self.devices = {"treib1": ExampleDeviceScalar(), "mess1": ExampleDeviceScalar()}
|
||||||
self.sensors = {"mess1": ExampleSensor()}
|
|
||||||
self.__plot_data = []
|
self.__plot_data = []
|
||||||
self.__measurement = []
|
self.__measurement = []
|
||||||
self.data_worker = DataWorker(self)
|
self.data_worker = DataWorker(self)
|
||||||
@ -62,25 +60,23 @@ class Param_Model:
|
|||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
LOGGER.debug("refresh")
|
LOGGER.debug("refresh")
|
||||||
for name, sens in self.sensors.items():
|
for name, device in self.devices.items():
|
||||||
data = sens.get_data
|
data = device.get_data
|
||||||
for meas in self.__measurement:
|
for meas in self.__measurement:
|
||||||
meas.append_data(name, data)
|
meas.append_data(name, data)
|
||||||
for pd in self.__plot_data:
|
for pd in self.__plot_data:
|
||||||
pd.append_data(name, data)
|
pd.append_data(name, data)
|
||||||
|
|
||||||
def stop_measuring(self):
|
def stop_measuring(self):
|
||||||
for sens in self.sensors.values():
|
for sens in self.devices.values():
|
||||||
sens.stop_measuring()
|
sens.stop_measuring()
|
||||||
|
|
||||||
def start_measuring(self):
|
def start_measuring(self):
|
||||||
for sens in self.sensors.values():
|
for sens in self.devices.values():
|
||||||
sens.start_measuring()
|
sens.start_measuring()
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
LOGGER.warning("entering exit method")
|
LOGGER.warning("entering exit method")
|
||||||
for sens in self.sensors.values():
|
for sens in self.devices.values():
|
||||||
sens.exit()
|
sens.exit()
|
||||||
for drv in self.drivers.values():
|
|
||||||
drv.exit()
|
|
||||||
self.data_worker.exit_request.set()
|
self.data_worker.exit_request.set()
|
||||||
|
@ -22,16 +22,16 @@ class Plot_Data:
|
|||||||
def get(self, key):
|
def get(self, key):
|
||||||
return self.data.get(key, np.full_like(self.data["time"], np.nan, dtype=np.double))
|
return self.data.get(key, np.full_like(self.data["time"], np.nan, dtype=np.double))
|
||||||
|
|
||||||
def append_data(self, sensor_name, data):
|
def append_data(self, device_name, data):
|
||||||
""" """
|
""" """
|
||||||
if sensor_name not in self.data:
|
if device_name not in self.data:
|
||||||
self.queues[sensor_name] = ([], [])
|
self.queues[device_name] = ([], [])
|
||||||
self.data[sensor_name] = np.full_like(self.data["time"], np.nan, dtype=np.double)
|
self.data[device_name] = np.full_like(self.data["time"], np.nan, dtype=np.double)
|
||||||
for time, dat in zip(data[0], data[1]):
|
for time, dat in zip(data[0], data[1]):
|
||||||
self.queues[sensor_name][0].append(
|
self.queues[device_name][0].append(
|
||||||
(time - self.start_time) / timedelta(milliseconds=self.resolution)
|
(time - self.start_time) / timedelta(milliseconds=self.resolution)
|
||||||
)
|
)
|
||||||
self.queues[sensor_name][1].append(dat)
|
self.queues[device_name][1].append(dat)
|
||||||
self.extend_timeline()
|
self.extend_timeline()
|
||||||
self.sort_in_queue()
|
self.sort_in_queue()
|
||||||
self.drop_old()
|
self.drop_old()
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
|
|
||||||
class Sensor(ABC):
|
|
||||||
"""docstring for Model."""
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def start_measuring(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def stop_measuring(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def exit(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
def get_data(self):
|
|
||||||
pass
|
|
@ -9,12 +9,12 @@ import matplotlib.pyplot as plt
|
|||||||
|
|
||||||
|
|
||||||
def clean():
|
def clean():
|
||||||
rmtree("meas_values")
|
rmtree("meas_values", ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
def main(param_model: Param_Model):
|
def main(param_model: Param_Model):
|
||||||
sensor = param_model.sensors["mess1"]
|
sensor = param_model.devices["mess1"]
|
||||||
driver = param_model.drivers["treib1"]
|
driver = param_model.devices["treib1"]
|
||||||
driver.set_config({"speed": 2})
|
driver.set_config({"speed": 2})
|
||||||
status = driver.get_status()
|
status = driver.get_status()
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ def main(param_model: Param_Model):
|
|||||||
driver.set_config({"speed": speed})
|
driver.set_config({"speed": speed})
|
||||||
|
|
||||||
measurement = param_model.new_measurement(name=f"penis_{speed}", writer="CSV")
|
measurement = param_model.new_measurement(name=f"penis_{speed}", writer="CSV")
|
||||||
measurement.attach_sensor(sensor=sensor, name="mess1")
|
measurement.attach_device(device=sensor, name="mess1")
|
||||||
measurement.write_log("ich mag ramen")
|
measurement.write_log("ich mag ramen")
|
||||||
param_model.start_measuring()
|
param_model.start_measuring()
|
||||||
sleep(2)
|
sleep(2)
|
||||||
|
Loading…
Reference in New Issue
Block a user