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)
|