Files
eink-push/config.py
YANG JIANKUAN 2015947812 feat: E1002 顶部时钟改 F84+用量行 12px 三档配色、标签右对齐
- 顶部时钟 F48→F84 占满 A 段,星期/日期移到时钟右侧并与基线对齐
- 用量行:标签常规字重右对齐贴进度条,百分比与 pace 数字 12px 粗体
- 配色:进度条/边框/百分比同色,用量与 pace 各自三档绿/黑/红、独立取色
  (曾按要求加过黄档,同日被否并移除)
- 用量块标题右侧「快照」改为「上次更新」,与今日实时统一
- 今日实时标题与指标名间距加大 4px
- 基类抽出 PCT_TRACK / LABEL_BOLD / LABEL_ALIGN / FPACE 供宽版覆写,
  400×300 小屏输出逐像素不变

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-14 11:39:55 +08:00

118 lines
8.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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"))
# ---- 局域网墨水屏设备喵喵固件开源https://gitee.com/gxp666111/miaomiao----
# 不再走 Zectrix 公网 API + 设备 MAC改为直连局域网设备 mDNS host 的 HTTP 接口。
EPD_HOST = os.environ.get("EPD_HOST", "epd400a44.local")
# ---- 时区 ----
# 服务端可能部署在境外 VPS所有「现在时刻」与时间戳格式化统一按此时区data.TZ本机与服务端结果一致。
TZ_NAME = os.environ.get("TZ_NAME", "Asia/Shanghai")
# ---- 画布(喵喵固件 400x300 三色屏)----
WIDTH, HEIGHT = 400, 300
# ---- reTerminal E1002800x480E Ink Spectra 6 六色;经 SenseCraft HMI 的 HTML 控件云端抓取)----
# 产物:固定 800x480 的 index.html + 同目录 dashboard.png需部署到公网 HTTPS 地址供平台每周期重新拉取。
E1002_WIDTH, E1002_HEIGHT = 800, 480
E1002_COLOR_STRIP = os.environ.get("E1002_COLOR_STRIP", "0") == "1" # 底部六色测试色条(真机校准用,默认关)
# ---- 图片服务server.py恒定 URL每次请求内存中现渲染 800x480 PNG供 SenseCraft HTML 控件周期抓取)----
# 服务端三路上游的内存缓存有效期(秒):收到请求先查缓存是否过期,过期才实拉并更新时间戳,否则直接用缓存渲染;
# 拉取失败沿用旧值且不更新时间戳(下次请求再试)。设 0 = 每次请求都实拉。天气/BTC 复用上面的 WEATHER_TTL/BTC_TTL。
MAO_TTL = int(os.environ.get("MAO_TTL", "60")) # 橘喵今日实时,默认 60 秒
# 真机验证结论Image 控件只在填写 URL 时抓一次快照、此后不再更新HTML 控件填同一图片 URL 则每周期重抓。
SERVER_HOST = os.environ.get("SERVER_HOST", "0.0.0.0")
SERVER_PORT = int(os.environ.get("SERVER_PORT", "8790"))
IMAGE_PATH = os.environ.get("IMAGE_PATH", "/e1002.png") # 方案一:恒定图片路径(每次请求内存渲染 PNG可改成难猜的路径防扫描
HTML_PATH = os.environ.get("HTML_PATH", "/e1002.html") # 方案二:恒定网页路径(每次请求生成 800x480 现代网页,平台截图)
# 方案三:服务端用无头 Chrome 把方案二的网页截成 800x480再按「最近色、不抖动」固化为六色 PNG需服务器装 Chrome/Chromium
HTML_PNG_PATH = os.environ.get("HTML_PNG_PATH", "/e1002-web.png")
CHROME_BIN = os.environ.get("CHROME_BIN", "") # 为空则按常见路径自动探测macOS Google Chrome / google-chrome / chromium
CHROME_EXTRA_ARGS = os.environ.get("CHROME_EXTRA_ARGS", "") # 例如 Linux 以 root 运行需 "--no-sandbox"
# 每通道二值化阈值0~255低于阈值归 0、否则归 255取 160而非 128偏向保留墨迹细笔画的浅灰边不至于被丢成白
HTML_PNG_THRESHOLD = int(os.environ.get("HTML_PNG_THRESHOLD", "160"))
PUSH_TOKEN = os.environ.get("PUSH_TOKEN", "") # 推送鉴权令牌X-Push-Token 头);为空则拒绝一切推送
PUSH_STATE_PATH = os.environ.get("PUSH_STATE_PATH", "") # 推送数据落盘路径(重启后恢复);为空=仅内存
# 本机推送端main.py --target push服务地址含协议与端口不含路径令牌同 PUSH_TOKEN
PUSH_URL = os.environ.get("PUSH_URL", "")
# ---- 资源路径 ----
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")
E1002_OUTPUT_DIR = os.path.join(OUTPUT_DIR, "e1002")
E1002_PNG_PATH = os.path.join(E1002_OUTPUT_DIR, "dashboard.png")
E1002_HTML_PATH = os.path.join(E1002_OUTPUT_DIR, "index.html")
# ---- 橘喵 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 分钟(本机文件缓存与 server.py 内存缓存共用)
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")
# ---- 比特币 K 线(仅 800x480 宽版底部面板)----
# 免费公开接口无需密钥逐源兜底OKX → Coinbase → Huobi见 btc_api.py。当前为时 K、近 48 小时2 天);
# 每 5 分钟刷新(与 launchd 节律一致,最新一根随实时价推进)。拉取失败沿用旧缓存。缓存文件已在 .gitignore。
BTC_BAR = os.environ.get("BTC_BAR", "1H") # 周期:"1H" 时K / "1D" 日K
BTC_LIMIT = int(os.environ.get("BTC_LIMIT", "48")) # 展示最近 N 根(时 K 默认 48 = 近 2 天2026-09-14 由 72 改 48
BTC_TTL = int(os.environ.get("BTC_TTL", "300")) # 秒,默认 5 分钟(本机文件缓存与 server.py 内存缓存共用)
BTC_CACHE_PATH = os.path.join(BASE_DIR, ".btc_cache.json")
# ---- Claude Code 用量Claude Usage 模块)数据源 ----
# 只读本地、**不发任何网络请求**(详见 usage_local.py——生产者/消费者模式:
# 生产者 = 打过补丁的 claude-statusline把每次从 Claude Code stdin 拿到的**权威实时**额度
# five_hour/seven_day 的 utilization + resets_at落盘到 ~/.claude/usage-snapshot.json本项目读它。
# 活跃使用时该快照几乎持续刷新、准确;空闲时停在最后一次。文件缺失时用量区显示 "--"。
USAGE_LOCAL_PATH = os.environ.get("USAGE_LOCAL_PATH", os.path.expanduser("~/.claude/usage-snapshot.json"))
USAGE_WARN = int(os.environ.get("USAGE_WARN", "80")) # 用量 ≥ 此百分比 → 进度条与百分比转红预警(两个版面统一)
# 以下两项仅六色宽版E1002使用三色小屏只有 黑/红 两档。用量与 pace 各自三档、独立取色,颜色顺序固定为 绿 → 黑 → 红
# 黄不用2026-09-14 曾按要求加过 60%80% 黄档,随即被否——黄小字压白底发虚、且四档在三行里过于花):
USAGE_OK = int(os.environ.get("USAGE_OK", "30")) # 用量 ≤ OK 绿「健康」OK~WARN 黑「正常」|≥ WARN 红「危险」;进度条、边框与百分比数字同色
PACE_TOL = int(os.environ.get("PACE_TOL", "10")) # pace=用量%−时间%:≤ TOL 绿「节余」±TOL 内黑「持平」|≥ +TOL 红「偏快」