load-controller/load_controller/profile_handler.py

98 lines
2.6 KiB
Python
Raw Normal View History

2023-01-04 00:22:27 +01:00
import enum
import csv
import time
2023-01-04 16:53:42 +01:00
from PySide6.QtCore import QObject, Signal, QTimer
2023-01-04 00:22:27 +01:00
class ProfileState(enum.Enum):
STOPPED = 0
RUNNING = 1
PAUSED = 2
class ProfileHandler(QObject):
2023-01-04 19:33:20 +01:00
currentChanged = Signal(float)
profileChanged = Signal(list)
2023-01-04 16:53:42 +01:00
finished = Signal()
2023-01-04 00:22:27 +01:00
state: ProfileState
_timer: QTimer
profile_start: float
2023-01-04 19:33:20 +01:00
_profile: list[list[float]]
2023-01-04 00:22:27 +01:00
_pause_time: float
_last_current: float
def __init__(self):
super().__init__(parent=None)
self.state = ProfileState.STOPPED
self._timer = QTimer()
self._timer.timeout.connect(self._update)
self._timer.start(100)
self._profile = []
self.profile_start = 0
self._pause_time = 0
self._last_current = 0
2023-01-04 19:33:20 +01:00
def load_profile(self, path: str):
2023-01-04 00:22:27 +01:00
with open(path) as fh:
result = []
t = 0
for l in csv.reader(fh):
i = float(l[0])
2023-01-04 19:33:20 +01:00
result.append([t, i])
2023-01-04 00:22:27 +01:00
t += float(l[1])
2023-01-04 19:33:20 +01:00
result.append([t, i])
2023-01-04 00:22:27 +01:00
self._profile = result
2023-01-04 19:33:20 +01:00
self.profileChanged.emit(result)
2023-01-04 00:22:27 +01:00
return result
def start(self):
assert self.state == ProfileState.STOPPED
self.profile_start = time.time()
self.state = ProfileState.RUNNING
current = self._profile[0][1]
self._last_current = current
2023-01-04 19:33:20 +01:00
self.currentChanged.emit(current)
2023-01-04 00:22:27 +01:00
def pause(self):
assert self.state == ProfileState.RUNNING
self.state = ProfileState.PAUSED
2023-01-04 19:33:20 +01:00
self.currentChanged.emit(0)
2023-01-04 00:22:27 +01:00
self._last_current = 0
self._pause_time = time.time()
def resume(self):
assert self.state == ProfileState.PAUSED
dt = time.time() - self._pause_time
self.profile_start += dt
self.state = ProfileState.RUNNING
def stop(self):
assert self.state != ProfileState.STOPPED
self.state = ProfileState.STOPPED
2023-01-04 19:33:20 +01:00
self.currentChanged.emit(0)
2023-01-04 00:22:27 +01:00
self._last_current = 0
def _update(self):
if self.state == ProfileState.RUNNING:
dt = time.time() - self.profile_start
try:
current = next(t[1] for t in self._profile if t[0] >= dt)
if current != self._last_current:
2023-01-04 19:33:20 +01:00
self.currentChanged.emit(current)
2023-01-04 00:22:27 +01:00
self._last_current = current
except StopIteration:
self.state = ProfileState.STOPPED
self.finished.emit()
else:
self._last_current = 0
2023-01-04 19:33:20 +01:00
self.currentChanged.emit(0)