diff --git a/cpdctrl_gui/ui/widgets/led_script.py b/cpdctrl_gui/ui/widgets/led_script.py index 98a941c..cfaac39 100644 --- a/cpdctrl_gui/ui/widgets/led_script.py +++ b/cpdctrl_gui/ui/widgets/led_script.py @@ -1,4 +1,4 @@ -from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QScrollArea, QTableView +from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QScrollArea, QTableView, QFormLayout from PyQt6.QtCore import QAbstractTableModel, QModelIndex, Qt import numpy as np @@ -6,29 +6,68 @@ from cpdctrl.led_script import LedScript import time import datetime + + +timedelta = [("d", 24*3600), ("h", 3600), ("m", 60), ("s", 1)] +def duration_to_string(duration: float) -> str: + """ + Convert a duration in seconds to a string of the form "d h m s" + where only the largest units are included. + Parameters + ---------- + duration: float + Duration in seconds. + + Returns + ------- + String representation of the duration. + """ + include = False + s = "" + sign = 1 if duration > 0 else -1 + time_left = abs(int(duration)) + for i, (unit, unit_seconds) in enumerate(timedelta): + t = int(time_left / unit_seconds) + if t != 0 or include or unit == "s": + s += f"{sign*t:02}{unit} " + include = True + time_left %= unit_seconds + return s.strip() + class TimeLeft(QWidget): def __init__(self, parent=None): super().__init__(parent) self.t_end = None - self.setLayout(QVBoxLayout()) - self.layout().addWidget(QLabel("Time left")) + self.t_start = None + self.setLayout(QFormLayout()) + self.setLayout(QFormLayout()) + self.w_time_passed = QLabel("N.A.") + self.layout().addRow(QLabel("Time passed:"), self.w_time_passed) self.w_time_left = QLabel("N.A.") - self.layout().addWidget(self.w_time_left) + self.layout().addRow(QLabel("Time left:"), self.w_time_left) self.w_end_time = QLabel("N.A.") - self.layout().addWidget(self.w_end_time) + self.layout().addRow(QLabel("End time:"), self.w_end_time) - def set_end_time(self, t_end: float): + def reset(self): + self.t_start = None + self.t_end = None + self.w_time_passed.setText("N.A.") + self.w_time_left.setText("N.A.") + self.w_end_time.setText("N.A.") + + def set_start_end_time(self, t_start: float, t_end: float): """ Set the end time Parameters ---------- + t_start + The start time in seconds since epoch t_end The end time in seconds since epoch """ + self.t_start = t_start self.t_end = t_end - self.w_end_time.setText( - datetime.datetime.fromtimestamp(t_end).strftime("%Y-%m-%d %H:%M:%S") - ) + self.w_end_time.setText(datetime.datetime.fromtimestamp(t_end).strftime("%Y-%m-%d %H:%M:%S")) def update_time(self, t_now: float): """ @@ -39,18 +78,8 @@ class TimeLeft(QWidget): The current time in seconds since epoch """ if self.t_end is None: raise RuntimeError("Update called before end time was set") - # convert to format d, h, m, s - print(self.t_end, t_now, self.t_end - t_now) - sign = 1 if self.t_end > t_now else -1 - time_left = abs(int(self.t_end - t_now)) - days = sign * int(time_left / (24 * 3600)) - time_left %= (24 * 3600) - hours = sign * int(time_left / 3600) - time_left %= 3600 - minutes = sign * int(time_left / 60) - time_left %= 60 - seconds = sign * int(time_left) - self.w_time_left.setText(f"{days}d, {hours:02}h, {minutes:02}m, {seconds:02}s") + self.w_time_left.setText(duration_to_string(self.t_end - t_now)) + self.w_time_passed.setText(duration_to_string(t_now - self.t_start)) @@ -110,6 +139,8 @@ class LedScriptTableModel(QAbstractTableModel): flags |= Qt.ItemFlag.ItemIsEditable return flags + def update_time(self, t_now: float): + self.dt = self.led_script.get_dt(t_now) @@ -149,5 +180,8 @@ class LedScriptViewer(QWidget): raise NotImplementedError() def update_time(self, t_now: float): + self.model.update_time(t_now) self.w_time_left.update_time(t_now) + self.w_table.update() +