Skip to content

API

如果你有开发能力,想集成时钟的配置在你的App、Home Assistant、Node-RED、脚本或其他系统中,请参考此API文档

本文档包含两类相互独立的接口

  • 部署在公网服务器上的云端发现 API
  • 由时钟 ESP32 在局域网内提供的设备 API

二者的主机地址、传输协议、响应格式和 CORS 策略均不同,请勿混用

1. API 分类

类别服务位置基础地址响应格式CORS主要用途
云端发现 API公网服务器https://topyuan.top/clock/findapiJSON 响应体允许任意来源 *根据公网出口 IP 获取时钟的局域网 IP
设备本地 API时钟 ESP32http://<时钟的局域网 IP>配置数据位于 HTTP Header,响应体通常为空不返回 CORS Header读取配置、修改设置、读取 ADC、重启或清除 Wi-Fi

推荐调用顺序:先请求云端发现 API 获得候选 localIp,然后在当前局域网内请求 http://<localIp>/get 等API

如果你有其他方式可获取到局域网内的时钟ip,也可以不请求云端发现api

2. 云端发现 API

2.1 通用约定

  • 完整地址:https://topyuan.top/clock/findapi
  • 服务位置:公网服务器,不在时钟 ESP32 上
  • 传输协议:HTTPS
  • 请求方式:GET
  • 身份认证:无
  • 成功响应:200 OK 和 JSON 数组
  • 内容类型:application/json; charset=utf-8
  • CORS:Access-Control-Allow-Origin: *
  • 缓存策略:Cache-Control: no-store

2.2 发现设备:GET /clock/findapi

App 或其他客户端可以先调用此接口,取得可能位于当前局域网内的时钟 IP,再使用返回的 localIp 调用设备的 /get/set 等接口

2.3 工作原理

时钟会定期把自身的公网 IP、局域网 IP 和设备信息上报到服务器。发现接口使用调用者的 REMOTE_ADDR 作为公网 IP,查询数据库中满足以下条件的设备:

  1. 设备上报时的公网 IP 与接口调用者的公网 IP 相同
  2. 设备在最近 12 小时内有过上报
  3. 设备上报了有效的 IPv4 局域网地址

接口按最后上报时间从新到旧排列结果

2.4 请求

http
GET /clock/findapi.php HTTP/1.1
Host: topyuan.top

无 Query 参数和请求体。公网 IP 由服务器根据当前连接自动取得,客户端不能通过参数指定要查询的公网 IP

bash
curl -i https://topyuan.top/clock/findapi

2.5 成功响应

  • 状态码:200 OK
  • Content-Type: application/json; charset=utf-8
  • Access-Control-Allow-Origin: *
  • 响应体:JSON 数组
  • 缓存策略:Cache-Control: no-store
json
[
  {
    "chipId": "9730432",
    "localIp": "192.168.31.247",
    "deviceType": "ClockWise Plus",
    "lastSeen": "2026-08-04 15:26:30"
  },
  {
    "chipId": "10557104",
    "localIp": "192.168.31.180",
    "deviceType": "SuperY",
    "lastSeen": "2026-08-04 15:20:12"
  }
]
JSON 字段类型说明
chipId字符串时钟芯片 ID
localIp字符串时钟上报的局域网 IPv4 地址,例如 192.168.1.50
deviceType字符串ClockWise PlusSuperYSuperY Lite
lastSeen字符串服务器记录的最后上报时间,格式为 YYYY-MM-DD HH:mm:ss

deviceTypeClockWise Plus的设备适用于本文档的时钟本地API,如果你还使用了我的其他类型时钟,云端发现API还可以查到其他类型的设备

没有找到设备时,接口返回空数组:

json
[]

2.6 错误响应

状态码响应示例含义
400{"error":"invalid_client_ip"}服务器无法取得有效的访问者 IP
405{"error":"method_not_allowed"}使用了 GETOPTIONS 以外的请求方式
500{"error":"discovery_unavailable"}服务器错误

