一
去年十月,我买了一块米家智能温湿度计3。到手之后却发现,时间竟会倒着走。拍视频给售后确认了之后,直接退了款,让我自己再下单一个。
新的很好,功能也正常。旧的售后也没要回去。那旧的怎么办?撇了?核心功能温湿度又没坏,所以我把它放在了我的桌前。时间嘛,电脑、手机、手表,哪个不能看。
不过看温湿度的时候,总是会注意到时间。看久了居然也看出了规律来。十分钟一循环。设定时间后,过了十分钟,就会又回到设定的时间。如果设定的时间刚好要在十分钟内跨小时,那么它将会在跨小时的时候重置,连十分钟都不到。我想办法让自己忽略时间,并关掉了星期显示,希望能让它不那么惹眼。
但看多了总觉得膈应。温湿度计的生命只有十分钟,我要给它完整的一生。起初,我以为是出厂固件的问题,但是升级、重刷都没有用。于是我想试试第三方的固件,看看能不能解决。
二
ATC
我没想到这么个小玩意还有人在折腾,于是满怀期待地刷了进去。
天啊!它活过了第一个十分钟,时间在十分钟之后依然在走!
看来问题就这么轻易地解决了,官方固件确实有问题。在第三方固件的加持下,甚至还更省电。这位温湿度计能安心地当它的摆件了。
三
好景不长,事与愿违。温湿度计还是难逃循环的命运。过了半个小时,我发现时钟又重置回了我设定的时刻。是不是这台机器的内存有问题,让它记录不了走过的这么长时间?
我把记录温湿度的间隔调长,最多记录的条数减到最少,希冀着它能走过更久的时间。上天似乎回应了我的愿望,温湿度计的时钟走过了半个小时,走过了四十五分钟,最终,倒在了整点之前。
整点似乎是个坚固的魔障,每当温湿度计的时钟想要跨越它,都会被无情地弹回上次同步的时刻。我取回温湿度计的记录,一次又一次跨越整点的尝试织成了一张紧密的网,似乎揭示着这温湿度计在一次次循环中沉沦的命运。

算了,我尽力了。我想。以后个隔三差五同步一下时间吧。但是,我亲爱的朋友,你知道的,隔三差五最终总是意味着永远。
直到昨天,我的温湿度计还困在2025年的十二月,没能走出那个冬天。
四
阴雨连绵,这两天空气潮湿得让我以为回到了南方。我的注意力又频繁回到了温湿度计上,为我的烦躁寻求一份解释。
我自然注意到了时间, 2025年十二月,那是我最后一次想起来给温湿度计同步的时间,距今已有将近半年。
好奇心又一次被勾起。我想知道这到底是怎么一回事,为什么时间会循环走不出整点,以及能不能修复。
米家温湿度计3
平时,主控会用自己的软件时间驱动LCD显示,在屏幕上展示具体的时间。每隔一段时间,主控就会从RTC读取更准确的时间来矫正自身,从而让显示的时间更加精准,同时降低功耗。而这个从RTC同步准确时间的间隔,在官方固件上是十分钟,在pvvx的固件上是每整小时。
对上了,都对上了。看起来是这块RTC芯片出了问题。
在Chat
利用pvvx固件暴露的BLE调试命令扫I²C总线。按照文档,我在私有服务0x1F10中的特征0x1F1F下发送了命令0x03,并且得到了返回通知(0x) 03-7C-88-A2。其中03是命令号,后边的就是I²C设备地址了。
0x就是RTC的地址,说明他还能在总线上ACK确认。问题出在RTC的内部。
进一步,发送04-01-10-A2-00-00读RTC的16个字节,得到04-01-A2-08-1F-FF-7F-3F-3F-07-9F-FF-FF-BF-BF-87-83-87-FF。
其中第四个08,也就是从RTC读出的第一个 (0x00) 字节,是Control1F,AF、TF、AIE、TIE全被点亮,意味着告警和定时器中断。
再往后,FF这一位就是秒了,最高位的VL被置位,表示芯片经历过电压跌落,所记的时间已经不可信。后边的分、时、日之类的也全是非法BCD。
如果运气好的话,把它覆写成正常的值就能让RTC恢复正常。可惜我的运气并不好。覆写成正常值之后半天没有动静,还是原来写入的时间。后来试了很多次,扣电池、短接、重置。除了Control变回了报错值之外,时种一秒也没有走。
排查到这里整件事就已经很明朗了:可能由于时钟源晶振坏了或者缺焊,导致RTC的计时震荡或者计数坏掉了,但自检却没发现,让时钟一直停在最后写入的值。而主控会按照设定好的时间间隔,从RTC读取这个固定的值,所以才会时间循环,一直重置到上次同步的时间。
五
知道问题了就好对症下药,把主控从RTC读精确时间这一行为改掉了就行。遗憾的是,似乎不能直接从软件上把RTC直接断电,不然还能更省电。
在Claude的协助下,我Clone了pvvx固件的源码。起初,我们以为把RTC从I²C上屏蔽掉就可以了:
void init_rtc(void) {
(void) rtc_init_b1;
(void) rtc_init_b2;
rtc_i2c_addr = 0;
utime_to_rtc(wrk.utc_time_sec, &rtc);
}
...
u32 rtc_get_utime(void) {
utime_to_rtc(wrk.utc_time_sec, &rtc);
return wrk.utc_time_sec;
}
但神奇的是,由于主控会在每跨小时的时候从RTC读取时间,所以主控计算时间时压根就没考虑过小时进位,还是会每跨小时就循环。所以还得把小时进位给加上:
#if (DEV_SERVICES & SERVICE_HARD_CLOCK)
u8 prev_min = rtc.minutes;
utime_to_rtc(wrk.utc_time_sec, &rtc);
if(rtc.minutes != prev_min)
SET_LCD_UPDATE();
#endif
找个Linux环境编译好,用Telink Flasher给刷进去。

现在,这台温湿度计终于走出了循环的魔沼,向着未来一去不复返。而我也拥有了一台虽然走时不太准,但是也能看的温湿度计。可喜可贺。●