From fbcb45c81bf6d7500f8f6093516fbd1ee1c9b8e6 Mon Sep 17 00:00:00 2001 From: zhilv Date: Thu, 18 Dec 2025 11:21:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20README=20=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96=E7=BB=98?= =?UTF-8?q?=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- main.py | 2 +- scheduler.py | 2 +- services/plot.py | 68 +++++++++++++++++++++++++++++++++++++----- services/render.py | 21 ++++++++----- services/statistics.py | 22 +++++++++----- 6 files changed, 91 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index e37e711..e7663c3 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ - 手动去 Github 下载 [LXGWWenKai-Medium 字体](https://github.com/lxgw/LxgwWenKai) 保存到fonts文件夹中,或者使用 wget 进行获取,然后修改配置文件 ```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` diff --git a/main.py b/main.py index 4b8d730..82b3373 100644 --- a/main.py +++ b/main.py @@ -30,7 +30,7 @@ async def main(): start_scheduler() - await SD().push() + # await SD().push() while True: await asyncio.sleep(3600) diff --git a/scheduler.py b/scheduler.py index afe03ee..39c5926 100644 --- a/scheduler.py +++ b/scheduler.py @@ -27,7 +27,7 @@ def start_scheduler(): sd.push, trigger="cron", hour=8, - minute=0, + minute=30, id="push_gzh", replace_existing=True, max_instances=1, diff --git a/services/plot.py b/services/plot.py index 2a6546a..5e734b3 100644 --- a/services/plot.py +++ b/services/plot.py @@ -16,16 +16,70 @@ FONT = font_manager.FontProperties(fname=config.FONT_PATH) plt.rcParams["axes.unicode_minus"] = False -def plot_line(times, values, title, ylabel, out_path): - plt.figure(figsize=(8, 4)) - plt.plot(times, values, marker="o") +def plot_line( + times, + 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) - plt.xlabel("时间", fontproperties=FONT) - plt.ylabel(ylabel, fontproperties=FONT) + if has_free: + fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), sharex=True) + 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.grid(True) plt.tight_layout() plt.savefig(out_path, dpi=150) plt.close() diff --git a/services/render.py b/services/render.py index 1a8e596..217965a 100644 --- a/services/render.py +++ b/services/render.py @@ -1,19 +1,22 @@ +import time from services.statistics import get_ammeter_left_ele, get_water_left from services.plot import plot_line 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: return None 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( - times=times, - values=values, - title="宿舍电量剩余趋势", + times=[time.strftime("%H:%M", time.localtime(t / 1000)) for t in times], + normal_values=left_ele, + title=f"宿舍电量剩余趋势({time_range})", ylabel="剩余电量(度)", out_path=out, ) @@ -22,17 +25,19 @@ async def render_ammeter_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: return None 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( - times=times, - values=values, - title="宿舍水量剩余趋势", + times=[time.strftime("%H:%M", time.localtime(t / 1000)) for t in times], + normal_values=left_water, + title=f"宿舍水量剩余趋势({time_range})", ylabel="剩余水量(吨)", out_path=out, ) diff --git a/services/statistics.py b/services/statistics.py index 681b7f6..0e7e7c7 100644 --- a/services/statistics.py +++ b/services/statistics.py @@ -9,7 +9,7 @@ async def get_ammeter_left_ele(limit=24): conn.row_factory = aiosqlite.Row cursor = await conn.execute( """ - SELECT created_at, left_ele + SELECT created_at, left_ele, left_free_ele FROM ammeter_usage ORDER BY created_at DESC LIMIT ? @@ -20,10 +20,13 @@ async def get_ammeter_left_ele(limit=24): rows.reverse() - times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows] - values = [r[1] for r in rows] + times = [r[0] 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): @@ -31,7 +34,7 @@ async def get_water_left(limit=24): conn.row_factory = aiosqlite.Row cursor = await conn.execute( """ - SELECT created_at, left_water + SELECT created_at, left_water, left_free_water FROM water_usage ORDER BY created_at DESC LIMIT ? @@ -42,7 +45,10 @@ async def get_water_left(limit=24): rows.reverse() - times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows] - values = [r[1] for r in rows] + times = [r[0] 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