Skip to content

设备控制、配置与本地定时 ​

平台将用户意图分为即时属性控制、持久参数配置和短期服务调用。持久定时通过配置保存,实际触发由设备本地内核完成。继电器只是首个产品适配;后端没有继电器专用定时API、Topic树或调度表。

1. 四种状态不要混淆 ​

行为保存在何处成功含义
property.set即时控制短期关联记录,实际结果更新影子原设备明确回复200;随后以真实状态上报更新界面
config.set持久配置PostgreSQL期望、设备NVS副本云端保存、设备接受、实际应用是三个步骤
service.callRedis短期请求与结果接受倒计时不代表倒计时已经执行
本地定时触发设备NVS规则与执行水位到时在设备执行,网络断开不自动取消

前提是当前拥有者/共享权限有效,运行归属ACTIVE且无待清理,设备启动与能力已确认。修改持久配置及倒计时仅限拥有者;读取允许当前有效分享者。管理员身份不自动绕过这些拥有者限定。

2. 配置保存与应用 ​

settings和schedules是相互独立的scope,各自从revision=1开始递增,最高2147483647。HTTP expectedRevision是比较并交换条件:仅当它等于云端当前revision才保存,否则409,客户端重新读取后合并。零版本表示尚未配置,不表示设备已接受云端默认值。

settings HTTP请求是改动集,服务端把可写改动与当前值/默认值合并为完整快照;schedules请求是全量替换,省略已有规则意味着删除。MQTT config/set始终携带完整scope快照,设备先校验并持久化,成功才回复接受。同版本同内容幂等,不允许同版本替换内容;低版本不能覆盖高版本。

syncStatus/结果用户应如何理解
unconfigured该scope没有当前归属的云端配置
pending期望已保存,尚未确认设备接受
applied当前完整版本已应用
pending_restart设备接受了需要下次启动生效的设置
failed已接受但存在应用失败项,查看items与error
conflict匹配查询发现设备领先、回退或内容不一致,需要显式处理

acceptedRevision是设备已持久接受的版本,appliedRevision是完整应用的版本;设置逐项还报告desiredValue、reportedValue、state。code=200不能单独推断所有设置已生效。config_apply_retry仅重试当前版本failed即时项,不重放已成功项、不制造新版本;next_boot参数应在重启后核对reported。

离线或发布失败时,期望配置仍保存在PostgreSQL,delivery可能queued;后续重连核对后可重发当前快照。HTTP delivery=published只表示Broker确认,不表示设备应用。具体字段与可复制报文见MQTT参考。

3. 查询与并发 ​

公开config_get/schedule_get和自动重连查询关联各自真实msgId。自动查询使用独立随机ID,不复用config/set的pendingMsgId;Redis观察记录保留120秒,记录scope、revision、pendingMsgId、accepted/appliedRevision与syncStatus。

查询回复必须来自原Topic设备、当前owner/epoch/已确认bootId。只有请求时观察状态仍等于当前记录时,才能把快照用于持久同步或冲突判断。版本2已经成功应用后迟到的版本1查询不能把配置改成冲突。公开查询即使不能再用于写状态,也要结束请求并释放占用。匹配的自动查询仍能识别真实设备回退/领先;不会通过忽略所有错误来掩盖数据分歧。

冲突时先读取云端desired、设备查询结果和当前归属,确认是否错误固件/回滚/手工改NVS。首版没有“强制采纳任意设备高版本”的通用接口;不能手工改revision或删除数据库记录碰运气。开发板需要重建归属时使用正常解绑及配网,离线清理的影响见下节。

4. 归属与启动屏障 ​

bindingEpoch是32位小写十六进制归属代号,bootId是每次启动的UUID。新的归属只能由物理配网窗口的nonce和有效认领票据建立,不能通过普通控制/能力消息设置。

