feat: 初始化项目并提交一次代码
This commit is contained in:
13
services/collector.py
Normal file
13
services/collector.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# services/collector.py
|
||||
from models.water_usage import WaterUsageModel
|
||||
from models.ammeter_usage import AmmeterUsageModel
|
||||
|
||||
|
||||
async def handle_water_response(resp: dict):
|
||||
if resp.get("statusCode") == "200":
|
||||
await WaterUsageModel.insert(resp["resultObject"])
|
||||
|
||||
|
||||
async def handle_ammeter_response(resp: dict):
|
||||
if resp.get("statusCode") == "200":
|
||||
await AmmeterUsageModel.insert(resp["resultObject"])
|
||||
31
services/plot.py
Normal file
31
services/plot.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import matplotlib
|
||||
|
||||
matplotlib.use("Agg")
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import font_manager
|
||||
import config
|
||||
import logging
|
||||
|
||||
logging.getLogger("matplotlib").setLevel(logging.WARNING)
|
||||
|
||||
# 从字体文件创建字体对象
|
||||
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")
|
||||
|
||||
plt.title(title, fontproperties=FONT)
|
||||
plt.xlabel("时间", fontproperties=FONT)
|
||||
plt.ylabel(ylabel, fontproperties=FONT)
|
||||
|
||||
plt.xticks(rotation=45, fontproperties=FONT)
|
||||
plt.grid(True)
|
||||
plt.tight_layout()
|
||||
plt.savefig(out_path, dpi=150)
|
||||
plt.close()
|
||||
40
services/render.py
Normal file
40
services/render.py
Normal file
@@ -0,0 +1,40 @@
|
||||
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)
|
||||
|
||||
if not times:
|
||||
return None
|
||||
|
||||
out = "data/ammeter.png"
|
||||
|
||||
plot_line(
|
||||
times=times,
|
||||
values=values,
|
||||
title="宿舍电量剩余趋势",
|
||||
ylabel="剩余电量(度)",
|
||||
out_path=out,
|
||||
)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
async def render_water_chart():
|
||||
times, values = await get_water_left(limit=24)
|
||||
|
||||
if not times:
|
||||
return None
|
||||
|
||||
out = "data/water.png"
|
||||
|
||||
plot_line(
|
||||
times=times,
|
||||
values=values,
|
||||
title="宿舍水量剩余趋势",
|
||||
ylabel="剩余水量(吨)",
|
||||
out_path=out,
|
||||
)
|
||||
|
||||
return out
|
||||
48
services/statistics.py
Normal file
48
services/statistics.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import time
|
||||
|
||||
import aiosqlite
|
||||
from database import get_conn
|
||||
|
||||
|
||||
async def get_ammeter_left_ele(limit=24):
|
||||
async with get_conn() as conn:
|
||||
conn.row_factory = aiosqlite.Row
|
||||
cursor = await conn.execute(
|
||||
"""
|
||||
SELECT created_at, left_ele
|
||||
FROM ammeter_usage
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?
|
||||
""",
|
||||
(limit,),
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
|
||||
rows.reverse()
|
||||
|
||||
times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows]
|
||||
values = [r[1] for r in rows]
|
||||
|
||||
return times, values
|
||||
|
||||
|
||||
async def get_water_left(limit=24):
|
||||
async with get_conn() as conn:
|
||||
conn.row_factory = aiosqlite.Row
|
||||
cursor = await conn.execute(
|
||||
"""
|
||||
SELECT created_at, left_water
|
||||
FROM water_usage
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ?
|
||||
""",
|
||||
(limit,),
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
|
||||
rows.reverse()
|
||||
|
||||
times = [time.strftime("%H:%M", time.localtime(r[0] / 1000)) for r in rows]
|
||||
values = [r[1] for r in rows]
|
||||
|
||||
return times, values
|
||||
Reference in New Issue
Block a user