如何在ESP32上通过CSA Matter SDK获取当前实时时间
根据我对CSA Matter(又称Project CHIP)规范(11.16)的理解,Matter网络中的节点会通过TimeSync集群服务同步当前时间。若属实,应该能在应用代码中通过Matter获取当前实时时间。
Matter SDK包含多个处理时间的头文件和函数,SystemClock().GetClock_RealTime()看似可行,但调用后仅能获取设备开机后的微秒数而非实时时间;同头文件中的ToTimeval()可转换为timeval,但在我使用的ESP32版本中未定义该声明。
我使用的是Espressif Matter SDK的Arduino移植版jakubdybczak/esp32-arduino-matter。我还尝试访问Node 0上的时间服务,但返回的属性始终为null:
endpoint_t *root_endpoint = endpoint::get(node,0); esp_matter::cluster_t *time_cluster = cluster::create(root_endpoint,TimeSynchronization::Id, CLUSTER_FLAG_CLIENT); // in this example I'm looking at timezone, but the same thing happens for LocalTime::Id attribute_t *timezone_attribute = attribute::get(time_cluster,TimeSynchronization::Attributes::TimeZone::Id); // always NULL esp_matter_attr_val_t timezone_value = esp_matter_invalid(NULL); attribute::get_val(timezone_attribute, &timezone_value);
请问通过Matter获取当前实时时间的正确方式是什么?
1. 明确Matter时间同步的核心逻辑
Matter的TimeSync集群负责节点间的相对时间同步(用于事件排序、定时任务触发),并不直接提供Unix时间戳这类墙钟时间。墙钟时间的同步依赖配网设备(如手机、智能家居网关)通过NTP获取标准时间后,再通过Matter的Time集群同步给终端节点。
2. 正确获取同步后的实时时间
在你使用的ESP32 Arduino Matter移植版中,Matter完成时间同步后会自动更新ESP32的系统时间,因此直接调用标准C/ESP-IDF的时间接口即可拿到实时时间:
#include <esp_system.h> #include <time.h> void get_sync_real_time() { time_t now; struct tm timeinfo; time(&now); localtime_r(&now, &timeinfo); char time_str[64]; strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &timeinfo); Serial.printf("当前实时时间:%s\n", time_str); }
3. 修正TimeSync集群的错误用法
你之前的代码存在两个核心问题:
TimeSynchronization是服务器端集群,用于节点对外暴露时间同步能力,客户端无需创建该集群来获取时间- 墙钟时间对应的是
Time集群的LocalTime属性,但Matter设备通常会直接同步系统时间,无需手动读取该属性
4. 关于SystemClock().GetClock_RealTime()的说明
GetClock_RealTime()返回的是单调时间(从设备启动开始累计的时间),属于Matter内部用于定时和事件排序的时间基准,并非墙钟时间。如果SDK支持,可尝试使用GetClock_UTC()获取UTC时间,但更可靠的方式是直接调用ESP32系统时间接口。
内容的提问来源于stack exchange,提问作者emmby