设备持久CLEARING后清除旧规则、参数、倒计时、执行日志和产品独立恢复目标。继电器通过产品清理回调严格提交OFF恢复目标;失败则保留屏障,重启幂等重试,不能提前READY。清理不立即切断当前负载,但未ACTIVE时重启不能恢复旧拥有者保存的ON。本地按键可改变当前输出,不保存跨归属恢复意图。

云端在ready后事务确认归属并发commit,设备持久ACTIVE回报后认领才completed。重连的READY/ACTIVE设备用30秒域分隔HMAC挑战确认bootId;能力自报不能替换bootId,旧启动的迟到证明被拒绝。commit恢复不靠过期的prepare票据自动失效,避免已提交归属永久卡在READY。报文见配网与归属。

解绑同时撤销旧共享与票据,保留设备身份、WiFi、设备记录与测量历史。离线设备收到清理前可能继续执行旧规则。 不能承诺点击解绑立即使离线负载停止,需设备重连或按正常配网进入清理屏障。

5. 日历定时 ​

每设备最多16条,真实上限以capabilities为准。一次规则atUtc是UTC秒,须为2024至2099年整分钟;每周规则minute是当天第0至1439分钟,weekdays位0至6对应周一至周日。timezoneMinutes是固定UTC偏移,范围-720至840,不是IANA时区,不自动处理夏令时。

同一属性同刻的两条启用规则会冲突,包含一次与每周的交叉情况。一次定时UI要求未来时间,云端协议校验绝对有效范围;错过时间不会补执行。设备成功校时后才运行日历动作;时钟回拨、重启或断网不能靠清空水位重复执行。

规则id是执行身份,不是列表序号。范围1至2147483647,新增ID必须大于已使用高水位;删除后不能复用。修改时间、属性、值、触发类型或每周时区必须换新ID,小程序自动处理。纯启停/原样保存保留ID及执行水位,已执行的一次定时不会因为重新启用而重放。云端与设备同时拒绝同ID改变执行含义。

执行前先持久reserved occurrence,再调用硬件动作;执行中掉电选择可能漏执行而不自动重放。该方案避免重复动作,但不保证物理“恰好一次”。删除配置须设备收到后才生效,不能把云端保存当作设备已删除。

6. 一次性倒计时 ​

countdown_set输入一个可定时属性动作和seconds,范围1至设备maxCountdownSeconds(当前最多86400秒)。同属性新倒计时替换旧的;成功手动控制取消该属性倒计时;取消通过countdown_cancel明确指定propertyId。

倒计时使用单调时钟,只在本次启动内有效,断网继续、重启取消。schedule_get返回剩余时间快照,不是每秒推送。服务请求有效期当前30秒、设备占用35秒、记录120秒;超时或发送结果不确定时先查询,不盲目重发。持续“上一项操作”需检查回复解析与占用释放,不通过调大超时解决。

7. 两产品适配 ​

继电器relay_1至relay_4对应逻辑通道一至四。每路relay_N_boot_delay_s范围0至3600秒、默认0、next_boot;只延迟恢复断电前已开启的通道,原本关闭不自动开启。运行中暂时OFF和持久恢复意图分开,其他通道写入不能覆盖其目标。清理策略见第4节。

环境传感器sample_interval_s范围5至3600秒、默认30;report_interval_s范围30至3600秒、默认60;均即时生效。60秒独立心跳不制造新测量,缺失光照不填假值。没有为传感器开放继电器定时面板。

8. 实现与验证定位 ​

后端modules/device-operation提供契约、事务、配置和服务;固件components/device_runtime是纯C通用内核,main/app_runtime.c或env_runtime.c是产品适配;小程序utils/device-configuration.ts和设备配置页负责规则编辑。NVS紧凑版本化编码带CRC,单镜像上限4096字节,规则及执行日志预留容量后才接受。

v0.7.1修复代码与两项继电器针对性实测范围见事实基线。早期阶段过程保存在历史归档,现行行为以上述契约为准。