2.7 发现结果的限制

“公网 IP 相同”只能作为设备可能处于同一局域网的判断依据,不能作为严格证明。运营商 CGNAT、企业网络、校园网、VPN 或代理可能让互不相邻的客户端共享公网 IP;反过来,IPv4/IPv6 出口不同也可能导致同一局域网内的设备无法匹配

该接口开放通配 CORS,浏览器 Web App 可以跨域直接调用。接口允许 GETOPTIONS,浏览器预检请求返回 204 No Content

3. 设备本地 API 通用约定

本节及后续设备接口均由时钟 ESP32 提供,与第 2 节的公网云端发现服务无关

3.1 连接与数据格式

  • 基础地址:http://<时钟的局域网 IP>,例如 http://192.168.1.50
  • 服务位置:时钟 ESP32
  • 端口:80
  • 传输协议:HTTP,不支持 HTTPS
  • 身份认证:无
  • 写入格式:application/x-www-form-urlencoded,表单类型提交请求,不支持 JSON 请求体
  • 成功响应:读取和控制接口通常返回 204 No Content,响应体为空
  • 字符编码:字符串参数使用 UTF-8,并进行 URL 编码
  • CORS:固件不返回 CORS Header

安全提示:任何能访问时钟局域网 IP 的客户端都可以修改设置、重启设备或清除 Wi-Fi 凭据。请只在可信局域网内开放这些接口,不要直接映射到公网

3.2 为什么通过 HTTP Header 返回数据

受 ESP32 运行内存、响应缓冲区以及 JSON 编码性能限制,固件没有采用常见的 JSON 响应体,而是将配置项直接放入 HTTP 响应 Header,并返回空的 204 No Content。这是一种针对嵌入式设备资源约束所作的实现取舍,并非常规 REST API 设计。第三方客户端必须读取响应 Header,不能依赖响应体或 JSON 解析

3.3 设备接口总览

下表所有路径都相对于 http://<时钟的局域网 IP>

请求方式路径用途成功响应
GET/get读取当前全部配置和设备信息204,数据位于响应 Header
POST/set修改一个或多个配置项204,无响应体
GET/read?pin=<GPIO>读取指定 GPIO 的 ADC 值204,结果位于响应 Header pin
POST/restart立即重启设备204,随后连接断开
POST/erase清除 Wi-Fi SSID/密码并重启204,随后连接断开

3.4 重要兼容说明

  1. HTTP Header 名称不区分大小写。部分客户端会把 displayBright 自动转成 displaybright,调用方必须按不区分大小写的方式读取
  2. /get/read 的数据在响应 Header 中,响应体始终为空。不要尝试把响应解析成 JSON
  3. 设备固件未返回 CORS Header。浏览器中由其他域名、端口或协议加载的网页不能直接读取这些响应;原生 App、后端服务、命令行程序以及时钟自身页面不受此限制
  4. /set 不返回逐字段校验结果。未知字段会被忽略,部分非法数值会被修正,另一些可能被转换为 0 或发生整数截断。建议写入后再次调用 /get 确认实际值
  5. 表单中的 + 会被解释为空格。例如时区 +8:00 必须编码为 %2B8%3A00。使用 curl --data-urlencode 可自动完成编码
  6. /set 支持部分更新:未提交的字段保持不变。值为空字符串的字段也会被视为“未提交”,因此当前接口不能把字符串配置清空

4. 读取全部配置:GET /get

请求

http
GET /get HTTP/1.1
Host: 192.168.1.50

无请求参数和请求体

响应

状态码为 204 No Content,所有数据通过自定义响应 Header 返回。这是为了避免 ESP32 生成和缓冲 JSON 响应带来的额外性能与内存开销。例如:

