터치 패널 PC 버튼 확장 복원

This commit is contained in:
seo committed 2026-08-14 02:26:55 +09:00
1 parent 637739386e
commit 64ded5e566
2 files changed
+117 -6

No files matched your search

+114 -5
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys
import time
import socket
import os
import shutil
from collections import deque
@@ -28,6 +29,8 @@ NET_GROUPS = {
"wifi5": ["wlan1"],
}
PC_IP = "192.168.50.73"
PC_MAC = "74:56:3C:CD:CD:79"
RPI_SERVICE_UNITS = [
("rpi_docker", "docker.service"),
("rpi_nginx", "nginx.service"),
@@ -340,6 +343,21 @@ def disk_io():
return reads, writes, not found
def send_magic_packet(mac):
clean = mac.replace(":", "").replace("-", "")
if len(clean) != 12:
return False
packet = bytes.fromhex("ff" * 6 + clean * 16)
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
for target in ["192.168.50.255", "255.255.255.255"]:
sock.sendto(packet, (target, 9))
return True
except OSError:
return False
class StatusDot(QWidget):
def __init__(self, active_color):
super().__init__()
@@ -462,6 +480,72 @@ class StatusTile(QFrame):
self.error_dot.set_steady(error_on)
class PcWakeButton(StatusTile):
def __init__(self):
super().__init__("PC")
self.online = False
self.last_wake_at = 0.0
self.wait_until = 0.0
self.error_until = 0.0
self.wait_phase = False
self.blink_timer = QTimer(self)
self.blink_timer.timeout.connect(self.tick_waiting)
self.blink_timer.start(250)
def set_online(self, online):
self.online = online
self.read_dot.set_steady(online)
now = time.monotonic()
self.error_dot.set_steady(now < self.error_until)
if online:
self.wait_until = 0.0
self.wait_phase = False
self.write_dot.set_steady(False)
self.detail.setText("켜짐")
elif now < self.wait_until:
remaining = int(self.wait_until - now)
self.detail.setText(f"대기 {remaining}s")
else:
self.write_dot.set_steady(False)
self.detail.setText("꺼짐")
def tick_waiting(self):
now = time.monotonic()
if not self.online and now < self.wait_until:
self.wait_phase = not self.wait_phase
self.write_dot.set_steady(self.wait_phase)
if not self.online and self.wait_until > 0 and now >= self.wait_until:
self.wait_until = 0.0
self.wait_phase = False
self.write_dot.set_steady(False)
self.error_until = now + 60
self.error_dot.set_steady(True)
self.detail.setText("실패")
if self.error_until > 0 and now >= self.error_until:
self.error_until = 0.0
self.error_dot.set_steady(False)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
now = time.monotonic()
if not self.online and now >= self.wait_until:
self.last_wake_at = now
self.wait_until = now + 60
self.wait_phase = True
self.write_dot.set_steady(True)
self.error_until = 0.0
self.error_dot.set_steady(False)
self.detail.setText("깨우는 중")
if not send_magic_packet(PC_MAC):
self.wait_until = 0.0
self.error_until = now + 5
self.error_dot.set_steady(True)
super().mousePressEvent(event)
def tick(self):
self.error_dot.tick()
class Sparkline(QFrame):
def __init__(self, title, color="#38bdf8", second_color=None, y_unit="", right_unit="", auto_byte_unit=False, max_points=120):
super().__init__()
@@ -610,6 +694,12 @@ class TouchPanel(QMainWindow):
self.fan_timer.timeout.connect(self.update_fan_status)
self.fan_timer.start(FAN_INTERVAL_MS)
self.pc_ping = QProcess(self)
self.pc_ping.finished.connect(self.pc_ping_finished)
self.pc_timer = QTimer(self)
self.pc_timer.timeout.connect(self.ping_pc)
self.pc_timer.start(1000)
self.disk_temp_timer = QTimer(self)
self.disk_temp_timer.timeout.connect(self.update_disk_temp)
self.disk_temp_timer.start(DISK_TEMP_INTERVAL_MS)
@@ -653,6 +743,7 @@ class TouchPanel(QMainWindow):
self.pulse_timer.start(25)
self.sample()
self.update_fan_status()
self.ping_pc()
self.update_disk_temp()
self.update_rpi_services()
self.update_synology_status()
@@ -663,9 +754,13 @@ class TouchPanel(QMainWindow):
def _build_ui(self):
root = QWidget()
layout = QHBoxLayout(root)
layout = QVBoxLayout(root)
layout.setContentsMargins(4, 8, 10, 8)
layout.setSpacing(8)
layout.setSpacing(6)
panel_layout = QHBoxLayout()
panel_layout.setContentsMargins(0, 0, 0, 0)
panel_layout.setSpacing(8)
rpi_rows = [
(("io", "SSD I/O"), ("rpi_temp", "TEMP"), ("rpi_fan", "FAN")),
@@ -684,7 +779,7 @@ class TouchPanel(QMainWindow):
(("synology_sata1", "SATA1 I/O"), ("synology_sata2", "SATA2 I/O"), ("synology_sata4", "SATA4 I/O")),
]
left = self.build_status_panel("RASPBERRY", rpi_rows, fixed_width=398, bottom_blank=True)
left = self.build_status_panel("RASPBERRY", rpi_rows, fixed_width=398)
right = self.build_status_panel("SYNOLOGY", synology_rows)
header = QHBoxLayout()
@@ -697,8 +792,13 @@ class TouchPanel(QMainWindow):
header.addWidget(self.clock)
right.layout().insertLayout(1, header)
layout.addWidget(left)
layout.addWidget(right, 1)
panel_layout.addWidget(left)
panel_layout.addWidget(right, 1)
layout.addLayout(panel_layout, 1)
self.pc_button = PcWakeButton()
self.pc_button.setFixedHeight(48)
layout.addWidget(self.pc_button)
self.setCentralWidget(root)
def build_status_panel(self, title_text, rows, fixed_width=None, bottom_blank=False):
@@ -836,6 +936,15 @@ class TouchPanel(QMainWindow):
detail = "OK" if active else state.upper()[:6]
self.rows[key].set_state(detail, read_steady=active, write_steady=False, error_steady=not active)
def ping_pc(self):
if self.pc_ping.state() != QProcess.NotRunning:
return
self.pc_ping.start("/usr/bin/ping", ["-c", "1", "-W", "1", PC_IP])
def pc_ping_finished(self, exit_code, exit_status):
del exit_status
self.pc_button.set_online(exit_code == 0)
def ping_synology(self):
if self.synology_ping_proc.state() != QProcess.NotRunning:
return