将仪表盘从「四区(时钟/天气/今日实时/30天趋势)」重构为上中下三段: - A 顶部:大时钟+日期 / 天气(定位改南京·江宁) - B 中部主角 Claude Usage:5h/7d 用量进度条 + 大号百分比 + 时间维度对比 pace (pace=用量%−时间%,超前↑红/节余↓黑,参考 claude-statusline);用量≥阈值该条转红预警 - C 底部 橘喵今日实时:三列版式对齐主分支(名F12/值F24粗/环比同比偏移 +18/+34/+64/+82) - 近30天趋势图隐藏(_trend_chart 及依赖保留、未调用,可挂回) 用量只读本地、不发网络请求:新增 usage_local.py 读取 claude-statusline 落盘的 /tmp/claude/statusline-usage-cache.json(utilization + resets_at)。utilization 可能滞后, 但 resets_at 为绝对时间,故 pace 每次按当前时间现算、始终准确;文件缺失回退 "--"。 其他: - 天气定位 秦淮→江宁(config 默认 118.840,31.953) - 进度条边框随条色(红条即红框);行内元素按墨迹竖直中心对齐(_mid) - 新增 F13/F16 字号(非整数倍,fontmode=1 保持纯色) - 全图仍严格三色(黑/白/红)、无灰阶不抖动;底部留 ~11px 下边距 - 同步更新 CLAUDE.md / README.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
80 lines
4.1 KiB
Python
80 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""全局配置。敏感项从同目录 .env 读取,真实环境变量(如 cron 注入)优先。"""
|
||
import os
|
||
|
||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
|
||
|
||
def _load_dotenv(path):
|
||
"""极简零依赖 .env 加载器:把 KEY=VALUE 写入 os.environ。
|
||
已存在的真实环境变量优先(不覆盖),故 cron/命令行注入仍可压过 .env。
|
||
支持 # 注释、空行、行内 KEY=VALUE,值两侧成对的单/双引号会被去掉。"""
|
||
try:
|
||
with open(path, "r", encoding="utf-8") as fp:
|
||
for raw in fp:
|
||
line = raw.strip()
|
||
if not line or line.startswith("#") or "=" not in line:
|
||
continue
|
||
key, _, val = line.partition("=")
|
||
key, val = key.strip(), val.strip()
|
||
if len(val) >= 2 and val[0] == val[-1] and val[0] in "\"'":
|
||
val = val[1:-1]
|
||
if key:
|
||
os.environ.setdefault(key, val)
|
||
except FileNotFoundError:
|
||
pass
|
||
|
||
|
||
_load_dotenv(os.path.join(BASE_DIR, ".env"))
|
||
|
||
# ---- Zectrix 极趣云平台 API ----
|
||
API_BASE = "https://cloud.zectrix.com/open/v1"
|
||
API_KEY = os.environ.get("ZECTRIX_API_KEY", "")
|
||
|
||
# 目标设备 ID(硬件 MAC)。必填——直接据此调推送接口,不再获取设备列表。
|
||
DEVICE_ID = os.environ.get("ZECTRIX_DEVICE_ID", "")
|
||
|
||
# 推送参数
|
||
PAGE_ID = "1" # 持久化页面编号 1-5
|
||
DITHER = False # 纯黑白点阵图用硬阈值最锐利;设备无真灰阶,勿开抖动
|
||
|
||
# ---- 画布 ----
|
||
WIDTH, HEIGHT = 400, 300
|
||
|
||
# ---- 资源路径 ----
|
||
FONT_PATH = os.path.join(BASE_DIR, "fonts", "fusion-pixel-12px-proportional-zh_hans.otf")
|
||
OUTPUT_DIR = os.path.join(BASE_DIR, "output")
|
||
OUTPUT_PATH = os.path.join(OUTPUT_DIR, "dashboard.png")
|
||
|
||
# ---- 橘喵 jm-devops 后端(今日经营 / 近30天趋势 数据源)----
|
||
# 鉴权方式:设备密钥授权(grant_type=client_secret,免验证码)。
|
||
# 用 CLIENT_ID + CLIENT_SECRET 调 /auth/login 换 token,再带 Bearer 调统计接口(详见 jm_api.py)。
|
||
# CLIENT_SECRET 等价于长期凭证,务必走 HTTPS、优先用环境变量覆盖、可在后端 sys_client 轮换。
|
||
BASE_API = os.environ.get("JM_BASE_API", "https://admin.jumiaotandian.com/prod-api")
|
||
CLIENT_ID = os.environ.get("JM_CLIENT_ID", "")
|
||
CLIENT_SECRET = os.environ.get("JM_CLIENT_SECRET", "")
|
||
GRANT_TYPE = os.environ.get("JM_GRANT_TYPE", "client_secret")
|
||
TENANT_ID = os.environ.get("JM_TENANT_ID", "000000")
|
||
|
||
# ---- 和风天气(QWeather)数据源 ----
|
||
# 专属 API Host 与 Key 在 https://console.qweather.com/setting 查看,须用环境变量配置;
|
||
# 未配置时天气区显示占位 "--",不影响其余渲染与推送。
|
||
QWEATHER_HOST = os.environ.get("QWEATHER_HOST", "") # 用户专属 API Host
|
||
QWEATHER_KEY = os.environ.get("QWEATHER_KEY", "")
|
||
# 定位固定为南京·江宁区。和风经纬度格式为「经度,纬度」
|
||
WEATHER_LOCATION = os.environ.get("WEATHER_LOCATION", "118.840,31.953")
|
||
WEATHER_LOC_NAME = "南京·江宁"
|
||
# 天气缓存:业务数据每分钟刷新,但天气 15 分钟才重新拉一次(cron 每次独立进程,缓存须落盘)。
|
||
WEATHER_TTL = int(os.environ.get("WEATHER_TTL", "900")) # 秒,默认 900=15 分钟
|
||
WEATHER_CACHE_PATH = os.path.join(BASE_DIR, ".weather_cache.json")
|
||
# 近30天趋势缓存:recent-days 每天只更新一次,按日期为 key 缓存,当天命中即不再请求。
|
||
TREND_CACHE_PATH = os.path.join(BASE_DIR, ".trend_cache.json")
|
||
|
||
# ---- Claude Code 用量(Claude Usage 模块)数据源 ----
|
||
# 只读本地:读取 claude-statusline 落盘的用量缓存文件,**不发任何网络请求**(详见 usage_local.py)。
|
||
# 注意:新版 Claude Code 经 stdin 喂 statusline,该磁盘缓存刷新不频繁、utilization 可能滞后;
|
||
# resets_at 为绝对时间,故 pace(时间维度对比)始终准确。文件缺失时用量区显示 "--"。
|
||
USAGE_LOCAL_PATH = os.environ.get("USAGE_LOCAL_PATH", "/tmp/claude/statusline-usage-cache.json")
|
||
USAGE_WARN = int(os.environ.get("USAGE_WARN", "80")) # 用量 ≥ 此百分比 → 进度条与百分比转红预警
|