init: init proj

This commit is contained in:
2026-06-29 09:43:20 +08:00
commit f26c490861
12 changed files with 890 additions and 0 deletions

47
CLAUDE.md Normal file
View File

@@ -0,0 +1,47 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目定位
`eink-push` 是 JM monorepo 中一个**独立的 Python 工具**,与其余 Java/Vue 子项目技术栈无关,不受父级 CLAUDE.md 的 jm-cloud/uniapp/admin 开发约束。
作用把橘喵今日经营、近30天趋势、日期与天气合成为一张 **400×300 纯黑白1bit** PNG推送到 Zectrix 极趣云墨水屏设备(`zectrix-s3-epaper-4.2`)。纯 Python + Pillow**无浏览器依赖**,适合 cron 定时运行。
## 命令
```bash
pip install -r requirements.txt # 仅 Pillow>=10.0urllib 用标准库
python3 main.py # 取数据 → 渲染 → 推送(设备取列表第一个)
python3 main.py --render-only # 只渲染到 output/dashboard.png不推送本地调试渲染时用这个
# 环境变量覆盖配置(见 config.py
ZECTRIX_API_KEY=zt_xxx ZECTRIX_DEVICE_ID=AA:BB:CC:DD:EE:FF python3 main.py
```
无测试、无 lint。调试渲染效果就跑 `--render-only``output/dashboard.png`
## 架构(数据 → 渲染 → 推送 三层)
`main.py` 串联三层,各层职责单一、低耦合:
- **`data.py`** — 唯一数据入口 `get_dashboard_data()`,返回固定结构的 dict。日期/时间用真实系统时间;橘喵今日经营+趋势由 `_mao()``jm_api`、天气由 `_weather()``weather_api`(和风,定位南京·秦淮)拉真实数据,**任何接口异常都回退占位 `"--"`,不回退 mock**。改数据保持返回结构不变即可renderer 依赖其 key尤其 `mao.trend.series` 每条须带 `style`;环比/同比 `(direction, text)`direction 为 `None` 时不画涨跌三角)。
- **`jm_api.py`** — jm-devops 后端统计接口客户端,**免鉴权 GET**`/system/statistics/realtime``/recent-days?days=`)。注:早期曾实现登录+RSA/AES 加密+验证码 OCR后改为后端直接放开这两个接口故已全部删除——若后端再次收紧鉴权参考 jm-devops 的 `src/utils/{crypto,jsencrypt,request}.ts` 复刻。
- **`weather_api.py`** — 和风天气QWeather客户端。用**用户专属 API Host**`QWEATHER_HOST`+ `X-QW-Api-Key` 头鉴权;响应 **gzip 压缩**(按 magic number 手动解压)、返回 `code` 为**字符串**。`get_now()` 取实时(`now.text` 中文天气 / `now.temp``get_today()``/3d``daily[0]` 今日温区。`QWEATHER_HOST`/`QWEATHER_KEY` 未配置时直接抛错→天气区显示 `"--"`
- **`renderer.py`** — `DashboardRenderer.render(data)` 返回 PIL `'L'` 模式纯 0/255 图;`render_to_file()` 落盘。布局硬编码为三区:大时钟+日期 / 天气 / 橘喵三列 / 近30天趋势折线图。趋势线用 `_styled_polyline()` 按 solid/dashed/dotted 区分(设备无颜色),各指标按自身极值独立归一化(故只看趋势形状、不可横向比绝对值)。
- **`pusher.py`** — `push_image()` 走 Zectrix API`POST /devices/{id}/display/image`,手写 multipart`resolve_device_id()``config.DEVICE_ID` 为空时自动取设备列表第一个。
- **`config.py`** — API、设备、画布尺寸、字体路径、推送参数敏感项可被环境变量覆盖。
## 墨水屏渲染约束(改 renderer.py 必读)
设备是 **1bit、无真灰阶**——灰阶只能抖动成网点(难看),所以全程纯黑白,靠构图/字号/留白建立层级,**不要引入灰色填充或抖动**
- 字体固定用 **Fusion Pixel 12px 点阵字体**`fonts/`OFL 协议),只按整数倍尺寸 **12/24/48** 渲染(`F12/F24/F48`),并设 `d.fontmode = "1"` 关闭抗锯齿,否则像素会糊。
- 加粗用「伪粗体」:`_draw()` 按 1~bold px 水平偏移叠绘笔画(点阵字体只有单一字重)。
- 推送时 `DITHER = False`(硬阈值),纯黑白图最锐利,勿改成 `true`
- 坐标、字号均为像素网格上的硬编码常量;调布局时注意各区分隔线 `hdash` 的 y 值与下方组件位置联动。
## 注意
- `config.py` 内置了一个默认 `API_KEY`(硬编码 fallback。修改/分享代码时留意,优先用 `ZECTRIX_API_KEY` 环境变量。
- `output/``__pycache__/` 已在 `.gitignore` 中忽略。