http
HTTP/1.1 204 No Content
displayBright: 205
autoBrightMin: 30
autoBrightMax: 2000
wifiSsid: MyWiFi
ntpFailRestart: 1
clockFace: 1
autoChange: 1
autoInterval: 0
version: 4.2

以下是完整 Header 列表。表中的默认值指首次启动或该配置尚未保存时的固件默认值

响应 Header类型含义与取值默认值/set 对应字段
displayBright整数显示亮度,0255。自动/定时模式下作为日间或最大亮度205displayBright
autoBrightMin整数自动亮度的夜间 LDR 阈值,130030autoBrightMax 合并为 autoBright
autoBrightMax整数自动亮度的明亮环境 LDR 阈值,80040952000autoBrightMin 合并为 autoBright
specialLed枚举整数LED 面板颜色接线:0 RGB、1 RBG、2 GBR0specialLed
use24hFormat布尔整数1 使用 24 小时制,0 使用 12 小时制1use24hFormat
ldrPin整数光敏电阻所接 GPIO;当前硬件页面固定使用 GPIO 3535ldrPin
wifiSsid字符串设备当前连接的 Wi-Fi SSID当前连接只读
ntpServer字符串NTP 服务器主机名或 IPntp2.aliyun.comntpServer
ntpFailRestart布尔整数1 启用 NTP 连续失败自动重启,0 禁用;设备至少成功同步过一次后,连续 24 次同步失败会重启,任意一次成功同步都会清零失败计数1ntpFailRestart
displayRotation枚举整数屏幕旋转:0=0°、1=90°、2=180°、3=270°0displayRotation
clockFace枚举整数当前表盘编号,127,详见表盘编号表1clockFace
language枚举整数配置页语言:0 中文、1 English0language
totalYear整数累计运行年数0只读
totalMonth整数累计运行月数0只读
totalDay整数累计运行天数0只读
brightMethod枚举整数亮度模式:0 环境光自动调节、1 按时间段调节、2 固定亮度0brightMethod
nightLevel整数定时亮度模式下的夜间亮度等级,151nightLevel
nightStarth整数夜间时段开始小时,建议 02322nightStarth
nightStartm整数夜间时段开始分钟,建议 0590nightStartm
nightEndh整数夜间时段结束小时,建议 0238nightEndh
nightEndm整数夜间时段结束分钟,建议 0590nightEndm
sqtext字符串固定 UTC 偏移显示值,例如 +8:00-3:30;用于 timemode=0+8:00sqtext
timemode枚举整数时区模式:0 固定 UTC 偏移、1 带夏令时规则的 POSIX 时区0timemode
posix字符串实际交给时钟库的 POSIX TZ 字符串<+8>-8posix
autoChange枚举整数自动换表盘方式:0 关闭、1 顺序、2 随机;执行计划由 autoInterval 决定1autoChange
autoInterval整数自动换表盘间隔,单位为分钟;仅在 autoChange0 时生效。0 表示每天 00:00,其他合法值为 101440 且必须是 10 的倍数。对应固件内部配置 autoChangeInterval0autoInterval
faceControl字符串27 位表盘启用掩码;从左至右对应表盘 1~27,1 启用、0 禁用27 个 1faceControl
reversePhase布尔整数HUB75 时钟相位:1 反相、0 正常0reversePhase
nightMode枚举整数夜间策略:0 无、1 关闭 LED、2 显示超大时钟2nightMode
superColor整数超大时钟颜色,RGB565 十进制值,06553516936superColor
version字符串当前固件版本当前版本只读

命令行读取示例:

bash
curl -i http://192.168.1.50/get

5. 修改配置:POST /set

请求格式

http
POST /set HTTP/1.1
Host: 192.168.1.50
Content-Type: application/x-www-form-urlencoded

displayBright=180&use24hFormat=1

一次请求可以提交一个或多个字段。成功时返回 204 No Content,无响应体,也不通过自定义 Header 回显配置结果

可写字段

