터치 패널 상태 표시등 실시간 분리
This commit is contained in:
1 parent
66d305bc18
commit
e89f1da109
2 files changed
+65
-47
No files matched your search
+63
-45
@@ -134,12 +134,12 @@ def write_sys(path, value):
|
||||
|
||||
|
||||
class StatusDot(QWidget):
|
||||
def __init__(self):
|
||||
def __init__(self, active_color):
|
||||
super().__init__()
|
||||
self.active_color = QColor(active_color)
|
||||
self.warning = False
|
||||
self.pulse = 0
|
||||
self.phase = False
|
||||
self.setFixedSize(22, 22)
|
||||
self.setFixedSize(15, 15)
|
||||
|
||||
def set_warning(self, warning=False):
|
||||
self.warning = warning
|
||||
@@ -147,7 +147,6 @@ class StatusDot(QWidget):
|
||||
|
||||
def blink(self):
|
||||
self.pulse = 3
|
||||
self.phase = not self.phase
|
||||
self.update()
|
||||
|
||||
def tick(self):
|
||||
@@ -160,21 +159,20 @@ class StatusDot(QWidget):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
base = QColor("#8fa0aa")
|
||||
if self.warning:
|
||||
base = QColor("#f59e0b")
|
||||
if self.pulse > 0:
|
||||
base = QColor("#86efac") if self.phase else QColor("#16a34a")
|
||||
base = self.active_color
|
||||
painter.setBrush(base)
|
||||
painter.setPen(Qt.NoPen)
|
||||
painter.drawEllipse(3, 3, 16, 16)
|
||||
painter.setPen(QPen(QColor("#ef4444"), 1) if self.warning else Qt.NoPen)
|
||||
painter.drawEllipse(2, 2, 11, 11)
|
||||
painter.setBrush(QColor(255, 255, 255, 55))
|
||||
painter.drawEllipse(8, 6, 5, 5)
|
||||
painter.drawEllipse(6, 4, 4, 4)
|
||||
|
||||
|
||||
class StatusTile(QFrame):
|
||||
def __init__(self, title):
|
||||
super().__init__()
|
||||
self.dot = StatusDot()
|
||||
self.read_dot = StatusDot("#16a34a")
|
||||
self.write_dot = StatusDot("#f97316")
|
||||
self.title = QLabel(title)
|
||||
self.title.setObjectName("statusTitle")
|
||||
self.detail = QLabel("-")
|
||||
@@ -183,9 +181,15 @@ class StatusTile(QFrame):
|
||||
self.setFixedHeight(58)
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(7, 6, 7, 6)
|
||||
layout.setSpacing(6)
|
||||
layout.addWidget(self.dot, 0, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
layout.setContentsMargins(6, 6, 6, 6)
|
||||
layout.setSpacing(4)
|
||||
|
||||
dots = QVBoxLayout()
|
||||
dots.setContentsMargins(0, 0, 0, 0)
|
||||
dots.setSpacing(4)
|
||||
dots.addWidget(self.read_dot, 0, Qt.AlignCenter)
|
||||
dots.addWidget(self.write_dot, 0, Qt.AlignCenter)
|
||||
layout.addLayout(dots)
|
||||
|
||||
texts = QVBoxLayout()
|
||||
texts.setContentsMargins(0, 0, 0, 0)
|
||||
@@ -195,14 +199,18 @@ class StatusTile(QFrame):
|
||||
layout.addLayout(texts, 1)
|
||||
self.setObjectName("statusTile")
|
||||
|
||||
def set_state(self, detail, warning=False, activity=False):
|
||||
self.dot.set_warning(warning)
|
||||
if activity:
|
||||
self.dot.blink()
|
||||
def set_state(self, detail, warning=False, read_activity=False, write_activity=False):
|
||||
self.read_dot.set_warning(warning)
|
||||
self.write_dot.set_warning(warning)
|
||||
if read_activity:
|
||||
self.read_dot.blink()
|
||||
if write_activity:
|
||||
self.write_dot.blink()
|
||||
self.detail.setText(detail)
|
||||
|
||||
def tick(self):
|
||||
self.dot.tick()
|
||||
self.read_dot.tick()
|
||||
self.write_dot.tick()
|
||||
|
||||
|
||||
class MetricCard(QFrame):
|
||||
@@ -299,10 +307,12 @@ class TouchPanel(QMainWindow):
|
||||
self.last_net = {}
|
||||
self.last_io = None
|
||||
self.last_sample = None
|
||||
self.last_graph = None
|
||||
self.current_rates = {"wan": {"rx": 0.0, "tx": 0.0}}
|
||||
self.current_pwm = read_int(self.fan["pwm"])
|
||||
self.temp_history = deque(maxlen=80)
|
||||
self.rpm_history = deque(maxlen=80)
|
||||
self.net_history = {key: {"rx": deque(maxlen=80), "tx": deque(maxlen=80)} for key in ["wan", "lan", "wifi"]}
|
||||
self.net_history = {"wan": {"rx": deque(maxlen=80), "tx": deque(maxlen=80)}}
|
||||
|
||||
self.setWindowTitle("Standalone Touch Dashboard")
|
||||
self.setCursor(Qt.BlankCursor)
|
||||
@@ -313,6 +323,10 @@ class TouchPanel(QMainWindow):
|
||||
self.sample_timer.timeout.connect(self.sample)
|
||||
self.sample_timer.start(120)
|
||||
|
||||
self.graph_timer = QTimer(self)
|
||||
self.graph_timer.timeout.connect(self.update_graphs)
|
||||
self.graph_timer.start(500)
|
||||
|
||||
self.pulse_timer = QTimer(self)
|
||||
self.pulse_timer.timeout.connect(self.tick_pulses)
|
||||
self.pulse_timer.start(70)
|
||||
@@ -399,11 +413,9 @@ class TouchPanel(QMainWindow):
|
||||
for index, (key, chart) in enumerate([
|
||||
("temp", Sparkline("온도 / RPM", "#f97316", "#38bdf8")),
|
||||
("wan", Sparkline("WAN 트래픽", "#38bdf8", "#22c55e")),
|
||||
("lan", Sparkline("LAN 트래픽", "#38bdf8", "#22c55e")),
|
||||
("wifi", Sparkline("WiFi 트래픽", "#38bdf8", "#22c55e")),
|
||||
]):
|
||||
self.charts[key] = chart
|
||||
chart_grid.addWidget(chart, index // 2, index % 2)
|
||||
chart_grid.addWidget(chart, index, 0)
|
||||
right_layout.addLayout(chart_grid, 1)
|
||||
|
||||
layout.addWidget(left)
|
||||
@@ -422,7 +434,8 @@ class TouchPanel(QMainWindow):
|
||||
percent = pwm / 255 * 100 if pwm > 0 else 0
|
||||
|
||||
reads, writes = disk_io()
|
||||
io_activity = self.last_io is not None and (reads, writes) != self.last_io
|
||||
io_read_activity = self.last_io is not None and reads != self.last_io[0]
|
||||
io_write_activity = self.last_io is not None and writes != self.last_io[1]
|
||||
self.last_io = (reads, writes)
|
||||
|
||||
groups = {key: group_stats(names) for key, names in NET_GROUPS.items()}
|
||||
@@ -431,7 +444,10 @@ class TouchPanel(QMainWindow):
|
||||
for key, row in groups.items():
|
||||
previous = self.last_net.get(key)
|
||||
current = (row["rx_bytes"], row["tx_bytes"], row["rx_packets"], row["tx_packets"])
|
||||
activity[key] = previous is not None and current != previous
|
||||
activity[key] = {
|
||||
"read": previous is not None and current[1] != previous[1],
|
||||
"write": previous is not None and current[0] != previous[0],
|
||||
}
|
||||
if previous:
|
||||
rates[key] = {
|
||||
"rx": max(0.0, (current[0] - previous[0]) * 8 / dt / 1_000_000),
|
||||
@@ -441,14 +457,15 @@ class TouchPanel(QMainWindow):
|
||||
rates[key] = {"rx": 0.0, "tx": 0.0}
|
||||
self.last_net[key] = current
|
||||
|
||||
self.render(temp, rpm, pwm, percent, enable, groups, rates, activity, io_activity)
|
||||
self.current_rates = rates
|
||||
self.render(temp, rpm, pwm, percent, enable, groups, rates, activity, io_read_activity, io_write_activity)
|
||||
|
||||
def render(self, temp, rpm, pwm, percent, enable, groups, rates, activity, io_activity):
|
||||
self.rows["io"].set_state(f"{temp:.1f} C", temp >= 75, io_activity)
|
||||
self.rows["wan"].set_state(self.iface_detail(groups["wan"]), self.iface_warn(groups["wan"]), activity["wan"])
|
||||
self.rows["lan"].set_state(self.iface_detail(groups["lan"]), self.iface_warn(groups["lan"]), activity["lan"])
|
||||
self.rows["wifi24"].set_state(self.iface_detail(groups["wifi24"]), self.iface_warn(groups["wifi24"]), activity["wifi24"])
|
||||
self.rows["wifi5"].set_state(self.iface_detail(groups["wifi5"]), self.iface_warn(groups["wifi5"]), activity["wifi5"])
|
||||
def render(self, temp, rpm, pwm, percent, enable, groups, rates, activity, io_read_activity, io_write_activity):
|
||||
self.rows["io"].set_state(f"{temp:.1f} C", temp >= 75, io_read_activity, io_write_activity)
|
||||
self.rows["wan"].set_state(self.iface_detail(groups["wan"]), self.iface_warn(groups["wan"]), activity["wan"]["read"], activity["wan"]["write"])
|
||||
self.rows["lan"].set_state(self.iface_detail(groups["lan"]), self.iface_warn(groups["lan"]), activity["lan"]["read"], activity["lan"]["write"])
|
||||
self.rows["wifi24"].set_state(self.iface_detail(groups["wifi24"]), self.iface_warn(groups["wifi24"]), activity["wifi24"]["read"], activity["wifi24"]["write"])
|
||||
self.rows["wifi5"].set_state(self.iface_detail(groups["wifi5"]), self.iface_warn(groups["wifi5"]), activity["wifi5"]["read"], activity["wifi5"]["write"])
|
||||
|
||||
self.metrics["rpm"].set_value(f"{rpm:,}")
|
||||
self.metrics["temp"].set_value(f"{temp:.1f} C")
|
||||
@@ -463,23 +480,24 @@ class TouchPanel(QMainWindow):
|
||||
self.mode_buttons["auto"].setChecked(enable not in [0, 1])
|
||||
|
||||
self.clock.setText(time.strftime("%H:%M:%S"))
|
||||
self.latest_temp = temp
|
||||
self.latest_rpm = rpm
|
||||
|
||||
def update_graphs(self):
|
||||
temp = getattr(self, "latest_temp", cpu_temp())
|
||||
rpm = getattr(self, "latest_rpm", read_int(self.fan["rpm"]))
|
||||
self.temp_history.append(temp)
|
||||
self.rpm_history.append(rpm / 100)
|
||||
self.charts["temp"].set_values(self.temp_history, "C / RPMx100", self.rpm_history)
|
||||
|
||||
for key, chart_key in [("wan", "wan"), ("lan", "lan")]:
|
||||
self.net_history[key]["rx"].append(rates[key]["rx"])
|
||||
self.net_history[key]["tx"].append(rates[key]["tx"])
|
||||
self.charts[chart_key].set_values(
|
||||
self.net_history[key]["rx"],
|
||||
f"{rates[key]['rx']:.2f}/{rates[key]['tx']:.2f} Mbps",
|
||||
self.net_history[key]["tx"],
|
||||
)
|
||||
wifi_rx = rates["wifi24"]["rx"] + rates["wifi5"]["rx"]
|
||||
wifi_tx = rates["wifi24"]["tx"] + rates["wifi5"]["tx"]
|
||||
self.net_history["wifi"]["rx"].append(wifi_rx)
|
||||
self.net_history["wifi"]["tx"].append(wifi_tx)
|
||||
self.charts["wifi"].set_values(self.net_history["wifi"]["rx"], f"{wifi_rx:.2f}/{wifi_tx:.2f} Mbps", self.net_history["wifi"]["tx"])
|
||||
wan = self.current_rates.get("wan", {"rx": 0.0, "tx": 0.0})
|
||||
self.net_history["wan"]["rx"].append(wan["rx"])
|
||||
self.net_history["wan"]["tx"].append(wan["tx"])
|
||||
self.charts["wan"].set_values(
|
||||
self.net_history["wan"]["rx"],
|
||||
f"{wan['rx']:.2f}/{wan['tx']:.2f} Mbps",
|
||||
self.net_history["wan"]["tx"],
|
||||
)
|
||||
|
||||
def set_fan(self, mode):
|
||||
pwm = self.slider.value()
|
||||
|
||||
Reference in new issue
Block a user