一、智能家居最大的坑:你以为你知道,其实你不知道
做智能家居的朋友都遇到过这种尴尬:
你写好了代码,红外发射器"滴"一声,电视开了。系统里记录:电视=开。
然后你妈走过来,拿起物理遥控器,把电视关了。
你的系统不知道。它还傻傻地以为电视开着。用户下一条指令"打开B站",系统自信满满地发了一串红外码------结果全打在关着的电视上,什么都没发生。
这个问题的本质是:大多数家用设备,能控制,但没反馈。
-
红外控制的电视、空调:你能发指令,但它不会告诉你"我收到了,我执行了"。
-
米家云端API:你能调接口,但有延迟,而且别人也能用App控制,你的缓存瞬间过期。
你系统里维护的那个"设备状态",本质上是一个缓存。它记录的是"上次我让它干什么了",而不是"它现在真实是什么"。
缓存一定会过期。问题是什么时候过期?过期了怎么办?
二、TTL:给状态贴张"保质期"
计算机里有一个经典概念:TTL(Time To Live),存活时间。
说白了就是:一个数据从生成开始,能活多久。过期就作废,不能再用了。
冰箱里的牛奶,保质期7天。1月1日生产,1月8日过期。1月9日你拿起来喝之前,看一眼标签:过期了,扔。
设备状态也一样。
你给电视发"开机"指令,记录状态为"开",同时贴一张标签:30秒后过期。
-
10秒后用户说"音量大点":30秒内,没过期,直接执行。
-
50秒后用户说"打开B站":过期了,不能信了,得重新确认。
TTL让你不用每秒钟都去问状态,但也不会在状态过期后还傻傻相信它。
三、在我的系统里,不同来源的状态,TTL不一样
这是我项目里实际的设计:
| 状态怎么来的 | 我能信多少 | TTL设多久 | 为什么 |
|---|---|---|---|
| 我发了红外指令,推测它成功了 | 很低 | 30秒 | 红外没反馈,物理遥控器随时覆盖 |
| 米家API返回的 | 中等 | 10-30秒 | 云端有延迟,家里别人也用App |
| ADB直接读屏幕 | 较高 | 5-10秒 | 真实读到的,但用户可能按物理键 |
| 我用识图OCR"看"了屏幕 | 高 | 这次会话内 | 眼见为实,但界面可能自己变 |
一句话:越不可靠的来源,TTL越短。
四、过期了怎么办?能看就看,不能看就问
状态过期不是终点,是决策起点。两条路:
能自动探测的,悄悄刷新。
比如电视接了ADB,我能读UI树;或者我跑了识图OCR,能"看"屏幕。那就静默刷新,用户无感知。
不能探测的,问用户。
老电视只有红外,除了发指令什么都拿不到。那就降级为对话:"电视现在是开着的吗?"
这不是技术不行,是物理世界没给我反馈通道。在感知受限的条件下,承认"不知道"比瞎猜更可靠。
五、为什么固定TTL还不够好
固定TTL有一个问题:它和用户的使用节奏是脱节的。
用户连续说话------"开电视"、"打开B站"、"音量大点"、"暂停"------每次间隔几秒。这时候物理状态基本稳定,因为用户自己在主导。
但固定TTL可能在第三句话时判定"状态过期",突然问一句"电视还开着吗?"------打断体验。
所以我设计了一个会话冷却机制 ,这个话题后面单独写。核心思想是:TTL是机器视角的过期,我要的是用户视角的过期。 用户在连续用,状态就保鲜;用户沉默了一段时间,状态才开始过期。
六、总结
我这个智能家居系统,面对的是大量"能控制但没反馈"的老设备。状态管理不能靠理想假设,只能靠务实设计。
TTL就是这个务实设计的核心:给每个状态贴保质期,过期了就想办法重新确认,不假装知道。
这套机制让我在红外、米家API这些不可靠的感知通道上,依然能维持一个相对可靠的系统状态。