summaryrefslogtreecommitdiff
path: root/ui/alarm_panel.py
diff options
context:
space:
mode:
authorChristian Kolset <christian.kolset@gmail.com>2026-04-13 15:22:56 -0600
committerChristian Kolset <christian.kolset@gmail.com>2026-04-13 15:22:56 -0600
commit2ed9d37da7b27d25173535550fb92702225ac14e (patch)
treed6ff360a656e577629d3cefdaa1ae02af7255864 /ui/alarm_panel.py
parent8d6acf3a8ea4b37f86b321dbf430be5be01b1267 (diff)
Removed QtPy5 snippet and fixed directories
Diffstat (limited to 'ui/alarm_panel.py')
-rw-r--r--ui/alarm_panel.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/ui/alarm_panel.py b/ui/alarm_panel.py
new file mode 100644
index 0000000..1270aff
--- /dev/null
+++ b/ui/alarm_panel.py
@@ -0,0 +1,85 @@
+"""
+ui/alarm_panel.py — Alarm event log.
+"""
+
+from datetime import datetime
+from PyQt6.QtWidgets import (
+ QWidget, QVBoxLayout, QHBoxLayout, QLabel,
+ QScrollArea, QFrame, QPushButton,
+)
+from PyQt6.QtCore import Qt
+
+
+class AlarmRow(QFrame):
+ def __init__(self, dev_id: str, ch_id: str, value: float, kind: str):
+ super().__init__()
+ self.setObjectName("alarmEntry")
+ color = "#ef4444" if kind == "high" else "#f59e0b"
+ arrow = "▲" if kind == "high" else "▼"
+ self.setStyleSheet(f"QFrame#alarmEntry {{ border-left: 3px solid {color}; }}")
+
+ ts_str = datetime.now().strftime("%H:%M:%S.%f")[:11]
+ layout = QHBoxLayout(self)
+ layout.setContentsMargins(8, 3, 8, 3)
+
+ msg = QLabel(f"{arrow} {dev_id} / {ch_id} = {value:.4f} [{kind.upper()}]")
+ msg.setObjectName("alarmMsg")
+ ts = QLabel(ts_str)
+ ts.setObjectName("alarmTs")
+
+ layout.addWidget(msg, 1)
+ layout.addWidget(ts)
+
+
+class AlarmPanel(QWidget):
+ def __init__(self):
+ super().__init__()
+ self._count = 0
+ self._build()
+
+ def _build(self):
+ layout = QVBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(0)
+
+ hdr_w = QWidget()
+ hdr_w.setObjectName("alarmHeaderWidget")
+ hdr_lay = QHBoxLayout(hdr_w)
+ hdr_lay.setContentsMargins(0, 0, 4, 0)
+ hdr = QLabel(" ALARMS")
+ hdr.setObjectName("panelHeader")
+ hdr.setMinimumHeight(28)
+ hdr_lay.addWidget(hdr, 1)
+ clr = QPushButton("Clear")
+ clr.setObjectName("clearAlarmsBtn")
+ clr.clicked.connect(self.clear)
+ hdr_lay.addWidget(clr)
+ layout.addWidget(hdr_w)
+
+ self._scroll = QScrollArea()
+ self._scroll.setWidgetResizable(True)
+ self._container = QWidget()
+ self._inner = QVBoxLayout(self._container)
+ self._inner.setContentsMargins(4, 4, 4, 4)
+ self._inner.setSpacing(2)
+ self._inner.addStretch()
+ self._scroll.setWidget(self._container)
+ layout.addWidget(self._scroll)
+
+ def add_alarm(self, dev_id: str, ch_id: str, value: float, kind: str):
+ row = AlarmRow(dev_id, ch_id, value, kind)
+ self._inner.insertWidget(0, row)
+ self._count += 1
+ # Cap at 300 entries
+ if self._count > 300:
+ item = self._inner.takeAt(self._inner.count() - 2)
+ if item and item.widget():
+ item.widget().deleteLater()
+ self._count -= 1
+
+ def clear(self):
+ while self._inner.count() > 1:
+ item = self._inner.takeAt(0)
+ if item and item.widget():
+ item.widget().deleteLater()
+ self._count = 0