From cb0eca7aaba53642879ec62f47c7e974f99b752e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E5=8F=A3=E6=B5=AA=E4=BA=BA?= Date: Sat, 26 Sep 2026 14:20:36 +0800 Subject: [PATCH 1/4] feat: add active network interface status --- README.md | 12 ++++--- app/pigway_pi_control.py | 61 ++++++++++++++++++++++++++++++----- config/pigway-pi-control.conf | 21 +++++++++++- install.sh | 2 +- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index fbd96c5..5b51d59 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Pigway Pi Control v3.1.0 — Release +# Pigway Pi Control v3.2.0 — Release 适用于本套 Raspberry Pi 4B 散热扩展板的正式发布版。 @@ -118,7 +118,7 @@ sudo reboot 进入解压后的目录: ```bash -cd pigway-pi-control-v3.1.0 +cd pigway-pi-control-v3.2.0 ``` ### 第三步:安装 @@ -185,7 +185,7 @@ systemd: 这些由安装包维护。 -因此安装成功后,解压出来的 `pigway-pi-control-v3.1.0/` 文件夹可以删除。 +因此安装成功后,解压出来的 `pigway-pi-control-v3.2.0/` 文件夹可以删除。 建议把 ZIP 保存到 Mac / NAS,供以后重装。 @@ -374,8 +374,12 @@ sudo rm /etc/pigway-pi-control.conf 2. raspi-config 开启 I²C 3. 重启 4. 解压本 ZIP -5. cd pigway-pi-control-v3.1.0 +5. cd pigway-pi-control-v3.2.0 6. sudo ./install.sh ``` 完成。 + +## v3.2.0 网络状态增强 + +主页显示当前 Linux 默认路由接口:Wi-Fi 为 `WIF -52`(RSSI),有线为 `ETH 1G`(链路速率)。双网同时连接时跟随内核默认路由,IP 与该接口保持一致。新增 Wi-Fi 弱信号持续告警。 diff --git a/app/pigway_pi_control.py b/app/pigway_pi_control.py index fc0cf93..a083556 100755 --- a/app/pigway_pi_control.py +++ b/app/pigway_pi_control.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import os,time,socket,subprocess,configparser,signal from pathlib import Path -APP_VERSION="3.1.0" +APP_VERSION="3.2.0" from smbus2 import SMBus from PIL import Image from shutil import disk_usage @@ -22,7 +22,8 @@ prev_cpu=None page=0; page_since=time.monotonic() cpu_hi=mem_hi=0 net_ok=link_ok=True -ip="NO IP" +net_iface=""; net_kind="NET"; net_metric="DOWN"; ip_label="IP4"; ip="NO IP" +wifi_weak_since=None; wifi_weak_active=False last_net=last_watch=0 watch_state=[] @@ -133,10 +134,37 @@ def mem_pct(): return 100*(vals["MemTotal"]-vals["MemAvailable"])/vals["MemTotal"] def disk_pct(): d=disk_usage("/"); return 100*d.used/d.total +def _run(args): + try: return subprocess.check_output(args,text=True,stderr=subprocess.DEVNULL,timeout=2).strip() + except Exception: return "" + +def primary_network(): + out=_run(["ip","-4","route","get","1.1.1.1"]) + dev=re.search(r"\\bdev\\s+(\\S+)",out); src=re.search(r"\\bsrc\\s+(\\S+)",out); label="IP4" + if not dev: + out=_run(["ip","-6","route","get","2606:4700:4700::1111"]) + dev=re.search(r"\\bdev\\s+(\\S+)",out); src=re.search(r"\\bsrc\\s+(\\S+)",out); label="IP6" + if not dev: return "","NET","DOWN","IP4","NO IP" + iface=dev.group(1); ipval=src.group(1) if src else "" + if Path(f"/sys/class/net/{iface}/wireless").exists(): + kind="WIF"; metric="--" + try: + for line in Path("/proc/net/wireless").read_text().splitlines(): + if line.lstrip().startswith(iface+":"): + metric=str(int(float(line.split()[3].rstrip(".")))); break + except Exception: pass + else: + kind="ETH"; metric="UP" + try: + n=int(Path(f"/sys/class/net/{iface}/speed").read_text().strip()) + metric=f"{n//1000}G" if n>=1000 and n%1000==0 else str(n) + except Exception: pass + if label=="IP6" and len(ipval)>18: ipval=ipval[:7]+".."+ipval[-7:] + return iface,kind,metric,label,(ipval or "NO IP") + def get_ip(): - try: - s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM);s.connect(("1.1.1.1",53));v=s.getsockname()[0];s.close();return v - except: return "NO IP" + return primary_network()[4] + def internet(): try: s=socket.create_connection(("1.1.1.1",53),0.5);s.close();return True @@ -176,6 +204,9 @@ TEMP_HIGH=cf("alerts","temp_high",68.0) TEMP_CRIT=cf("alerts","temp_critical",75.0) DISK_HIGH=cf("alerts","disk_high",90.0) DISK_CRIT=cf("alerts","disk_critical",95.0) +WIFI_WEAK=cf("alerts","wifi_weak",-75.0) +WIFI_RECOVER=cf("alerts","wifi_recover",-68.0) +WIFI_WEAK_SECONDS=cf("alerts","wifi_weak_seconds",30.0) FAN_T=[cf("fan","start",50.0),cf("fan","level2",53.0),cf("fan","level3",56.0), cf("fan","level4",59.0),cf("fan","max",62.0)] @@ -201,6 +232,7 @@ def alert(title,l2="",l3="",l4="",sev=1,color=(20,16,0),blink=0): "sev":sev,"color":color,"blink":blink} def make_alerts(cpu,temp,mem,disk): + global wifi_weak_since,wifi_weak_active global cpu_hi,mem_hi a=[] cpu_hi=cpu_hi+1 if cpu>=CPU_HIGH else 0 if cpu= WIFI_WEAK_SECONDS: wifi_weak_active=True + else: wifi_weak_since=None + elif rssi >= WIFI_RECOVER: + wifi_weak_active=False; wifi_weak_since=None + if wifi_weak_active: + a.append(alert("WIFI SIGNAL WEAK",f"{rssi:.0f} dBm",f"IF {net_iface}","CHECK SIGNAL",1,(0,0,28),1)) + else: + wifi_weak_since=None; wifi_weak_active=False a.sort(key=lambda x:x["sev"],reverse=True) return a @@ -238,12 +283,12 @@ def render_home(cpu,temp,mem,disk): f"CPU {cpu:.1f}%", f"TMP {temp:.1f}C", f"DSK {disk:.1f}%", - ("IP6 " if ":" in ip else "IP4 ")+ip, + ip_label+" "+ip, ] right=[ f"MEM {mem:.1f}%", f"FAN {FAN_NAME[fan_level]}", - f"NET {'OK' if net_ok else 'DOWN'}", + f"{net_kind} {net_metric}", "", ] for row in range(4): @@ -302,7 +347,7 @@ while running: latest=(c,t,m,d); update_fan(t); last_sensor=now if now-last_net >= NETWORK_INTERVAL: - ip=get_ip(); link_ok=ip!="NO IP"; net_ok=internet() if link_ok else False + net_iface,net_kind,net_metric,ip_label,ip=primary_network(); link_ok=ip!="NO IP"; net_ok=internet() if link_ok else False last_net=now if now-last_watch >= SERVICE_INTERVAL: diff --git a/config/pigway-pi-control.conf b/config/pigway-pi-control.conf index e7464fe..8ce3a7f 100644 --- a/config/pigway-pi-control.conf +++ b/config/pigway-pi-control.conf @@ -1,5 +1,5 @@ # ============================================================================= -# Pigway Pi Control v3.1.0 - 用户配置文件 +# Pigway Pi Control v3.2.0 - 用户配置文件 # ============================================================================= # # 正式安装后的配置路径: @@ -120,6 +120,25 @@ disk_high = 90 # 根分区使用率达到此百分比触发严重告警。 disk_critical = 95 +# ---------------- Wi-Fi 信号 ---------------- +# 仅当 Wi-Fi 是 Linux 当前默认路由/主网络接口时生效。 +# +# RSSI 单位为 dBm,越接近 0 表示信号越强: +# -50 左右:很好 +# -60 左右:良好 +# -70 左右:一般 +# -80 以下:较弱 +# +# 连续低于该值达到 wifi_weak_seconds 后触发蓝色网络告警。 +wifi_weak = -75 + +# 已触发弱信号告警后,必须恢复到该值以上才解除。 +# 与 wifi_weak 留出差值可避免信号在临界值附近反复报警。 +wifi_recover = -68 + +# 弱信号必须持续多少秒才报警,避免瞬时 Wi-Fi 波动产生误报。 +wifi_weak_seconds = 30 + [led] # RGB 规则: diff --git a/install.sh b/install.sh index c5fdcdf..d96eec1 100755 --- a/install.sh +++ b/install.sh @@ -63,7 +63,7 @@ systemctl restart pigway-pi-control.service echo "[7/8] 安装后自检..." FAIL=0 check() { if eval "$2"; then printf " %-30s PASS\n" "$1"; else printf " %-30s FAIL\n" "$1"; FAIL=1; fi; } -check "Version 3.1.0" "grep -q 'APP_VERSION=\"3.1.0\"' /usr/local/sbin/pigway-pi-control" +check "Version 3.2.0" "grep -q 'APP_VERSION=\"3.2.0\"' /usr/local/sbin/pigway-pi-control" check "OLED physical 128x32" "grep -q 'W,H=128,32' /usr/local/sbin/pigway-pi-control" check "OLED MUX 0x1F" "grep -q '0xA8,0x1F' /usr/local/sbin/pigway-pi-control" check "OLED pages 0..3" "grep -q 'cmd(0x22);cmd(0);cmd(3)' /usr/local/sbin/pigway-pi-control" -- 2.54.0 From b28ee63f38c99625cabf88b534578bb91c715f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E5=8F=A3=E6=B5=AA=E4=BA=BA?= Date: Sat, 26 Sep 2026 14:25:39 +0800 Subject: [PATCH 2/4] fix: correct default route regex parsing --- app/pigway_pi_control.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pigway_pi_control.py b/app/pigway_pi_control.py index a083556..b50059c 100755 --- a/app/pigway_pi_control.py +++ b/app/pigway_pi_control.py @@ -140,10 +140,10 @@ def _run(args): def primary_network(): out=_run(["ip","-4","route","get","1.1.1.1"]) - dev=re.search(r"\\bdev\\s+(\\S+)",out); src=re.search(r"\\bsrc\\s+(\\S+)",out); label="IP4" + dev=re.search(r"\bdev\s+(\S+)",out); src=re.search(r"\bsrc\s+(\S+)",out); label="IP4" if not dev: out=_run(["ip","-6","route","get","2606:4700:4700::1111"]) - dev=re.search(r"\\bdev\\s+(\\S+)",out); src=re.search(r"\\bsrc\\s+(\\S+)",out); label="IP6" + dev=re.search(r"\bdev\s+(\S+)",out); src=re.search(r"\bsrc\s+(\S+)",out); label="IP6" if not dev: return "","NET","DOWN","IP4","NO IP" iface=dev.group(1); ipval=src.group(1) if src else "" if Path(f"/sys/class/net/{iface}/wireless").exists(): -- 2.54.0 From 62db207c45b013ea15f8036b3f5588f39155e674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E5=8F=A3=E6=B5=AA=E4=BA=BA?= Date: Sat, 26 Sep 2026 14:31:49 +0800 Subject: [PATCH 3/4] fix: import regex module for network detection --- app/pigway_pi_control.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/pigway_pi_control.py b/app/pigway_pi_control.py index b50059c..d266471 100755 --- a/app/pigway_pi_control.py +++ b/app/pigway_pi_control.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import re import os,time,socket,subprocess,configparser,signal from pathlib import Path APP_VERSION="3.2.0" -- 2.54.0 From 2b70db10fc4576636b2702de8068a53fdf05474b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E5=8F=A3=E6=B5=AA=E4=BA=BA?= Date: Sat, 26 Sep 2026 14:38:17 +0800 Subject: [PATCH 4/4] fix: update IP4/IP6 installer self-check --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index d96eec1..5253e37 100755 --- a/install.sh +++ b/install.sh @@ -68,7 +68,7 @@ check "OLED physical 128x32" "grep -q 'W,H=128,32' /usr/local/sbin/pigway-pi-con check "OLED MUX 0x1F" "grep -q '0xA8,0x1F' /usr/local/sbin/pigway-pi-control" check "OLED pages 0..3" "grep -q 'cmd(0x22);cmd(0);cmd(3)' /usr/local/sbin/pigway-pi-control" check "UI CPU/TMP/DSK" "grep -q 'f\"TMP {temp:.1f}C\"' /usr/local/sbin/pigway-pi-control" -check "UI IP4/IP6" "grep -q 'IP6 .*IP4 ' /usr/local/sbin/pigway-pi-control" +check "UI IP4/IP6" "grep -q 'ip_label.*IP4' /usr/local/sbin/pigway-pi-control && grep -q 'label=\"IP6\"' /usr/local/sbin/pigway-pi-control" check "UI right column x=72" "grep -q \"draw_text_5x7(pix,72,y,right\\[row\\])\" /usr/local/sbin/pigway-pi-control" check "Legacy service stopped" "! systemctl is-active --quiet temp-control.service" check "Service running" "systemctl is-active --quiet pigway-pi-control.service" -- 2.54.0