diff options
Diffstat (limited to 'core/acquisition.py')
| -rw-r--r-- | core/acquisition.py | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/core/acquisition.py b/core/acquisition.py index a984c71..4fffb8b 100644 --- a/core/acquisition.py +++ b/core/acquisition.py @@ -33,13 +33,22 @@ class ChannelBuffer: self.values.append(v) def window(self, seconds: float) -> Tuple[List[float], List[float]]: + """Last `seconds` of data. Walks in from the newest sample only — + cost is proportional to the window size, not the full buffer + (which can hold far more history than is ever displayed).""" if not self.times: return [], [] cutoff = self.times[-1] - seconds - ts = list(self.times) - vs = list(self.values) - idx = next((i for i, t in enumerate(ts) if t >= cutoff), 0) - return ts[idx:], vs[idx:] + out_t: List[float] = [] + out_v: List[float] = [] + for t, v in zip(reversed(self.times), reversed(self.values)): + if t < cutoff: + break + out_t.append(t) + out_v.append(v) + out_t.reverse() + out_v.reverse() + return out_t, out_v def all(self) -> Tuple[List[float], List[float]]: return list(self.times), list(self.values) @@ -61,13 +70,14 @@ class AcquisitionEngine(QObject): Signals ------- - new_data(device_id, channel_id, timestamp, value) + new_data(timestamp, readings) # readings: list[(device_id, channel_id, value)] — + # one batched emit per poll tick, not one per channel device_status_changed(device_id, status_str) log_started(filepath) log_stopped(filepath) """ - new_data = pyqtSignal(str, str, float, float) + new_data = pyqtSignal(float, list) device_status_changed = pyqtSignal(str, str) log_started = pyqtSignal(str) log_stopped = pyqtSignal(str) @@ -109,6 +119,14 @@ class AcquisitionEngine(QObject): # ── Start / stop ───────────────────────────────────────────────────── + def is_running(self) -> bool: + return self._running + + def elapsed_now(self) -> float: + """Wall-clock elapsed since start() — lets the UI scroll the strip + chart smoothly between poll ticks instead of only on data arrival.""" + return time.time() - self._t0 if self._running else 0.0 + def start(self): if self._running: return @@ -165,6 +183,7 @@ class AcquisitionEngine(QObject): t_start = time.time() elapsed = t_start - self._t0 log_row = [f"{elapsed:.4f}"] + batch: List[Tuple[str, str, float]] = [] for dev in list(self._devices): active = dev.status in (DeviceStatus.CONNECTED, DeviceStatus.SIMULATED) @@ -179,11 +198,15 @@ class AcquisitionEngine(QObject): if val is None or not ch.enabled: log_row.append("") continue + fval = float(val) buf = self._buffers.get(dev.info.device_id, {}).get(ch.channel_id) if buf is not None: - buf.append(elapsed, float(val)) - self.new_data.emit(dev.info.device_id, ch.channel_id, elapsed, float(val)) - log_row.append(f"{val:.5f}") + buf.append(elapsed, fval) + batch.append((dev.info.device_id, ch.channel_id, fval)) + log_row.append(f"{fval:.5f}") + + if batch: + self.new_data.emit(elapsed, batch) if self._logging and self._csv_writer: try: |