表单字段输入格式合法/推荐值说明
displayBright十进制整数0255设置显示亮度
autoBright固定格式字符串MMMM,XXXX同时设置 LDR 最小/最大值;两个数都必须补足 4 位,例如 0030,2000
specialLed整数012RGB / RBG / GBR 面板接线
reversePhase布尔字符串01反转相位
use24hFormat布尔字符串01使用24小时制
ldrPin整数当前硬件为 35更改光敏电阻 GPIO;固件不验证该引脚是否支持 ADC
ntpServer字符串有效 NTP 主机名/IP修改后立即同步
ntpFailRestart布尔字符串01是否在 NTP 连续 24 次同步失败后自动重启;只有设备至少成功同步过一次后才开始累计失败次数
displayRotation整数03分别表示 0°、90°、180°、270°
clockFace整数127切换当前表盘
language整数01修改配置页语言;重新打开配置页面后生效
brightMethod整数012自动、定时、固定亮度
nightLevel整数15超出范围会被改为 1
nightStarth整数023夜间开始小时;固件不做范围检查
nightStartm整数059夜间开始分钟;固件不做范围检查
nightEndh整数023夜间结束小时;固件不做范围检查
nightEndm整数059夜间结束分钟;固件不做范围检查
sqtextURL 编码字符串+8:00固定偏移模式的显示值;需与 posix 同步提交
timemode整数01固定偏移 / 智能夏令时
posixURL 编码字符串合法 POSIX TZ固件不校验语法,需自行校验,具体请参考后续正则表达式
autoChange整数012关闭 / 顺序 / 随机换表盘
autoInterval整数0,或 101440 内 10 的倍数自动换表盘间隔,单位为分钟;仅在 autoChange0 时生效,0 表示每天 00:00。对应固件内部配置 autoChangeInterval
faceControl27 字符字符串仅使用 01第 N 位控制第 N 个表盘;建议至少启用两个表盘
nightMode整数012无策略 / 关屏 / 超大时钟
superColor十进制整数065535超大时钟 RGB565 颜色

wifiSsidtotalYeartotalMonthtotalDayversion 只读,提交到 /set 不会产生作用。autoBrightMinautoBrightMax 也不能单独提交,必须使用组合字段 autoBright

posix校验正则表达式:

^([a-zA-Z]{1,6}|<[a-zA-Z0-9+-]{1,6}>)([+-]?([0-9]|1[0-4])(:[0-5]\d)?)((([a-zA-Z]{1,6}|<[a-zA-Z0-9+-]{1,6}>)([+-]?([0-9]|1[0-4])(:[0-5]\d)?)?)(,M([1-9]|1[0-2]).([1-5]).([0-6])(/([0-9]|1[0-9]|2[0-4])(:[0-5]\d)?)?,M([1-9]|1[0-2]).([1-5]).([0-6])(/([0-9]|1[0-9]|2[0-4])(:[0-5]\d)?)?)?)?$

5.1 常用写入示例

设置亮度和 24 小时制:

bash
curl -i -X POST http://192.168.1.50/set \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data "displayBright=180&use24hFormat=1"

设置自动亮度阈值。autoBright 的精确格式是 4 位最小值、英文逗号、4 位最大值:

bash
curl -i -X POST http://192.168.1.50/set \
  --data-urlencode "autoBright=0030,2000"

设置 NTP 服务器,并启用连续 24 次同步失败后自动重启:

bash
curl -i -X POST http://192.168.1.50/set \
  --data-urlencode "ntpServer=ntp2.aliyun.com" \
  --data "ntpFailRestart=1"

设置固定 UTC+8 时区。建议将三个相关字段放在同一个请求中:

bash
curl -i -X POST http://192.168.1.50/set \
  --data-urlencode "sqtext=+8:00" \
  --data-urlencode "timemode=0" \
  --data-urlencode "posix=<+8>-8"

设置带夏令时的 POSIX 时区:

