터치 패널 실시간 점멸과 PC 대기 상태 개선

This commit is contained in:
seo committed 2026-07-30 13:20:01 +09:00
1 parent 6aa8e7277f
commit 2184183ed8
2 files changed
+35 -9

No files matched your search

+1 -1
View File
@@ -146,7 +146,7 @@ cd /var/www/control
/usr/bin/python3 touch_panel/panel.py
```
패널은 Control PHP/API/DB snapshot을 호출하지 않는 standalone 방식입니다. Python이 `/sys/class/net`, `/proc/diskstats`, `/sys/class/thermal`, 팬 hwmon 파일을 직접 읽습니다. 상태패널과 팬패널은 120ms 간격으로 갱신하고, 그래프는 500ms 간격으로 샘플링합니다. 왼쪽 `DISK I/O`, `WAN`, `LAN`, `2.4G`, `5G` 표시등은 장식용 heartbeat가 아니라 실제 커널 카운터 증가에 반응합니다. 각 타일에는 글자 아래에 세 개의 작은 표시등을 두며 읽기/업로드는 초록, 쓰기/다운로드는 주황, 오류는 빨강으로 표시합니다. 활동이 없으면 초록/주황은 회색입니다. `DISK I/O`의 값은 `/dev/sda` Samsung T7을 `smartctl -d sntasmedia`로 1초마다 읽은 디스크 자체 온도입니다. 네트워크 상태값은 정상, 드롭 누적, 꺼짐으로 표시합니다. 상태패널 최하단의 `PC` 타일은 `192.168.50.73`에 1초마다 ping을 보내 켜짐 여부를 표시하고, 꺼져 있을 때 누르면 `74:56:3C:CD:CD:79`로 WOL magic packet을 보냅니다. PC 타일의 주황은 터치/WOL 전송 시도 표시, 빨강은 magic packet 전송 실패 표시입니다. WOL은 한 번 누르면 30초 동안 추가 전송을 막습니다.
패널은 Control PHP/API/DB snapshot을 호출하지 않는 standalone 방식입니다. Python이 `/sys/class/net`, `/proc/diskstats`, `/sys/class/thermal`, 팬 hwmon 파일을 직접 읽습니다. 상태패널과 팬패널은 50ms 간격으로 커널 카운터를 따라가고, 그래프는 500ms 간격으로 샘플링합니다. 왼쪽 `DISK I/O`, `WAN`, `LAN`, `2.4G`, `5G` 표시등은 장식용 heartbeat가 아니라 실제 커널 카운터 증가에 반응합니다. 각 타일에는 글자 아래에 세 개의 작은 표시등을 두며 읽기/업로드는 초록, 쓰기/다운로드는 주황, 오류는 빨강으로 표시합니다. 활동이 없으면 초록/주황은 회색입니다. `DISK I/O`의 값은 `/dev/sda` Samsung T7을 `smartctl -d sntasmedia`로 1초마다 읽은 디스크 자체 온도입니다. GUI 사용자 `seo`는 `/etc/sudoers.d/control-touch-panel-smartctl`에서 해당 smartctl 명령만 NOPASSWD로 허용합니다. 네트워크 상태값은 정상, 드롭 누적, 꺼짐으로 표시합니다. 상태패널 최하단의 `PC` 타일은 `192.168.50.73`에 1초마다 ping을 보내 켜짐 여부를 표시하고, 꺼져 있을 때 누르면 `74:56:3C:CD:CD:79`로 WOL magic packet을 보냅니다. PC 타일의 주황은 WOL 후 최대 1분 동안 컴퓨터 응답 대기 표시, 빨강은 magic packet 전송 실패 시 5초 또는 1분 대기 후 응답 실패 시 1분 표시입니다.
오른쪽에는 팬 RPM, CPU 온도, PWM, WAN 실시간 속도와 온도/RPM, WAN 트래픽 그래프를 표시합니다. 위 그래프는 좌측 Y축에 온도, 우측 Y축에 RPM 단위를 표시하고, 아래 WAN 그래프는 기존 형태를 유지합니다. 팬 auto/manual/off 버튼은 없고 PWM 슬라이더는 현재값 위치만 보여 주며 터치 제어는 받지 않습니다.
+34 -8
View File
@@ -230,26 +230,52 @@ class PcWakeButton(StatusTile):
super().__init__("PC")
self.online = False
self.last_wake_at = 0.0
self.wait_until = 0.0
self.error_until = 0.0
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)
self.error_dot.set_steady(False)
now = time.monotonic()
self.error_dot.set_steady(now < self.error_until)
if online:
self.wait_until = 0.0
self.detail.setText("켜짐")
elif time.monotonic() - self.last_wake_at < 30:
remaining = int(30 - (time.monotonic() - self.last_wake_at))
elif now < self.wait_until:
remaining = int(self.wait_until - now)
self.detail.setText(f"대기 {remaining}s")
else:
self.detail.setText("꺼짐")
def tick_waiting(self):
now = time.monotonic()
if not self.online and now < self.wait_until:
self.write_dot.blink()
if not self.online and self.wait_until > 0 and now >= self.wait_until:
self.wait_until = 0.0
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:
self.write_dot.blink()
if not self.online and time.monotonic() - self.last_wake_at >= 30:
self.last_wake_at = time.monotonic()
now = time.monotonic()
if not self.online and now >= self.wait_until:
self.last_wake_at = now
self.wait_until = now + 60
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)
@@ -385,7 +411,7 @@ class TouchPanel(QMainWindow):
self.sample_timer = QTimer(self)
self.sample_timer.timeout.connect(self.sample)
self.sample_timer.start(120)
self.sample_timer.start(50)
self.graph_timer = QTimer(self)
self.graph_timer.timeout.connect(self.update_graphs)
@@ -405,7 +431,7 @@ class TouchPanel(QMainWindow):
self.pulse_timer = QTimer(self)
self.pulse_timer.timeout.connect(self.tick_pulses)
self.pulse_timer.start(70)
self.pulse_timer.start(25)
self.sample()
self.ping_pc()
self.update_disk_temp()
@@ -557,7 +583,7 @@ class TouchPanel(QMainWindow):
def update_disk_temp(self):
if self.disk_temp_proc.state() != QProcess.NotRunning:
return
self.disk_temp_proc.start("/usr/sbin/smartctl", ["-A", "-d", "sntasmedia", "/dev/sda"])
self.disk_temp_proc.start("/usr/bin/sudo", ["-n", "/usr/sbin/smartctl", "-A", "-d", "sntasmedia", "/dev/sda"])
def disk_temp_finished(self, exit_code, exit_status):
del exit_code, exit_status