修复配网时城市输入乱码的问题
This commit is contained in:
@@ -139,6 +139,7 @@ async def lcd_set(request):
|
|||||||
elif k == "ui_type":
|
elif k == "ui_type":
|
||||||
display.ui_type = v
|
display.ui_type = v
|
||||||
config.set(k, v)
|
config.set(k, v)
|
||||||
|
config.write()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
ack["status"] = "error"
|
ack["status"] = "error"
|
||||||
ack["message"] = str(e)
|
ack["message"] = str(e)
|
||||||
@@ -212,7 +213,7 @@ async def fetch_weather_data(city=None):
|
|||||||
|
|
||||||
# 从配置文件获取城市,如果没有提供则使用配置中的值
|
# 从配置文件获取城市,如果没有提供则使用配置中的值
|
||||||
if not city:
|
if not city:
|
||||||
city = config.get("city") or "北京"
|
city = config.get("cityid") or "北京"
|
||||||
|
|
||||||
print(f"正在获取{city}天气数据...")
|
print(f"正在获取{city}天气数据...")
|
||||||
# 从配置获取API基础URL,默认使用官方API
|
# 从配置获取API基础URL,默认使用官方API
|
||||||
|
|||||||
@@ -119,11 +119,13 @@ class HTTPServer(BaseServer):
|
|||||||
ssid = unquote(params.get(b"ssid", None))
|
ssid = unquote(params.get(b"ssid", None))
|
||||||
password = unquote(params.get(b"password", ""))
|
password = unquote(params.get(b"password", ""))
|
||||||
city = unquote(params.get(b"city", None))
|
city = unquote(params.get(b"city", None))
|
||||||
|
cityid = params.get(b"city", None)
|
||||||
|
|
||||||
# 使用全局Config实例保存配置
|
# 使用全局Config实例保存配置
|
||||||
config.set("ssid", ssid)
|
config.set("ssid", ssid)
|
||||||
config.set("password", password)
|
config.set("password", password)
|
||||||
config.set("city", city)
|
config.set("city", city)
|
||||||
|
config.set("cityid", cityid)
|
||||||
if config.write():
|
if config.write():
|
||||||
print("Configuration saved successfully")
|
print("Configuration saved successfully")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ placeholder="例如:北京"
|
|||||||
可输入城市名称或城市ID(<a
|
可输入城市名称或城市ID(<a
|
||||||
href="https://mapopen-website-wiki.cdn.bcebos.com/cityList/weather_district_id.csv"
|
href="https://mapopen-website-wiki.cdn.bcebos.com/cityList/weather_district_id.csv"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
download
|
||||||
>查看城市ID列表</a
|
>查看城市ID列表</a
|
||||||
>)
|
>)
|
||||||
</small></div><div class="form-group"><label class="form-label">自动熄屏时间</label
|
</small></div><div class="form-group"><label class="form-label">自动熄屏时间</label
|
||||||
@@ -348,6 +349,7 @@ showMessage("城市名称不能为空", "error");
|
|||||||
return;
|
return;
|
||||||
}const configData = {
|
}const configData = {
|
||||||
city: city,
|
city: city,
|
||||||
|
cityid: encodeURIComponent(city),
|
||||||
};// 只有当输入了熄屏时间时才添加到配置中
|
};// 只有当输入了熄屏时间时才添加到配置中
|
||||||
if (standbyTime !== "") {
|
if (standbyTime !== "") {
|
||||||
configData.standby_time = standbyTime;
|
configData.standby_time = standbyTime;
|
||||||
|
|||||||
@@ -1,318 +1,288 @@
|
|||||||
<html>
|
<html><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>WiFi认证</title><style>
|
||||||
<head>
|
body {
|
||||||
<meta charset="utf-8" />
|
font-family: sans-serif;
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
background: #3498db;
|
||||||
<title>WiFi认证</title>
|
width: 100%;
|
||||||
<style>
|
text-align: center;
|
||||||
body {
|
margin: 20px 0;
|
||||||
font-family: sans-serif;
|
position: relative;
|
||||||
background: #3498db;
|
}
|
||||||
width: 100%;
|
p {
|
||||||
text-align: center;
|
font-size: 12px;
|
||||||
margin: 20px 0;
|
text-decoration: none;
|
||||||
position: relative;
|
color: #fff;
|
||||||
}
|
}
|
||||||
p {
|
h1 {
|
||||||
font-size: 12px;
|
font-size: 1.5em;
|
||||||
text-decoration: none;
|
color: #525252;
|
||||||
color: #fff;
|
}
|
||||||
}
|
.box {
|
||||||
h1 {
|
background: white;
|
||||||
font-size: 1.5em;
|
width: 40ch;
|
||||||
color: #525252;
|
border-radius: 6px;
|
||||||
}
|
margin: 0 auto;
|
||||||
.box {
|
padding: 10px 0;
|
||||||
background: white;
|
position: relative;
|
||||||
width: 40ch;
|
}
|
||||||
border-radius: 6px;
|
input[type="text"],
|
||||||
margin: 0 auto;
|
input[type="password"] {
|
||||||
padding: 10px 0;
|
background: #ecf0f1;
|
||||||
position: relative;
|
border: #ccc 1px solid;
|
||||||
}
|
border-bottom: #ccc 2px solid;
|
||||||
input[type="text"],
|
padding: 8px;
|
||||||
input[type="password"] {
|
width: 80%;
|
||||||
background: #ecf0f1;
|
color: #000;
|
||||||
border: #ccc 1px solid;
|
margin-top: 10px;
|
||||||
border-bottom: #ccc 2px solid;
|
font-size: 1em;
|
||||||
padding: 8px;
|
border-radius: 4px;
|
||||||
width: 80%;
|
}
|
||||||
color: #000;
|
.btn {
|
||||||
margin-top: 10px;
|
background: #2ecc71;
|
||||||
font-size: 1em;
|
width: 80%;
|
||||||
border-radius: 4px;
|
padding: 8px 0;
|
||||||
}
|
color: white;
|
||||||
.btn {
|
border-radius: 4px;
|
||||||
background: #2ecc71;
|
border: #27ae60 1px solid;
|
||||||
width: 80%;
|
margin: 20 auto;
|
||||||
padding: 8px 0;
|
font-weight: 800;
|
||||||
color: white;
|
font-size: 0.9em;
|
||||||
border-radius: 4px;
|
cursor: pointer;
|
||||||
border: #27ae60 1px solid;
|
}
|
||||||
margin: 20 auto;
|
.btn:hover {
|
||||||
font-weight: 800;
|
background: #27ae60;
|
||||||
font-size: 0.9em;
|
}
|
||||||
cursor: pointer;
|
.config-title {
|
||||||
}
|
font-size: 1em;
|
||||||
.btn:hover {
|
color: #525252;
|
||||||
background: #27ae60;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
.config-title {
|
.wifi-list {
|
||||||
font-size: 1em;
|
width: 80%;
|
||||||
color: #525252;
|
max-height: 200px;
|
||||||
margin-top: 15px;
|
overflow-y: auto;
|
||||||
}
|
margin: 10px auto;
|
||||||
.wifi-list {
|
text-align: left;
|
||||||
width: 80%;
|
border: 1px solid #eee;
|
||||||
max-height: 200px;
|
background: #f8f8f8;
|
||||||
overflow-y: auto;
|
border-radius: 4px;
|
||||||
margin: 10px auto;
|
padding: 5px;
|
||||||
text-align: left;
|
}
|
||||||
border: 1px solid #eee;
|
.wifi-item {
|
||||||
background: #f8f8f8;
|
padding: 5px;
|
||||||
border-radius: 4px;
|
cursor: pointer;
|
||||||
padding: 5px;
|
border-bottom: 1px solid #eee;
|
||||||
}
|
display: flex;
|
||||||
.wifi-item {
|
align-items: center;
|
||||||
padding: 5px;
|
justify-content: space-between;
|
||||||
cursor: pointer;
|
}
|
||||||
border-bottom: 1px solid #eee;
|
.wifi-item:hover {
|
||||||
display: flex;
|
background: #e0e0e0;
|
||||||
align-items: center;
|
}
|
||||||
justify-content: space-between;
|
.wifi-name {
|
||||||
}
|
flex-grow: 1;
|
||||||
.wifi-item:hover {
|
}
|
||||||
background: #e0e0e0;
|
.wifi-signal {
|
||||||
}
|
font-size: 12px;
|
||||||
.wifi-name {
|
color: #888;
|
||||||
flex-grow: 1;
|
}
|
||||||
}
|
.refresh-btn {
|
||||||
.wifi-signal {
|
position: absolute;
|
||||||
font-size: 12px;
|
top: 10px;
|
||||||
color: #888;
|
right: 10px;
|
||||||
}
|
background: none;
|
||||||
.refresh-btn {
|
border: none;
|
||||||
position: absolute;
|
cursor: pointer;
|
||||||
top: 10px;
|
font-size: 20px;
|
||||||
right: 10px;
|
color: #7f8c8d;
|
||||||
background: none;
|
width: 30px;
|
||||||
border: none;
|
height: 30px;
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
font-size: 20px;
|
align-items: center;
|
||||||
color: #7f8c8d;
|
justify-content: center;
|
||||||
width: 30px;
|
border-radius: 50%;
|
||||||
height: 30px;
|
}
|
||||||
display: flex;
|
.refresh-btn:hover {
|
||||||
align-items: center;
|
background: #ecf0f1;
|
||||||
justify-content: center;
|
}
|
||||||
border-radius: 50%;
|
.refresh-btn:disabled {
|
||||||
}
|
color: #bdc3c7;
|
||||||
.refresh-btn:hover {
|
cursor: not-allowed;
|
||||||
background: #ecf0f1;
|
}
|
||||||
}
|
.wifi-icon {
|
||||||
.refresh-btn:disabled {
|
position: relative;
|
||||||
color: #bdc3c7;
|
display: inline-block;
|
||||||
cursor: not-allowed;
|
width: 18px;
|
||||||
}
|
height: 12px;
|
||||||
.wifi-icon {
|
margin-right: 5px;
|
||||||
position: relative;
|
}
|
||||||
display: inline-block;
|
.wifi-icon-bar {
|
||||||
width: 18px;
|
position: absolute;
|
||||||
height: 12px;
|
bottom: 0;
|
||||||
margin-right: 5px;
|
background: #7f8c8d;
|
||||||
}
|
border-radius: 1px;
|
||||||
.wifi-icon-bar {
|
}
|
||||||
position: absolute;
|
.wifi-icon-bar:nth-child(1) {
|
||||||
bottom: 0;
|
left: 0;
|
||||||
background: #7f8c8d;
|
width: 3px;
|
||||||
border-radius: 1px;
|
height: 3px;
|
||||||
}
|
}
|
||||||
.wifi-icon-bar:nth-child(1) {
|
.wifi-icon-bar:nth-child(2) {
|
||||||
left: 0;
|
left: 5px;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
height: 3px;
|
height: 6px;
|
||||||
}
|
}
|
||||||
.wifi-icon-bar:nth-child(2) {
|
.wifi-icon-bar:nth-child(3) {
|
||||||
left: 5px;
|
left: 10px;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
height: 6px;
|
height: 9px;
|
||||||
}
|
}
|
||||||
.wifi-icon-bar:nth-child(3) {
|
.wifi-icon-bar:nth-child(4) {
|
||||||
left: 10px;
|
left: 15px;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
height: 9px;
|
height: 12px;
|
||||||
}
|
}
|
||||||
.wifi-icon-bar:nth-child(4) {
|
.wifi-signal-4 .wifi-icon-bar {
|
||||||
left: 15px;
|
background: #2ecc71;
|
||||||
width: 3px;
|
}
|
||||||
height: 12px;
|
.wifi-signal-3 .wifi-icon-bar:nth-child(1),
|
||||||
}
|
.wifi-signal-3 .wifi-icon-bar:nth-child(2),
|
||||||
.wifi-signal-4 .wifi-icon-bar {
|
.wifi-signal-3 .wifi-icon-bar:nth-child(3) {
|
||||||
background: #2ecc71;
|
background: #f1c40f;
|
||||||
}
|
}
|
||||||
.wifi-signal-3 .wifi-icon-bar:nth-child(1),
|
.wifi-signal-2 .wifi-icon-bar:nth-child(1),
|
||||||
.wifi-signal-3 .wifi-icon-bar:nth-child(2),
|
.wifi-signal-2 .wifi-icon-bar:nth-child(2) {
|
||||||
.wifi-signal-3 .wifi-icon-bar:nth-child(3) {
|
background: #e67e22;
|
||||||
background: #f1c40f;
|
}
|
||||||
}
|
.wifi-signal-1 .wifi-icon-bar:nth-child(1) {
|
||||||
.wifi-signal-2 .wifi-icon-bar:nth-child(1),
|
background: #e74c3c;
|
||||||
.wifi-signal-2 .wifi-icon-bar:nth-child(2) {
|
}
|
||||||
background: #e67e22;
|
/* 遮罩层样式 */
|
||||||
}
|
.overlay {
|
||||||
.wifi-signal-1 .wifi-icon-bar:nth-child(1) {
|
position: fixed;
|
||||||
background: #e74c3c;
|
top: 0;
|
||||||
}
|
left: 0;
|
||||||
/* 遮罩层样式 */
|
width: 100%;
|
||||||
.overlay {
|
height: 100%;
|
||||||
position: fixed;
|
background: rgba(0, 0, 0, 0.7);
|
||||||
top: 0;
|
display: none;
|
||||||
left: 0;
|
z-index: 1000;
|
||||||
width: 100%;
|
justify-content: center;
|
||||||
height: 100%;
|
align-items: center;
|
||||||
background: rgba(0, 0, 0, 0.7);
|
}
|
||||||
display: none;
|
.overlay-content {
|
||||||
z-index: 1000;
|
background: white;
|
||||||
justify-content: center;
|
padding: 30px;
|
||||||
align-items: center;
|
border-radius: 8px;
|
||||||
}
|
text-align: center;
|
||||||
.overlay-content {
|
max-width: 80%;
|
||||||
background: white;
|
}
|
||||||
padding: 30px;
|
.spinner-small {
|
||||||
border-radius: 8px;
|
width: 30px;
|
||||||
text-align: center;
|
height: 30px;
|
||||||
max-width: 80%;
|
border: 3px solid #f3f3f3;
|
||||||
}
|
border-top: 3px solid #3498db;
|
||||||
.spinner-small {
|
border-radius: 50%;
|
||||||
width: 30px;
|
margin: 15px auto;
|
||||||
height: 30px;
|
animation: spin 1.5s linear infinite;
|
||||||
border: 3px solid #f3f3f3;
|
}
|
||||||
border-top: 3px solid #3498db;
|
</style></head><body><form action="/login" method="get" class="box"><h1>WiFi 配置</h1><button
|
||||||
border-radius: 50%;
|
type="button"
|
||||||
margin: 15px auto;
|
class="refresh-btn"
|
||||||
animation: spin 1.5s linear infinite;
|
onclick="refreshList()"
|
||||||
}
|
title="刷新WiFi列表"
|
||||||
</style>
|
>
|
||||||
</head>
|
↻
|
||||||
<body>
|
</button><div id="wifiList" class="wifi-list"></div><input
|
||||||
<form action="/login" method="get" class="box">
|
type="text"
|
||||||
<h1>WiFi 配置</h1>
|
id="ssid"
|
||||||
<button
|
placeholder="WiFi名称"
|
||||||
type="button"
|
name="ssid"
|
||||||
class="refresh-btn"
|
required
|
||||||
onclick="refreshList()"
|
/><br /><input
|
||||||
title="刷新WiFi列表"
|
type="password"
|
||||||
>
|
id="pwd"
|
||||||
↻
|
placeholder="WiFi密码"
|
||||||
</button>
|
name="password"
|
||||||
<div id="wifiList" class="wifi-list"></div>
|
/><br /><input
|
||||||
<input
|
type="text"
|
||||||
type="text"
|
placeholder="城市名称"
|
||||||
id="ssid"
|
name="city"
|
||||||
placeholder="WiFi名称"
|
value=""
|
||||||
name="ssid"
|
/><br /><button type="submit" class="btn">保存配置</button></form><div class="overlay" id="connectingOverlay"><div class="overlay-content"><h2>正在连接到WiFi</h2><div class="spinner-small"></div><p>设备正在尝试连接,请稍候...</p></div></div><script>
|
||||||
required
|
window.onload = function () {
|
||||||
/><br />
|
fetchWifiList();// 添加表单提交事件监听
|
||||||
<input
|
document
|
||||||
type="password"
|
.querySelector(".box")
|
||||||
id="pwd"
|
.addEventListener("submit", function (e) {
|
||||||
placeholder="WiFi密码"
|
// 显示遮罩层
|
||||||
name="password"
|
document.getElementById(
|
||||||
/><br />
|
"connectingOverlay",
|
||||||
<input
|
).style.display = "flex";
|
||||||
type="text"
|
});
|
||||||
placeholder="城市名称"
|
};
|
||||||
name="city"
|
function fetchWifiList() {
|
||||||
value=""
|
const listContainer = document.getElementById("wifiList");
|
||||||
/><br />
|
listContainer.innerHTML = "Loading...";
|
||||||
<button type="submit" class="btn">保存配置</button>
|
fetch("/scan")
|
||||||
</form>
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
<!-- 遮罩层 -->
|
if (data.networks) {
|
||||||
<div class="overlay" id="connectingOverlay">
|
data.networks.sort((a, b) => b.rssi - a.rssi);
|
||||||
<div class="overlay-content">
|
displayWifiList(data.networks);
|
||||||
<h2>正在连接到WiFi</h2>
|
}
|
||||||
<div class="spinner-small"></div>
|
})
|
||||||
<p>设备正在尝试连接,请稍候...</p>
|
.catch((error) => {
|
||||||
</div>
|
console.error("Error fetching WiFi list:", error);
|
||||||
</div>
|
});
|
||||||
<script>
|
}
|
||||||
window.onload = function () {
|
function getSignalLevel(rssi) {
|
||||||
fetchWifiList();
|
if (rssi >= -50) return 4;
|
||||||
|
if (rssi >= -60) return 3;
|
||||||
// 添加表单提交事件监听
|
if (rssi >= -70) return 2;
|
||||||
document
|
return 1;
|
||||||
.querySelector(".box")
|
}
|
||||||
.addEventListener("submit", function (e) {
|
function createSignalIcon(signalLevel) {
|
||||||
// 显示遮罩层
|
const icon = document.createElement("span");
|
||||||
document.getElementById(
|
icon.className = `wifi-icon wifi-signal-${signalLevel}`;
|
||||||
"connectingOverlay",
|
for (let i = 0; i < 4; i++) {
|
||||||
).style.display = "flex";
|
const bar = document.createElement("span");
|
||||||
});
|
bar.className = "wifi-icon-bar";
|
||||||
};
|
icon.appendChild(bar);
|
||||||
function fetchWifiList() {
|
}
|
||||||
const listContainer = document.getElementById("wifiList");
|
return icon;
|
||||||
listContainer.innerHTML = "Loading...";
|
}
|
||||||
fetch("/scan")
|
function displayWifiList(networks) {
|
||||||
.then((response) => response.json())
|
const listContainer = document.getElementById("wifiList");
|
||||||
.then((data) => {
|
listContainer.innerHTML = "";
|
||||||
if (data.networks) {
|
for (const network of networks) {
|
||||||
data.networks.sort((a, b) => b.rssi - a.rssi);
|
const item = document.createElement("div");
|
||||||
displayWifiList(data.networks);
|
item.className = "wifi-item";
|
||||||
}
|
const nameContainer = document.createElement("div");
|
||||||
})
|
nameContainer.className = "wifi-name";
|
||||||
.catch((error) => {
|
const signalLevel = getSignalLevel(network.rssi);
|
||||||
console.error("Error fetching WiFi list:", error);
|
nameContainer.appendChild(createSignalIcon(signalLevel));
|
||||||
});
|
const nameText = document.createTextNode(network.ssid);
|
||||||
}
|
nameContainer.appendChild(nameText);
|
||||||
function getSignalLevel(rssi) {
|
const signalContainer = document.createElement("div");
|
||||||
if (rssi >= -50) return 4;
|
signalContainer.className = "wifi-signal";
|
||||||
if (rssi >= -60) return 3;
|
signalContainer.textContent = `${network.rssi} dBm`;
|
||||||
if (rssi >= -70) return 2;
|
item.appendChild(nameContainer);
|
||||||
return 1;
|
item.appendChild(signalContainer);
|
||||||
}
|
item.onclick = function () {
|
||||||
function createSignalIcon(signalLevel) {
|
document.getElementById("ssid").value = network.ssid;
|
||||||
const icon = document.createElement("span");
|
document.getElementById("pwd").focus();
|
||||||
icon.className = `wifi-icon wifi-signal-${signalLevel}`;
|
};
|
||||||
for (let i = 0; i < 4; i++) {
|
listContainer.appendChild(item);
|
||||||
const bar = document.createElement("span");
|
}
|
||||||
bar.className = "wifi-icon-bar";
|
}
|
||||||
icon.appendChild(bar);
|
function refreshList() {
|
||||||
}
|
const btn = document.querySelector(".refresh-btn");
|
||||||
return icon;
|
btn.innerHTML = "⟳";
|
||||||
}
|
btn.disabled = true;
|
||||||
function displayWifiList(networks) {
|
fetchWifiList();
|
||||||
const listContainer = document.getElementById("wifiList");
|
setTimeout(() => {
|
||||||
listContainer.innerHTML = "";
|
btn.innerHTML = "↻";
|
||||||
for (const network of networks) {
|
btn.disabled = false;
|
||||||
const item = document.createElement("div");
|
}, 1000);
|
||||||
item.className = "wifi-item";
|
}
|
||||||
const nameContainer = document.createElement("div");
|
</script></body></html>
|
||||||
nameContainer.className = "wifi-name";
|
|
||||||
const signalLevel = getSignalLevel(network.rssi);
|
|
||||||
nameContainer.appendChild(createSignalIcon(signalLevel));
|
|
||||||
const nameText = document.createTextNode(network.ssid);
|
|
||||||
nameContainer.appendChild(nameText);
|
|
||||||
const signalContainer = document.createElement("div");
|
|
||||||
signalContainer.className = "wifi-signal";
|
|
||||||
signalContainer.textContent = `${network.rssi} dBm`;
|
|
||||||
item.appendChild(nameContainer);
|
|
||||||
item.appendChild(signalContainer);
|
|
||||||
item.onclick = function () {
|
|
||||||
document.getElementById("ssid").value = network.ssid;
|
|
||||||
document.getElementById('pwd').focus();
|
|
||||||
};
|
|
||||||
listContainer.appendChild(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function refreshList() {
|
|
||||||
const btn = document.querySelector(".refresh-btn");
|
|
||||||
btn.innerHTML = "⟳";
|
|
||||||
btn.disabled = true;
|
|
||||||
fetchWifiList();
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.innerHTML = "↻";
|
|
||||||
btn.disabled = false;
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user