bash
curl -i -X POST http://192.168.1.50/set \
  --data-urlencode "timemode=1" \
  --data-urlencode "posix=EST5EDT,M3.2.0,M11.1.0"

设置夜间时段为 22:30~07:00,夜间关闭屏幕:

bash
curl -i -X POST http://192.168.1.50/set \
  --data "nightLevel=1&nightStarth=22&nightStartm=30&nightEndh=7&nightEndm=0&nightMode=1"

启用顺序自动换表盘,并只允许表盘 1、2、3 参与轮换:

bash
curl -i -X POST http://192.168.1.50/set \
  --data "autoChange=1&faceControl=111000000000000000000000000"

每 180 分钟顺序更换一次表盘:

bash
curl -i -X POST http://192.168.1.50/set \
  --data "autoChange=1&autoInterval=180"

将自动换表盘恢复为每天 00:00 执行:

bash
curl -i -X POST http://192.168.1.50/set \
  --data "autoInterval=0"

5.2 固件实际校正行为

  • autoBright 使用固定位置解析:前 4 个字符为最小值,第 6~9 个字符为最大值,因此必须按 0030,2000 这样的 9 字符格式提交
  • autoBrightMin 小于 1 会改为 1,大于 300 会改为 300
  • autoBrightMax 小于 800 会改为 800,大于 4095 会改为 4095
  • nightLevel 不在 15 时会改为 1
  • ntpFailRestart 只有字符串 1 会启用,其他非空值都会按关闭处理;建议只提交 01
  • /set 仅接受值为 0,或 101440 内 10 的倍数的 autoInterval;非法值会被忽略并保留原设置。启动时如果读到非法的已保存值,固件会在内存中改为 0
  • autoInterval 为非 0 时按相对间隔计时;设备启动、自动换表盘模式或间隔发生变化,以及手动切换表盘后,都会重新开始计时
  • 其他多数整数参数没有范围校验;调用方应自行保证取值有效
  • 未知字段和只读字段不会报错,响应仍可能是 204

6. 读取 ADC:GET /read

读取指定 GPIO 的 analogRead() 原始值,可获取光敏电阻采集的ADC值

输入

名称类型必填说明
pin整数GPIO 编号;当前硬件的 LDR 默认接 GPIO 35

输出

  • 状态码:204 No Content
  • 响应体:空
  • 响应 Header:pin: <ADC 原始值>

示例:

bash
curl -i "http://192.168.1.50/read?pin=35"
http
HTTP/1.1 204 No Content
pin: 1842

固件会把参数转换为 8 位无符号整数后直接调用 analogRead(),不检查引脚是否合法。第三方客户端不应允许最终用户任意传入 GPIO,建议固定使用 /get 返回的 ldrPin

7. 重启设备:POST /restart

无参数、无请求体。固件先尝试发送 204,随后立即执行重启

bash
curl -i -X POST http://192.168.1.50/restart

重启会使连接立即断开;个别客户端可能在完整收到响应前报告网络断开

8. 清除 Wi-Fi:POST /erase

无参数、无请求体。接口只清除当前保存的 Wi-Fi SSID 和密码,然后立即重启

bash
curl -i -X POST http://192.168.1.50/erase

调用后设备无法再通过原 IP 访问,并会重新进入 Wi-Fi 配网流程。这是破坏性操作,调用前应增加二次确认

9. 表盘编号

编号表盘编号表盘
1Super Mario15Shar Pei Dog
2Pac Man16Girl
3World Map17Kirby
4Time In Words18Labubu-Zimomo
5Clock Tower19Hello Kitty
6Pokedex20Twinkle Twinkle
7Retro Computer21Zootopia
8Snoopy22Minecraft-Village
9Nyan Cat23Codex
10Transformer24Rainy Window
11Minecraft-Torch25GTA VI
12Coffee26Zelda-Sunrise
13Pepsi27Particle Time
14Pikachu