터치 패널 실시간 점멸과 PC 대기 상태 개선
This commit is contained in:
1 parent
6aa8e7277f
commit
2184183ed8
2 files changed
+35
-9
No files matched your search
@@ -146,7 +146,7 @@ cd /var/www/control
|
|||||||
/usr/bin/python3 touch_panel/panel.py
|
/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 슬라이더는 현재값 위치만 보여 주며 터치 제어는 받지 않습니다.
|
오른쪽에는 팬 RPM, CPU 온도, PWM, WAN 실시간 속도와 온도/RPM, WAN 트래픽 그래프를 표시합니다. 위 그래프는 좌측 Y축에 온도, 우측 Y축에 RPM 단위를 표시하고, 아래 WAN 그래프는 기존 형태를 유지합니다. 팬 auto/manual/off 버튼은 없고 PWM 슬라이더는 현재값 위치만 보여 주며 터치 제어는 받지 않습니다.
|
||||||
|
|
||||||
|
|||||||
+34
-8
@@ -230,26 +230,52 @@ class PcWakeButton(StatusTile):
|
|||||||
super().__init__("PC")
|
super().__init__("PC")
|
||||||
self.online = False
|
self.online = False
|
||||||
self.last_wake_at = 0.0
|
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):
|
def set_online(self, online):
|
||||||
self.online = online
|
self.online = online
|
||||||
self.read_dot.set_steady(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:
|
if online:
|
||||||
|
self.wait_until = 0.0
|
||||||
self.detail.setText("켜짐")
|
self.detail.setText("켜짐")
|
||||||
elif time.monotonic() - self.last_wake_at < 30:
|
elif now < self.wait_until:
|
||||||
remaining = int(30 - (time.monotonic() - self.last_wake_at))
|
remaining = int(self.wait_until - now)
|
||||||
self.detail.setText(f"대기 {remaining}s")
|
self.detail.setText(f"대기 {remaining}s")
|
||||||
else:
|
else:
|
||||||
self.detail.setText("꺼짐")
|
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):
|
def mousePressEvent(self, event):
|
||||||
if event.button() == Qt.LeftButton:
|
if event.button() == Qt.LeftButton:
|
||||||
self.write_dot.blink()
|
self.write_dot.blink()
|
||||||
if not self.online and time.monotonic() - self.last_wake_at >= 30:
|
now = time.monotonic()
|
||||||
self.last_wake_at = 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("깨우는 중")
|
self.detail.setText("깨우는 중")
|
||||||
if not send_magic_packet(PC_MAC):
|
if not send_magic_packet(PC_MAC):
|
||||||
|
self.wait_until = 0.0
|
||||||
|
self.error_until = now + 5
|
||||||
self.error_dot.set_steady(True)
|
self.error_dot.set_steady(True)
|
||||||
super().mousePressEvent(event)
|
super().mousePressEvent(event)
|
||||||
|
|
||||||
@@ -385,7 +411,7 @@ class TouchPanel(QMainWindow):
|
|||||||
|
|
||||||
self.sample_timer = QTimer(self)
|
self.sample_timer = QTimer(self)
|
||||||
self.sample_timer.timeout.connect(self.sample)
|
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 = QTimer(self)
|
||||||
self.graph_timer.timeout.connect(self.update_graphs)
|
self.graph_timer.timeout.connect(self.update_graphs)
|
||||||
@@ -405,7 +431,7 @@ class TouchPanel(QMainWindow):
|
|||||||
|
|
||||||
self.pulse_timer = QTimer(self)
|
self.pulse_timer = QTimer(self)
|
||||||
self.pulse_timer.timeout.connect(self.tick_pulses)
|
self.pulse_timer.timeout.connect(self.tick_pulses)
|
||||||
self.pulse_timer.start(70)
|
self.pulse_timer.start(25)
|
||||||
self.sample()
|
self.sample()
|
||||||
self.ping_pc()
|
self.ping_pc()
|
||||||
self.update_disk_temp()
|
self.update_disk_temp()
|
||||||
@@ -557,7 +583,7 @@ class TouchPanel(QMainWindow):
|
|||||||
def update_disk_temp(self):
|
def update_disk_temp(self):
|
||||||
if self.disk_temp_proc.state() != QProcess.NotRunning:
|
if self.disk_temp_proc.state() != QProcess.NotRunning:
|
||||||
return
|
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):
|
def disk_temp_finished(self, exit_code, exit_status):
|
||||||
del exit_code, exit_status
|
del exit_code, exit_status
|
||||||
|
|||||||
Reference in new issue
Block a user