터치 패널 상태 확인 카드 추가
This commit is contained in:
1 parent
8386e2c8e7
commit
1011079cdb
2 files changed
+128
-19
No files matched your search
+127
-18
@@ -90,11 +90,23 @@ awk -F= '
|
||||
$1 == "sata4" {printf "SATA4_TEMP=%s\n", $2 ? $2 : "-"}
|
||||
'
|
||||
"""
|
||||
SYNOLOGY_SERVICE_SCRIPT = r"""
|
||||
ps -ef | grep 'nginx: master' | grep -v grep >/dev/null && echo WEB=1 || echo WEB=0
|
||||
ps -ef | grep -E 'mariadbd|mysqld' | grep -v grep >/dev/null && echo DB=1 || echo DB=0
|
||||
ps -ef | grep -E '[/ ]gitea( |$)|gitea web' | grep -v grep >/dev/null && echo GITEA=1 || echo GITEA=0
|
||||
"""
|
||||
LOCAL_LOG_SCRIPT = r"""
|
||||
active="$(/usr/bin/systemctl is-active rsyslog 2>/dev/null || echo unknown)"
|
||||
queue="$(find /var/spool/rsyslog -name 'control_synology_fwd*' -type f 2>/dev/null | wc -l)"
|
||||
echo "RSYSLOG=$active"
|
||||
echo "QUEUE=$queue"
|
||||
"""
|
||||
SAMPLE_INTERVAL_MS = 50
|
||||
GRAPH_SECONDS = 30
|
||||
GRAPH_POINTS = GRAPH_SECONDS * 1000 // SAMPLE_INTERVAL_MS
|
||||
SYNOLOGY_RESTART_INTERVAL_MS = 1000
|
||||
SYNOLOGY_DISK_TEMP_INTERVAL_MS = 10000
|
||||
SLOW_STATUS_INTERVAL_MS = 5000
|
||||
|
||||
|
||||
def byte_rate_unit(values):
|
||||
@@ -569,6 +581,7 @@ class TouchPanel(QMainWindow):
|
||||
self.synology_buffer = ""
|
||||
self.synology_values = {}
|
||||
self.synology_disk_temps = {}
|
||||
self.synology_services = {}
|
||||
self.last_io = None
|
||||
self.last_sample = None
|
||||
self.last_graph = None
|
||||
@@ -621,6 +634,18 @@ class TouchPanel(QMainWindow):
|
||||
self.synology_disk_temp_timer.timeout.connect(self.update_synology_disk_temp)
|
||||
self.synology_disk_temp_timer.start(SYNOLOGY_DISK_TEMP_INTERVAL_MS)
|
||||
|
||||
self.synology_service_proc = QProcess(self)
|
||||
self.synology_service_proc.finished.connect(self.synology_service_finished)
|
||||
self.synology_service_timer = QTimer(self)
|
||||
self.synology_service_timer.timeout.connect(self.update_synology_services)
|
||||
self.synology_service_timer.start(SLOW_STATUS_INTERVAL_MS)
|
||||
|
||||
self.local_log_proc = QProcess(self)
|
||||
self.local_log_proc.finished.connect(self.local_log_finished)
|
||||
self.local_log_timer = QTimer(self)
|
||||
self.local_log_timer.timeout.connect(self.update_local_log_status)
|
||||
self.local_log_timer.start(SLOW_STATUS_INTERVAL_MS)
|
||||
|
||||
self.pulse_timer = QTimer(self)
|
||||
self.pulse_timer.timeout.connect(self.tick_pulses)
|
||||
self.pulse_timer.start(25)
|
||||
@@ -629,6 +654,8 @@ class TouchPanel(QMainWindow):
|
||||
self.update_disk_temp()
|
||||
self.update_synology_status()
|
||||
self.update_synology_disk_temp()
|
||||
self.update_synology_services()
|
||||
self.update_local_log_status()
|
||||
self.update_dashboard()
|
||||
|
||||
def _build_ui(self):
|
||||
@@ -639,7 +666,7 @@ class TouchPanel(QMainWindow):
|
||||
|
||||
left = QFrame()
|
||||
left.setObjectName("statusPanel")
|
||||
left.setFixedWidth(266)
|
||||
left.setFixedWidth(398)
|
||||
left_layout = QVBoxLayout(left)
|
||||
left_layout.setContentsMargins(6, 8, 6, 8)
|
||||
left_layout.setSpacing(6)
|
||||
@@ -655,32 +682,27 @@ class TouchPanel(QMainWindow):
|
||||
pi_title.setObjectName("statusGroupTitle")
|
||||
synology_title = QLabel("SYNOLOGY")
|
||||
synology_title.setObjectName("statusGroupTitle")
|
||||
extra_title = QLabel("CHECK")
|
||||
extra_title.setObjectName("statusGroupTitle")
|
||||
status_grid.addWidget(pi_title, 0, 0)
|
||||
status_grid.addWidget(synology_title, 0, 1)
|
||||
status_grid.addWidget(extra_title, 0, 2)
|
||||
|
||||
status_rows = [
|
||||
(("io", "DISK I/O"), ("synology_sata1", "SATA1")),
|
||||
(("local", "LOCAL"), ("synology_sata2", "SATA2")),
|
||||
(("wan", "UPLINK"), ("synology_sata4", "SATA4")),
|
||||
(("lan", "ETH1"), ("synology_local", "LOCAL")),
|
||||
(("wifi5", "5G"), ("synology_wan", "UPLINK")),
|
||||
(("wifi24", "2.4G"), None),
|
||||
(("io", "DISK I/O"), ("synology_sata1", "SATA1"), ("warn_temp", "TEMP")),
|
||||
(("local", "LOCAL"), ("synology_sata2", "SATA2"), ("svc_web", "WEB")),
|
||||
(("wan", "UPLINK"), ("synology_sata4", "SATA4"), ("svc_db", "DB")),
|
||||
(("lan", "ETH1"), ("synology_local", "LOCAL"), ("svc_gitea", "GITEA")),
|
||||
(("wifi5", "5G"), ("synology_wan", "UPLINK"), ("syslog_link", "SYSLOG")),
|
||||
(("wifi24", "2.4G"), None, ("pc_net", "PC NET")),
|
||||
]
|
||||
for index, (pi_row, synology_row) in enumerate(status_rows, 1):
|
||||
for index, (pi_row, synology_row, extra_row) in enumerate(status_rows, 1):
|
||||
key, label = pi_row
|
||||
tile = StatusTile(label)
|
||||
self.rows[key] = tile
|
||||
status_grid.addWidget(tile, index, 0)
|
||||
if synology_row is None:
|
||||
spacer = QWidget()
|
||||
spacer.setFixedHeight(48)
|
||||
spacer.setObjectName("statusEmpty")
|
||||
status_grid.addWidget(spacer, index, 1)
|
||||
else:
|
||||
key, label = synology_row
|
||||
tile = StatusTile(label)
|
||||
self.rows[key] = tile
|
||||
status_grid.addWidget(tile, index, 1)
|
||||
self.add_status_grid_cell(status_grid, index, 1, synology_row)
|
||||
self.add_status_grid_cell(status_grid, index, 2, extra_row)
|
||||
left_layout.addLayout(status_grid)
|
||||
left_layout.addStretch(1)
|
||||
self.pc_button = PcWakeButton()
|
||||
@@ -737,6 +759,18 @@ class TouchPanel(QMainWindow):
|
||||
layout.addWidget(right, 1)
|
||||
self.setCentralWidget(root)
|
||||
|
||||
def add_status_grid_cell(self, grid, row, column, spec):
|
||||
if spec is None:
|
||||
spacer = QWidget()
|
||||
spacer.setFixedHeight(48)
|
||||
spacer.setObjectName("statusEmpty")
|
||||
grid.addWidget(spacer, row, column)
|
||||
return
|
||||
key, label = spec
|
||||
tile = StatusTile(label)
|
||||
self.rows[key] = tile
|
||||
grid.addWidget(tile, row, column)
|
||||
|
||||
def sample(self):
|
||||
now = time.monotonic()
|
||||
dt = max(0.001, now - self.last_sample) if self.last_sample else 0.001
|
||||
@@ -793,6 +827,13 @@ class TouchPanel(QMainWindow):
|
||||
self.rows["lan"].set_state(self.iface_detail(groups["lan"], "eth1"), activity["lan"]["error"], activity["lan"]["read"], activity["lan"]["write"])
|
||||
self.rows["wifi24"].set_state(self.iface_detail(groups["wifi24"], "wlan0"), activity["wifi24"]["error"], activity["wifi24"]["read"], activity["wifi24"]["write"])
|
||||
self.rows["wifi5"].set_state(self.iface_detail(groups["wifi5"], "wlan1"), activity["wifi5"]["error"], activity["wifi5"]["read"], activity["wifi5"]["write"])
|
||||
self.render_temp_warning(temp)
|
||||
self.rows["pc_net"].set_state(
|
||||
"eth1" if self.pc_button.online else "꺼짐",
|
||||
read_activity=self.pc_button.online and activity["lan"]["read"],
|
||||
write_activity=self.pc_button.online and activity["lan"]["write"],
|
||||
error_steady=False,
|
||||
)
|
||||
|
||||
self.latest_temp = temp
|
||||
self.latest_rpm = rpm
|
||||
@@ -856,6 +897,16 @@ class TouchPanel(QMainWindow):
|
||||
return
|
||||
self.synology_disk_temp_proc.start(SYNOLOGY_SSH[0], SYNOLOGY_SSH[1:] + [SYNOLOGY_DISK_TEMP_SCRIPT])
|
||||
|
||||
def update_synology_services(self):
|
||||
if self.synology_service_proc.state() != QProcess.NotRunning:
|
||||
return
|
||||
self.synology_service_proc.start(SYNOLOGY_SSH[0], SYNOLOGY_SSH[1:] + [SYNOLOGY_SERVICE_SCRIPT])
|
||||
|
||||
def update_local_log_status(self):
|
||||
if self.local_log_proc.state() != QProcess.NotRunning:
|
||||
return
|
||||
self.local_log_proc.start("/bin/sh", ["-c", LOCAL_LOG_SCRIPT])
|
||||
|
||||
def synology_disk_temp_finished(self, exit_code, exit_status):
|
||||
del exit_status
|
||||
if exit_code != 0:
|
||||
@@ -868,6 +919,30 @@ class TouchPanel(QMainWindow):
|
||||
key, value = line.split("=", 1)
|
||||
temps[key.strip()] = value.strip()
|
||||
self.synology_disk_temps = temps
|
||||
self.render_temp_warning(getattr(self, "latest_temp", cpu_temp()))
|
||||
|
||||
def synology_service_finished(self, exit_code, exit_status):
|
||||
del exit_status
|
||||
output = bytes(self.synology_service_proc.readAllStandardOutput()).decode("utf-8", "ignore")
|
||||
values = self.parse_status_output(output) if exit_code == 0 else {}
|
||||
self.synology_services = values
|
||||
self.render_service_tile("svc_web", "nginx", values.get("WEB") == "1", bool(values))
|
||||
self.render_service_tile("svc_db", "MariaDB", values.get("DB") == "1", bool(values))
|
||||
self.render_service_tile("svc_gitea", "Gitea", values.get("GITEA") == "1", bool(values))
|
||||
|
||||
def local_log_finished(self, exit_code, exit_status):
|
||||
del exit_status
|
||||
output = bytes(self.local_log_proc.readAllStandardOutput()).decode("utf-8", "ignore")
|
||||
values = self.parse_status_output(output) if exit_code == 0 else {}
|
||||
rsyslog_ok = values.get("RSYSLOG") == "active"
|
||||
queue_count = int(values.get("QUEUE", "0") or 0)
|
||||
detail = f"Q {queue_count}" if rsyslog_ok else values.get("RSYSLOG", "down")
|
||||
self.rows["syslog_link"].set_state(
|
||||
detail,
|
||||
read_steady=rsyslog_ok and queue_count == 0,
|
||||
write_steady=rsyslog_ok and queue_count > 0,
|
||||
error_steady=not rsyslog_ok,
|
||||
)
|
||||
|
||||
def synology_status_ready(self):
|
||||
output = bytes(self.synology_proc.readAllStandardOutput()).decode("utf-8", "ignore")
|
||||
@@ -926,12 +1001,46 @@ class TouchPanel(QMainWindow):
|
||||
write_activity = previous is not None and writes > previous[1]
|
||||
self.rows[key].set_state(detail, read_activity=read_activity, write_activity=write_activity, error_steady=False)
|
||||
|
||||
def render_temp_warning(self, pi_temp):
|
||||
synology_temps = []
|
||||
for value in self.synology_disk_temps.values():
|
||||
if value.isdigit():
|
||||
synology_temps.append(float(value))
|
||||
synology_max = max(synology_temps) if synology_temps else 0.0
|
||||
pi_disk = self.disk_temp or 0.0
|
||||
hottest = max(float(pi_temp), pi_disk, synology_max)
|
||||
detail = f"{hottest:.0f} C" if hottest > 0 else "- C"
|
||||
self.rows["warn_temp"].set_state(
|
||||
detail,
|
||||
read_steady=0 < hottest < 60,
|
||||
write_steady=60 <= hottest < 70,
|
||||
error_steady=hottest >= 70,
|
||||
)
|
||||
|
||||
def render_service_tile(self, key, detail, ok, reachable):
|
||||
self.rows[key].set_state(
|
||||
detail if reachable else "끊김",
|
||||
read_steady=ok,
|
||||
write_steady=False,
|
||||
error_steady=not ok,
|
||||
)
|
||||
|
||||
def synology_disk_temp_detail(self, disk):
|
||||
value = self.synology_disk_temps.get(f"{disk}_TEMP", "")
|
||||
if not value:
|
||||
return "- C"
|
||||
return f"{value} C"
|
||||
|
||||
@staticmethod
|
||||
def parse_status_output(output):
|
||||
values = {}
|
||||
for line in output.splitlines():
|
||||
if "=" not in line:
|
||||
continue
|
||||
key, value = line.split("=", 1)
|
||||
values[key.strip()] = value.strip()
|
||||
return values
|
||||
|
||||
def set_synology_net_tile(self, key, rx, tx, errors, drops, detail):
|
||||
previous = self.last_synology.get(key)
|
||||
self.last_synology[key] = (rx, tx, errors, drops)
|
||||
|
||||
Reference in new issue
Block a user