fix: 优化 README 内容问题,优化绘图
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
- 手动去 Github 下载 [LXGWWenKai-Medium 字体](https://github.com/lxgw/LxgwWenKai) 保存到fonts文件夹中,或者使用 wget 进行获取,然后修改配置文件
|
- 手动去 Github 下载 [LXGWWenKai-Medium 字体](https://github.com/lxgw/LxgwWenKai) 保存到fonts文件夹中,或者使用 wget 进行获取,然后修改配置文件
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -L -o ./fonts/LXGWWenKaiMono-Medium.ttf https://github.5700.cf/https://github.com/lxgw/LxgwWenKai/releases/download/v1.521/LXGWWenKaiMono-Medium.ttf
|
curl -L -o ./fonts/LXGWWenKai-Medium.ttf https://github.5700.cf/https://github.com/lxgw/LxgwWenKai/releases/download/v1.521/LXGWWenKai-Medium.ttf
|
||||||
```
|
```
|
||||||
|
|
||||||
- `UID` 获取,使用支付宝进行扫描下方二维码即可获得 `uid`
|
- `UID` 获取,使用支付宝进行扫描下方二维码即可获得 `uid`
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -30,7 +30,7 @@ async def main():
|
|||||||
|
|
||||||
start_scheduler()
|
start_scheduler()
|
||||||
|
|
||||||
await SD().push()
|
# await SD().push()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(3600)
|
await asyncio.sleep(3600)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def start_scheduler():
|
|||||||
sd.push,
|
sd.push,
|
||||||
trigger="cron",
|
trigger="cron",
|
||||||
hour=8,
|
hour=8,
|
||||||
minute=0,
|
minute=30,
|
||||||
id="push_gzh",
|
id="push_gzh",
|
||||||
replace_existing=True,
|
replace_existing=True,
|
||||||
max_instances=1,
|
max_instances=1,
|
||||||
|
|||||||
@@ -16,16 +16,70 @@ FONT = font_manager.FontProperties(fname=config.FONT_PATH)
|
|||||||
plt.rcParams["axes.unicode_minus"] = False
|
plt.rcParams["axes.unicode_minus"] = False
|
||||||
|
|
||||||
|
|
||||||
def plot_line(times, values, title, ylabel, out_path):
|
def plot_line(
|
||||||
plt.figure(figsize=(8, 4))
|
times,
|
||||||
plt.plot(times, values, marker="o")
|
normal_values,
|
||||||
|
title,
|
||||||
|
ylabel,
|
||||||
|
out_path,
|
||||||
|
free_values=None, # ✅ 免费额度可选
|
||||||
|
):
|
||||||
|
has_free = free_values is not None and len(free_values) > 0
|
||||||
|
|
||||||
plt.title(title, fontproperties=FONT)
|
if has_free:
|
||||||
plt.xlabel("时间", fontproperties=FONT)
|
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
|
||||||
plt.ylabel(ylabel, fontproperties=FONT)
|
else:
|
||||||
|
fig, ax1 = plt.subplots(1, 1, figsize=(8, 4))
|
||||||
|
ax2 = None
|
||||||
|
|
||||||
|
# ===== 普通额度 =====
|
||||||
|
ax1.plot(times, normal_values, marker="o")
|
||||||
|
ax1.set_title(
|
||||||
|
f"{title}(普通额度)" if has_free else title,
|
||||||
|
fontproperties=FONT,
|
||||||
|
)
|
||||||
|
ax1.set_ylabel(ylabel, fontproperties=FONT)
|
||||||
|
ax1.grid(True)
|
||||||
|
|
||||||
|
for i, (x, y) in enumerate(zip(times, normal_values)):
|
||||||
|
dy = 8 if i == 0 or y >= normal_values[i - 1] else -12
|
||||||
|
|
||||||
|
ax1.annotate(
|
||||||
|
f"{y}",
|
||||||
|
(x, y),
|
||||||
|
textcoords="offset points",
|
||||||
|
xytext=(0, dy),
|
||||||
|
ha="center",
|
||||||
|
fontsize=10,
|
||||||
|
fontproperties=FONT,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ===== 免费额度(可选) =====
|
||||||
|
if has_free and ax2:
|
||||||
|
ax2.plot(times, free_values, marker="o", linestyle="--")
|
||||||
|
ax2.set_title(f"{title}(免费额度)", fontproperties=FONT)
|
||||||
|
ax2.set_xlabel("时间", fontproperties=FONT)
|
||||||
|
ax2.set_ylabel(ylabel, fontproperties=FONT)
|
||||||
|
ax2.grid(True)
|
||||||
|
|
||||||
|
for i, (x, y) in enumerate(zip(times, free_values)):
|
||||||
|
# 免费额度同样根据趋势决定标注方向
|
||||||
|
if i == 0:
|
||||||
|
dy = -8
|
||||||
|
else:
|
||||||
|
dy = -8 if y <= free_values[i - 1] else 8
|
||||||
|
|
||||||
|
ax2.annotate(
|
||||||
|
f"{y}",
|
||||||
|
(x, y),
|
||||||
|
textcoords="offset points",
|
||||||
|
xytext=(0, dy),
|
||||||
|
ha="center",
|
||||||
|
fontsize=8,
|
||||||
|
fontproperties=FONT,
|
||||||
|
)
|
||||||
|
|
||||||
plt.xticks(rotation=45, fontproperties=FONT)
|
plt.xticks(rotation=45, fontproperties=FONT)
|
||||||
plt.grid(True)
|
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
plt.savefig(out_path, dpi=150)
|
plt.savefig(out_path, dpi=150)
|
||||||
plt.close()
|
plt.close()
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
|
import time
|
||||||
from services.statistics import get_ammeter_left_ele, get_water_left
|
from services.statistics import get_ammeter_left_ele, get_water_left
|
||||||
from services.plot import plot_line
|
from services.plot import plot_line
|
||||||
|
|
||||||
|
|
||||||
async def render_ammeter_chart():
|
async def render_ammeter_chart():
|
||||||
times, values = await get_ammeter_left_ele(limit=24)
|
times, left_ele, left_free_ele = await get_ammeter_left_ele(limit=24)
|
||||||
|
|
||||||
if not times:
|
if not times:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
out = "data/ammeter.png"
|
out = "data/ammeter.png"
|
||||||
|
|
||||||
|
time_range = f"{time.strftime("%Y-%m-%d %H:%M", time.localtime(times[0] / 1000))} ~ {time.strftime("%Y-%m-%d %H:%M", time.localtime(times[-1] / 1000))}"
|
||||||
|
|
||||||
plot_line(
|
plot_line(
|
||||||
times=times,
|
times=[time.strftime("%H:%M", time.localtime(t / 1000)) for t in times],
|
||||||
values=values,
|
normal_values=left_ele,
|
||||||
title="宿舍电量剩余趋势",
|
title=f"宿舍电量剩余趋势({time_range})",
|
||||||
ylabel="剩余电量(度)",
|
ylabel="剩余电量(度)",
|
||||||
out_path=out,
|
out_path=out,
|
||||||
)
|
)
|
||||||
@@ -22,17 +25,19 @@ async def render_ammeter_chart():
|
|||||||
|
|
||||||
|
|
||||||
async def render_water_chart():
|
async def render_water_chart():
|
||||||
times, values = await get_water_left(limit=24)
|
times, left_water, left_free_water = await get_water_left(limit=24)
|
||||||
|
|
||||||
if not times:
|
if not times:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
out = "data/water.png"
|
out = "data/water.png"
|
||||||
|
|
||||||
|
time_range = f"{time.strftime("%Y-%m-%d %H:%M", time.localtime(times[0] / 1000))} ~ {time.strftime("%Y-%m-%d %H:%M", time.localtime(times[-1] / 1000))}"
|
||||||
|
|
||||||
plot_line(
|
plot_line(
|
||||||
times=times,
|
times=[time.strftime("%H:%M", time.localtime(t / 1000)) for t in times],
|
||||||
values=values,
|
normal_values=left_water,
|
||||||
title="宿舍水量剩余趋势",
|
title=f"宿舍水量剩余趋势({time_range})",
|
||||||
ylabel="剩余水量(吨)",
|
ylabel="剩余水量(吨)",
|
||||||
out_path=out,
|
out_path=out,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ async def get_ammeter_left_ele(limit=24):
|
|||||||
conn.row_factory = aiosqlite.Row
|
conn.row_factory = aiosqlite.Row
|
||||||
cursor = await conn.execute(
|
cursor = await conn.execute(
|
||||||
"""
|
"""
|
||||||
SELECT created_at, left_ele
|
SELECT created_at, left_ele, left_free_ele
|
||||||
FROM ammeter_usage
|
FROM ammeter_usage
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
@@ -20,10 +20,13 @@ async def get_ammeter_left_ele(limit=24):
|
|||||||
|
|
||||||
rows.reverse()
|
rows.reverse()
|
||||||
|
|
||||||
times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows]
|
times = [r[0] for r in rows]
|
||||||
values = [r[1] for r in rows]
|
# times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows]
|
||||||
|
|
||||||
|
left_ele = [r[1] for r in rows]
|
||||||
|
left_free_ele = [r[2] for r in rows]
|
||||||
|
|
||||||
return times, values
|
return times, left_ele, left_free_ele
|
||||||
|
|
||||||
|
|
||||||
async def get_water_left(limit=24):
|
async def get_water_left(limit=24):
|
||||||
@@ -31,7 +34,7 @@ async def get_water_left(limit=24):
|
|||||||
conn.row_factory = aiosqlite.Row
|
conn.row_factory = aiosqlite.Row
|
||||||
cursor = await conn.execute(
|
cursor = await conn.execute(
|
||||||
"""
|
"""
|
||||||
SELECT created_at, left_water
|
SELECT created_at, left_water, left_free_water
|
||||||
FROM water_usage
|
FROM water_usage
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
@@ -42,7 +45,10 @@ async def get_water_left(limit=24):
|
|||||||
|
|
||||||
rows.reverse()
|
rows.reverse()
|
||||||
|
|
||||||
times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows]
|
times = [r[0] for r in rows]
|
||||||
values = [r[1] for r in rows]
|
# times = [time.strftime("%Y-%m-%d %H:%M", time.localtime(r[0] / 1000)) for r in rows]
|
||||||
|
|
||||||
return times, values
|
left_water = [r[1] for r in rows]
|
||||||
|
left_free_water = [r[2] for r in rows]
|
||||||
|
|
||||||
|
return times, left_water, left_free_water
|
||||||
|
|||||||
Reference in New Issue
Block a user