Files
eink-push/CLAUDE.md
YANG JIANKUAN cc11dffb02 docs: 更新 CLAUDE.md 与 README 对齐最新业务
- 补充天气/趋势两套文件缓存机制说明(为 cron 每分钟触发而设)
- 天气接入真实和风 API + 矢量手绘图标,修正原 mock 占位描述
- 修正 jm_api 为免登录 GET(带 clientid 头)、布局四区、回退占位
- 更新 cron 部署为 run.sh、补全环境变量与 gitignore 清单

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-29 11:52:41 +08:00

54 lines
5.9 KiB
Markdown
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.

# 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不推送本地调试渲染时用这个
sh run.sh # cron 包装脚本cd 项目目录 + vfox python 绝对路径 + 追加日志到 output/cron.log
# 环境变量覆盖配置(见 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`
**定时部署**`run.sh` 是 cron 入口(已在 `.gitignore`本机专用。cron 不继承登录环境,故脚本内 python 写死 vfox 绝对路径、并 `cd` 到项目目录后追加日志到 `output/cron.log`。设计为**每分钟**触发:业务数据每次都刷新,天气/趋势靠缓存避免高频打接口(见 `data.py`)。可覆盖的环境变量不止 ZECTRIX 两项,还有 `JM_BASE_API`/`JM_CLIENT_ID`/`QWEATHER_HOST`/`QWEATHER_KEY`/`WEATHER_LOCATION`/`WEATHER_TTL`(详见 `config.py`)。
## 架构(数据 → 渲染 → 推送 三层)
`main.py` 串联三层,各层职责单一、低耦合:
- **`data.py`** — 唯一数据入口 `get_dashboard_data()`,返回固定结构的 dict。日期/时间用真实系统时间;橘喵今日经营+趋势由 `_mao()``jm_api`、天气由 `_weather()``weather_api`(和风,定位南京·秦淮)拉真实数据,**任何接口异常都回退占位 `"--"`,不回退 mock**。改数据保持返回结构不变即可renderer 依赖其 key尤其 `mao.trend.series` 每条须带 `style``weather.icon` 为和风图标代码;环比/同比 `(direction, text)`direction 为 `None` 时不画涨跌三角)。
- **两套文件缓存**(为 cron 每分钟独立进程而设,必须落盘):天气缓存 `.weather_cache.json`TTL=`WEATHER_TTL`,默认 15min未过期不发请求趋势缓存 `.trend_cache.json`(按日期 key当天命中即不再调 `recent-days`,每天只拉一次)。两者**拉取失败均沿用旧缓存**避免整片 `"--"`,仍无缓存才回退占位。两个缓存文件已在 `.gitignore`
- **`jm_api.py`** — jm-devops 后端统计接口客户端,**免登录 GET**`/system/statistics/realtime``/recent-days?days=`),仅带 `clientid` 头(`config.CLIENT_ID`)、无 token。注早期曾实现登录+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` / `now.icon` 图标代码),`get_today()``/3d``daily[0]` 今日温区。`QWEATHER_HOST`/`QWEATHER_KEY` 未配置时直接抛错→天气区显示 `"--"`
- **`renderer.py`** — `DashboardRenderer.render(data)` 返回 PIL `'L'` 模式纯 0/255 图;`render_to_file()` 落盘。布局硬编码为四区render 内 A/B/C/DA 大时钟+日期 / B 天气 / C 橘喵今日三列 / D 近30天趋势折线图。趋势线用 `_styled_polyline()` 按 solid/dashed/dotted 区分(设备无颜色),各指标按自身极值独立归一化(故只看趋势形状、不可横向比绝对值)。
- **天气图标全矢量手绘**(无图片资源):`_weather_category()` 把和风 icon 代码归并为 8 类sunny/clear_night/cloudy/overcast/thunder/rain/snow/fog识别不了回退 cloudy再由 `_weather_icon()``_sun`/`_cloud` 等基元按 1bit 描边画出;改天气展示从这里动。
- **`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` 环境变量。
- `.gitignore` 已忽略:`output/``__pycache__/``*.pyc`、两个缓存文件 `.weather_cache.json`/`.trend_cache.json`、本机专用的 `run.sh`。改缓存逻辑后想强制重拉,删掉对应缓存文件即可。