gcode预览测试

This commit is contained in:
2026-05-14 20:21:16 +08:00
parent 65f221a5d8
commit 837996c436
17 changed files with 1363 additions and 296 deletions

View File

@@ -3,8 +3,9 @@ import time
import re
class WifiManager:
def __init__(self, interface="wlan0"):
def __init__(self, interface="wlan0", backend="nmcli"):
self.interface = interface
self.backend = backend # "nmcli" or "wpa_cli"
def _run_wpa_cli(self, *args):
"""执行 wpa_cli 命令"""
@@ -16,128 +17,209 @@ class WifiManager:
print(f"执行 wpa_cli {args} 失败: {e.stderr}")
return ""
def _run_nmcli(self, *args):
"""执行 nmcli 命令"""
cmd = ["nmcli"] + list(args)
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"执行 nmcli {args} 失败: {e.stderr}")
return ""
def list_saved_networks(self):
"""列出已保存的 wifiwpa_cli list_networks 以 Tab 分隔)"""
output = self._run_wpa_cli("list_networks")
networks = []
lines = output.splitlines()
if len(lines) > 1:
for line in lines[1:]: # skip header
parts = line.split('\t')
if len(parts) >= 4:
if self.backend == "wpa_cli":
output = self._run_wpa_cli("list_networks")
networks = []
lines = output.splitlines()
if len(lines) > 1:
for line in lines[1:]:
parts = line.split('\t')
if len(parts) >= 4:
networks.append({
"network_id": parts[0],
"ssid": parts[1],
"bssid": parts[2],
"flags": parts[3]
})
return networks
else:
output = self._run_nmcli("-t", "-f", "UUID,NAME,TYPE", "connection", "show")
networks = []
for line in output.splitlines():
parts = line.split(':')
# UUID:NAME:TYPE
if len(parts) >= 3 and "wireless" in parts[-1]:
networks.append({
"network_id": parts[0],
"ssid": parts[1],
"bssid": parts[2],
"flags": parts[3]
"bssid": "",
"flags": parts[-1]
})
return networks
return networks
def scan_networks(self):
"""扫描范围内的 wifi"""
self._run_wpa_cli("scan")
time.sleep(3) # 等待扫描完成
output = self._run_wpa_cli("scan_results")
networks = []
lines = output.splitlines()
if len(lines) > 1:
for line in lines[1:]:
# bssid / frequency / signal level / flags / ssid
parts = line.split('\t')
if len(parts) >= 5:
networks.append({
"bssid": parts[0],
"frequency": parts[1],
"signal_level": parts[2],
"flags": parts[3],
"ssid": parts[4]
})
return networks
if self.backend == "wpa_cli":
self._run_wpa_cli("scan")
time.sleep(3)
output = self._run_wpa_cli("scan_results")
networks = []
lines = output.splitlines()
if len(lines) > 1:
for line in lines[1:]:
parts = line.split('\t')
if len(parts) >= 5:
networks.append({
"bssid": parts[0],
"frequency": parts[1],
"signal_level": parts[2],
"flags": parts[3],
"ssid": parts[4]
})
return networks
else:
output = self._run_nmcli("-t", "-m", "multiline", "-f", "BSSID,FREQ,SIGNAL,SECURITY,SSID", "device", "wifi", "list", "--rescan", "yes")
networks = []
current = {}
for line in output.splitlines():
if ':' in line:
k, v = line.split(':', 1)
current[k] = v
if k == "SSID":
networks.append({
"bssid": current.get("BSSID", ""),
"frequency": current.get("FREQ", "").replace(" MHz", ""),
"signal_level": current.get("SIGNAL", ""),
"flags": current.get("SECURITY", ""),
"ssid": current.get("SSID", "")
})
current = {}
return networks
def connect_wifi(self, ssid, password=None):
"""连接普通 Wi-Fi (WPA2-PSK)"""
network_id = self._run_wpa_cli("add_network")
if not network_id.isdigit():
return False
self._run_wpa_cli("set_network", network_id, "ssid", f'"{ssid}"')
if password:
self._run_wpa_cli("set_network", network_id, "psk", f'"{password}"')
if self.backend == "wpa_cli":
network_id = self._run_wpa_cli("add_network")
if not network_id.isdigit(): return False
self._run_wpa_cli("set_network", network_id, "ssid", f'"{ssid}"')
if password: self._run_wpa_cli("set_network", network_id, "psk", f'"{password}"')
else: self._run_wpa_cli("set_network", network_id, "key_mgmt", "NONE")
self._run_wpa_cli("enable_network", network_id)
self._run_wpa_cli("select_network", network_id)
self._run_wpa_cli("save_config")
return True
else:
self._run_wpa_cli("set_network", network_id, "key_mgmt", "NONE")
self._run_wpa_cli("enable_network", network_id)
self._run_wpa_cli("select_network", network_id)
self._run_wpa_cli("save_config")
return True
args = ["device", "wifi", "connect", ssid, "ifname", self.interface]
if password:
args.extend(["password", password])
res = self._run_nmcli(*args)
return "successfully" in res.lower() or "成功" in res
def connect_eap(self, ssid, identity, password):
"""连接企业级 Wi-Fi (WPA-EAP PEAP/MSCHAPv2)"""
network_id = self._run_wpa_cli("add_network")
if not network_id.isdigit():
if self.backend == "wpa_cli":
network_id = self._run_wpa_cli("add_network")
if not network_id.isdigit(): return False
self._run_wpa_cli("set_network", network_id, "ssid", f'"{ssid}"')
self._run_wpa_cli("set_network", network_id, "key_mgmt", "WPA-EAP")
self._run_wpa_cli("set_network", network_id, "eap", "PEAP")
self._run_wpa_cli("set_network", network_id, "phase2", '"auth=MSCHAPV2"')
self._run_wpa_cli("set_network", network_id, "identity", f'"{identity}"')
self._run_wpa_cli("set_network", network_id, "password", f'"{password}"')
self._run_wpa_cli("enable_network", network_id)
self._run_wpa_cli("select_network", network_id)
self._run_wpa_cli("save_config")
return True
else:
res = self._run_nmcli("con", "add", "type", "wifi", "con-name", ssid, "ifname", self.interface, "ssid", ssid,
"--", "802-11-wireless-security.key-mgmt", "wpa-eap", "802-1x.eap", "peap",
"802-1x.phase2-auth", "mschapv2", "802-1x.identity", identity, "802-1x.password", password)
if "successfully" in res.lower() or "成功" in res:
self._run_nmcli("con", "up", ssid)
return True
return False
self._run_wpa_cli("set_network", network_id, "ssid", f'"{ssid}"')
self._run_wpa_cli("set_network", network_id, "key_mgmt", "WPA-EAP")
self._run_wpa_cli("set_network", network_id, "eap", "PEAP")
self._run_wpa_cli("set_network", network_id, "phase2", '"auth=MSCHAPV2"')
self._run_wpa_cli("set_network", network_id, "identity", f'"{identity}"')
self._run_wpa_cli("set_network", network_id, "password", f'"{password}"')
self._run_wpa_cli("enable_network", network_id)
self._run_wpa_cli("select_network", network_id)
self._run_wpa_cli("save_config")
return True
def connect_network_id(self, network_id):
"""通过 network_id 连接已保存的网络"""
ret1 = self._run_wpa_cli("select_network", str(network_id))
self._run_wpa_cli("save_config")
return bool(ret1)
if self.backend == "wpa_cli":
ret1 = self._run_wpa_cli("select_network", str(network_id))
self._run_wpa_cli("save_config")
return bool(ret1)
else:
res = self._run_nmcli("connection", "up", "uuid", str(network_id))
return "successfully" in res.lower() or "成功" in res
def remove_network(self, network_id):
"""删除某个已保存的网络"""
self._run_wpa_cli("remove_network", str(network_id))
self._run_wpa_cli("save_config")
if self.backend == "wpa_cli":
self._run_wpa_cli("remove_network", str(network_id))
self._run_wpa_cli("save_config")
else:
self._run_nmcli("connection", "delete", "uuid", str(network_id))
def get_current_status(self):
"""获取当前网络状态"""
output = self._run_wpa_cli("status")
status = {}
for line in output.splitlines():
if '=' in line:
key, val = line.split('=', 1)
status[key] = val
return status
if self.backend == "wpa_cli":
output = self._run_wpa_cli("status")
status = {}
for line in output.splitlines():
if '=' in line:
key, val = line.split('=', 1)
status[key] = val
return status
else:
output = self._run_nmcli("-t", "-m", "multiline", "-f", "GENERAL.STATE,GENERAL.CONNECTION,IP4.ADDRESS", "device", "show", self.interface)
status = {"wpa_state": "DISCONNECTED", "ssid": "", "signal_level": None}
for line in output.splitlines():
if line.startswith("GENERAL.STATE:"):
state_val = line.split(':', 1)[1]
if "connected" in state_val.lower():
status["wpa_state"] = "COMPLETED"
elif line.startswith("GENERAL.CONNECTION:"):
conn_val = line.split(':', 1)[1]
if conn_val:
status["ssid"] = conn_val
elif line.startswith("IP4.ADDRESS[1]:"):
ip_val = line.split(':', 1)[1]
status["ip_address"] = ip_val.split('/')[0]
# 额外获取当前连接网络的信号强度nmcli device wifi 才有 SIGNAL 字段)
if status["wpa_state"] == "COMPLETED":
wifi_out = self._run_nmcli("-t", "-f", "SSID,SIGNAL,IN-USE", "device", "wifi")
for line in wifi_out.splitlines():
parts = line.split(':')
if len(parts) >= 3 and parts[2] == '*':
status["signal_level"] = parts[1] # SIGNAL 字段(百分比 0-100
break
return status
def open_hotspot(self, ssid, password, channel=6):
"""
开启热点 (AP 模式)
注意:要求网卡和 wpa_supplicant 均支持 AP 模式 (mode=2)
"""
network_id = self._run_wpa_cli("add_network")
if not network_id.isdigit():
return False
self._run_wpa_cli("set_network", network_id, "ssid", f'"{ssid}"')
self._run_wpa_cli("set_network", network_id, "mode", "2")
self._run_wpa_cli("set_network", network_id, "key_mgmt", "WPA-PSK")
self._run_wpa_cli("set_network", network_id, "psk", f'"{password}"')
self._run_wpa_cli("set_network", network_id, "frequency", str(2412 + (channel - 1) * 5))
self._run_wpa_cli("select_network", network_id)
self._run_wpa_cli("save_config")
return network_id
if self.backend == "wpa_cli":
network_id = self._run_wpa_cli("add_network")
if not network_id.isdigit(): return False
self._run_wpa_cli("set_network", network_id, "ssid", f'"{ssid}"')
self._run_wpa_cli("set_network", network_id, "mode", "2")
self._run_wpa_cli("set_network", network_id, "key_mgmt", "WPA-PSK")
self._run_wpa_cli("set_network", network_id, "psk", f'"{password}"')
self._run_wpa_cli("set_network", network_id, "frequency", str(2412 + (channel - 1) * 5))
self._run_wpa_cli("select_network", network_id)
self._run_wpa_cli("save_config")
return network_id
else:
self._run_nmcli("device", "wifi", "hotspot", "ifname", self.interface, "con-name", ssid, "ssid", ssid, "band", "bg", "channel", str(channel), "password", password)
networks = self.list_saved_networks()
for net in networks:
if net.get("ssid") == ssid:
return net.get("network_id")
return ssid
def close_hotspot(self, network_id=None):
"""关闭热点"""
if network_id is not None:
self._run_wpa_cli("remove_network", str(network_id))
self._run_wpa_cli("reconfigure")
self._run_wpa_cli("save_config")
if self.backend == "wpa_cli":
if network_id is not None:
self._run_wpa_cli("remove_network", str(network_id))
self._run_wpa_cli("reconfigure")
self._run_wpa_cli("save_config")
else:
if network_id is not None:
self._run_nmcli("connection", "down", str(network_id))
self._run_nmcli("connection", "delete", str(network_id))
if __name__ == "__main__":
# Example Usage
wifi = WifiManager("wlan0")
wifi = WifiManager("wlan0", backend="nmcli")
print("Current status:", wifi.get_current_status())
print("Saved networks:", wifi.list_saved_networks())