时间同步 Cluster(TimeSynchronization)

Cluster ID: 0x0038  |  所在 Endpoint: 固定在 Endpoint 0(Root Endpoint)

TimeSynchronization 负责 Matter 设备的时间管理 —— 让设备知道「现在几点」「在哪个时区」「有没有夏令时」。 很多功能依赖准确的时间:定时自动化、日志时间戳、证书有效期校验、能源统计等。 没有时间同步,这些功能要么无法工作,要么会给出错误的结果。

Feature 特性

TimeSynchronization Cluster 定义了三个 Feature,设备根据自身能力选择支持: TZ(时区管理)支持时区列表和夏令时配置; NTPC(NTP 客户端)可主动从 NTP 服务器获取时间; NTPS(NTP 服务器)可作为时间源向其他设备提供时间。 未启用任何 Feature 的设备仅支持最基础的 SetUTCTime 手动设置时间。

命令(Commands)

TimeSynchronization Cluster 共有 5 个请求命令,其中 SetTimeZone 有对应的响应命令。 最基础的 SetUTCTime 所有设备都支持,其余命令需要设备启用对应的 Feature。 点击下方表格中的命令 ID 可跳转到对应的详细说明。

ID 名称 说明 所需特性
0x00 SetUTCTime 设置设备的 UTC 时间 无
0x01 SetTrustedTimeSource 指定可信时间源节点 无
0x02 SetTimeZone 设置时区列表 TZ
0x04 SetDSTOffset 设置夏令时偏移列表 TZ
0x05 SetDefaultNTP 设置默认 NTP 服务器地址 NTPC

SetUTCTime —— 设置 UTC 时间(0x00)

直接设置设备的 UTC 时间。这是最基础的时间设置方式 —— 在配网阶段,Commissioner 通常通过此命令为设备注入当前时间。 设备收到后会同时更新 Granularity 和 TimeSource 属性。

参数类型说明
UTCTime epoch_us UTC 时间,微秒级(自 2000-01-01T00:00:00Z 起的微秒数)
Granularity GranularityEnum 时间精度等级 —— 告知设备这个时间有多精确
TimeSource TimeSourceEnum 时间来源 —— 告知设备这个时间从哪里获取
时间精度要求

设备会根据 Granularity 参数判断时间的可靠性。 如果设备当前已有更高精度的时间源(例如已从 NTP 同步),它可能会拒绝来自低精度源的 SetUTCTime 请求。 配网阶段设备通常没有时间,此时设置一定会成功。

使用场景

最常见的使用场景是配网完成后,Commissioner 立即调用 SetUTCTime 为设备设置初始时间。 Granularity 通常传 SecondsGranularity (2) 或 MillisecondsGranularity (3), TimeSource 传 Admin (2)(表示时间由管理者手动设置)。

SetTrustedTimeSource —— 设置可信时间源(0x01)

指定一个 Fabric 内的节点作为可信时间源。设备会周期性地从这个节点同步时间, 类似于局域网内部的「时间权威」。设置为 null 可清除可信时间源。

参数类型说明
TrustedTimeSource struct / null 可信时间源节点信息,包含 NodeID 和 Endpoint。设为 null 清除

TrustedTimeSource 结构体

字段类型说明
NodeID node-id 时间源节点的 Node ID
Endpoint endpoint-no 该节点上 TimeSynchronization Cluster 所在的 Endpoint(通常是 0)
使用场景

在 Fabric 中,通常由 Hub(如 Apple HomePod、Google Nest Hub)充当可信时间源。 Commissioner 在配网时设置 TrustedTimeSource 指向 Hub 的 Node ID, 之后设备就会自动从 Hub 同步时间,无需外部 NTP 服务器。 这对于没有直接互联网访问的 Thread 设备尤其重要。

SetTimeZone —— 设置时区(0x02)

设置设备的时区列表。可以包含多个时区条目,每个条目有生效时间(validAt), 用于支持历史或未来的时区变更。设备处理成功后返回 SetTimeZoneResponse, 告知 Commissioner 是否需要继续设置夏令时偏移。

参数类型说明
TimeZone list<TimeZoneStruct> 时区列表(最多 TimeZoneListMaxSize 个条目)

TimeZoneStruct 结构体

字段类型说明
Offset int32 相对 UTC 的偏移量,单位秒。例如 UTC+8 = 28800,UTC-5 = -18000
ValidAt epoch_us 此条目的生效时间(微秒级 epoch)。第一个条目的 ValidAt 必须为 0
Name string(可选) IANA 时区名称(如 "Asia/Shanghai"),用于显示和夏令时数据库查询

SetTimeZoneResponse 响应字段

字段类型说明
DSTOffsetRequired bool true 表示设备需要 Commissioner 接着调用 SetDSTOffset
DSTOffsetRequired 的含义

如果设备内置了 IANA 时区数据库(TimeZoneDatabase = Full), 设备可以自己推算夏令时规则,此时响应 DSTOffsetRequired = false。 如果设备没有时区数据库(TimeZoneDatabase = None), 则返回 true,Commissioner 必须手动下发夏令时偏移。

使用场景

用户搬家到新时区,或设备首次配网时需要设置时区。 对于中国用户,通常只需一条记录:Offset = 28800(UTC+8),ValidAt = 0,Name = "Asia/Shanghai"。 中国没有夏令时,所以 DSTOffset 可以设为偏移量 0 的单条记录。

SetDSTOffset —— 设置夏令时偏移(0x04)

设置夏令时(DST)偏移列表。每个条目定义一段时间范围内的额外偏移量。 设备根据当前时间匹配对应的条目,将偏移量叠加到时区偏移上,得出本地时间。

参数类型说明
DSTOffset list<DSTOffsetStruct> 夏令时偏移列表(最多 DSTOffsetListMaxSize 个条目)

DSTOffsetStruct 结构体

字段类型说明
Offset int32 夏令时额外偏移量,单位秒。例如美国夏令时 = 3600(+1 小时),无夏令时 = 0
ValidStarting epoch_us 此条目的生效起始时间(微秒级 epoch)
ValidUntil epoch_us / null 此条目的失效时间。最后一条的 ValidUntil 必须为 null(表示一直有效直到被新列表替换)
本地时间计算

LocalTime = UTCTime + TimeZone.Offset + DSTOffset.Offset
例如:UTC 时间 12:00,时区 UTC+8(28800 秒),夏令时 +1h(3600 秒)→ 本地时间 21:00。 对于不使用夏令时的地区(如中国),DSTOffset 列表只需一条 Offset = 0 的记录。

使用场景

美国东部时区(UTC-5)的设备需要在每年 3 月第二个周日进入夏令时(+1h), 11 月第一个周日退出。Commissioner 可以下发两条 DSTOffset 记录来覆盖当前年份的切换。 当列表中最后一条的 ValidUntil 到期后,设备会触发 DSTTableEmpty 事件, 提醒 Commissioner 需要更新夏令时表。

SetDefaultNTP —— 设置默认 NTP 服务器(0x05)

设置设备用于时间同步的默认 NTP 服务器地址。需要设备启用 NTPC(NTP 客户端)特性。 设为 null 可清除默认 NTP 服务器。

参数类型说明
DefaultNTP string / null NTP 服务器地址(域名或 IPv6 地址)。设为 null 清除
DNS 解析能力

如果传入的是域名(如 "pool.ntp.org"),设备需要具备 DNS 解析能力 (检查 SupportsDNSResolve 属性)。 不支持 DNS 的设备只能接受 IPv6 地址形式的 NTP 服务器。

使用场景

配网完成后,Commissioner 可以为支持 NTPC 的设备配置 NTP 服务器。 设备随后会自动通过 NTP 协议同步时间,不再依赖 Commissioner 手动设置。 常用的公共 NTP 服务器:pool.ntp.org、time.google.com、ntp.aliyun.com。

属性详解

TimeSynchronization Cluster 共有 13 个应用属性。点击下方汇总表中的属性 ID 可跳转到对应的详细说明。

ID 名称 类型 分组 说明
0x0000 UTCTime epoch_us / null 时间状态 当前 UTC 时间(微秒级)
0x0001 Granularity GranularityEnum 时间状态 当前时间的精度等级
0x0002 TimeSource TimeSourceEnum 时间状态 当前时间的来源
0x0003 TrustedTimeSource struct / null 时间源配置 Fabric 内可信时间源节点
0x0004 DefaultNTP string / null 时间源配置 默认 NTP 服务器地址
0x0005 TimeZone list<TimeZoneStruct> 时区与夏令时 时区配置列表
0x0006 DSTOffset list<DSTOffsetStruct> 时区与夏令时 夏令时偏移列表
0x0007 LocalTime epoch_us / null 时区与夏令时 当前本地时间(已含时区 + 夏令时偏移)
0x0008 TimeZoneDatabase TimeZoneDatabaseEnum 能力与限制 设备的时区数据库类型
0x0009 NTPServerAvailable bool 能力与限制 设备是否可用作 NTP 服务器
0x000A TimeZoneListMaxSize uint8 能力与限制 时区列表最大条目数
0x000B DSTOffsetListMaxSize uint8 能力与限制 夏令时偏移列表最大条目数
0x000C SupportsDNSResolve bool 能力与限制 是否支持 DNS 域名解析

时间状态(0x0000 ~ 0x0002)

描述设备当前的时间值以及时间的精度和来源。

ID名称类型说明
0x0000 UTCTime
UTC 时间
epoch_us / null 设备当前的 UTC 时间,微秒级精度(自 2000-01-01T00:00:00Z 起)。 null 表示设备尚未获得有效时间 —— 这是刚上电、未经时间同步的设备的默认状态
0x0001 Granularity
时间精度
GranularityEnum 当前时间的精度等级。NoTimeGranularity (0) 表示设备没有可信时间。 精度越高,说明时间来源越可靠(见下方枚举定义)
0x0002 TimeSource
时间来源
TimeSourceEnum 当前时间是从哪里获取的 —— NTP、管理员手动设置、GNSS、还是其他 Matter 节点等。 用于判断时间的可信程度(见下方枚举定义)
Epoch 基准

Matter 的时间 epoch 基准是 2000-01-01T00:00:00Z,不是 Unix 的 1970 年。 转换公式:Matter epoch_us = (Unix timestamp - 946684800) * 1000000。 读取 UTCTime 后需要注意转换。

时间源配置(0x0003, 0x0004)

描述设备的时间同步源 —— 从哪里获取精确时间。

ID名称类型说明
0x0003 TrustedTimeSource
可信时间源
struct / null Fabric 内指定的可信时间源节点。包含 FabricIndex、NodeID 和 Endpoint 三个字段。 null 表示未配置。通过 SetTrustedTimeSource 命令设置
0x0004 DefaultNTP
默认 NTP 服务器
string / null 设备使用的默认 NTP 服务器地址(域名或 IPv6 地址)。 null 表示未配置。通过 SetDefaultNTP 命令设置。 需要 NTPC 特性
时间源优先级

设备获取时间的优先级通常是:NTP 服务器 > 可信时间源节点 > 管理员手动设置。 如果设备支持 NTPC 且配置了 DefaultNTP,它会自动通过 NTP 同步,精度最高。 对于不能直接访问互联网的 Thread 设备,TrustedTimeSource 是唯一的自动同步途径。

时区与夏令时(0x0005 ~ 0x0007)

管理时区配置、夏令时偏移和本地时间计算。需要设备启用 TZ 特性。

ID名称类型说明
0x0005 TimeZone
时区列表
list<TimeZoneStruct> 当前生效的时区配置列表。每条包含 Offset(秒)、ValidAt(生效时间)、Name(IANA 时区名)。 通过 SetTimeZone 命令设置。需要 TZ 特性
0x0006 DSTOffset
夏令时偏移列表
list<DSTOffsetStruct> 当前生效的夏令时偏移列表。每条包含 Offset(秒)、ValidStarting、ValidUntil。 通过 SetDSTOffset 命令设置。需要 TZ 特性
0x0007 LocalTime
本地时间
epoch_us / null 设备计算得出的本地时间 = UTCTime + TimeZone.Offset + DSTOffset.Offset。 null 表示缺少 UTC 时间或时区配置,无法计算。只读属性。需要 TZ 特性

能力与限制(0x0008 ~ 0x000C)

描述设备在时间同步方面的能力上限和硬件特性。这些属性大部分是只读的,由设备固件决定。

ID名称类型说明
0x0008 TimeZoneDatabase
时区数据库
TimeZoneDatabaseEnum 设备内置的时区数据库类型。 Full (0) = 完整 IANA 数据库,可自动推算夏令时; Partial (1) = 部分数据库; None (2) = 无数据库,完全依赖 Commissioner 手动设置。需要 TZ 特性
0x0009 NTPServerAvailable
NTP 服务器可用
bool 设备自身是否可作为 NTP 服务器向其他节点提供时间。 true 表示其他设备可以将此设备设为 TrustedTimeSource。 需要 NTPS 特性
0x000A TimeZoneListMaxSize
时区列表上限
uint8 TimeZone 列表允许的最大条目数。最小为 1,最大为 2。 SetTimeZone 的列表长度不能超过此值。需要 TZ 特性
0x000B DSTOffsetListMaxSize
夏令时列表上限
uint8 DSTOffset 列表允许的最大条目数。 SetDSTOffset 的列表长度不能超过此值。需要 TZ 特性
0x000C SupportsDNSResolve
支持 DNS 解析
bool 设备是否支持将域名解析为 IP 地址。 如果为 false,SetDefaultNTP 只能接受 IPv6 地址,不能传域名。 需要 NTPC 特性

Feature 位图

TimeSynchronization Cluster 通过 FeatureMap(0xFFFC)声明设备支持哪些时间同步能力:

Bit 0
TZ(TimeZone) 时区管理 —— 支持 SetTimeZone、SetDSTOffset 命令,以及时区、夏令时、本地时间相关属性
Bit 1
NTPC(NTPClient) NTP 客户端 —— 设备可主动从 NTP 服务器同步时间,支持 SetDefaultNTP 命令
Bit 2
NTPS(NTPServer) NTP 服务器 —— 设备自身可作为时间源,向 Fabric 内其他设备提供 NTP 时间服务
常见组合

基础设备(如低功耗传感器):无 Feature,仅支持 SetUTCTime 手动设置;
普通设备(如灯、插座):TZ,支持时区和夏令时配置;
联网设备(如 Wi-Fi 灯):TZ + NTPC,可自动从 NTP 同步;
Hub 设备(如边界路由器):TZ + NTPC + NTPS,不仅自己同步,还能为其他设备提供时间。

枚举定义

GranularityEnum

描述设备当前时间的精度等级。精度越高,表示设备的时间源越可靠。

0
NoTimeGranularity 无有效时间 —— 设备尚未获取任何时间信息
1
MinutesGranularity 分钟级精度 —— 时间误差可能达到数分钟
2
SecondsGranularity 秒级精度 —— 时间误差在秒级范围内
3
MillisecondsGranularity 毫秒级精度 —— 通常来自 NTP 同步
4
MicrosecondsGranularity 微秒级精度 —— 通常来自 PTP 或 GNSS

TimeSourceEnum

标识设备当前时间的获取来源。数值越高通常意味着更可靠的时间源。NTS 后缀表示使用了网络时间安全(Network Time Security)认证。

0
None 无时间源
1
Unknown 来源未知
2
Admin 管理员手动设置(通过 SetUTCTime)
3
NodeTimeCluster 从其他 Matter 节点的 TimeSynchronization Cluster 同步
4
NonMatterSNTP 非 Matter 网络的 SNTP 服务器
5
NonMatterNTP 非 Matter 网络的 NTP 服务器
6
MatterSNTP Matter Fabric 内的 SNTP 服务器
7
MatterNTP Matter Fabric 内的 NTP 服务器
8
MixedNTP 混合 NTP 源(Matter + 非 Matter)
9
NonMatterSNTPNTS 非 Matter SNTP + NTS 认证
10
NonMatterNTPNTS 非 Matter NTP + NTS 认证
11
MatterSNTPNTS Matter SNTP + NTS 认证
12
MatterNTPNTS Matter NTP + NTS 认证
13
MixedNTPNTS 混合 NTP 源 + NTS 认证
14
CloudSource 云端时间源
15
PTP 精确时间协议(IEEE 1588),微秒级精度
16
GNSS 全球导航卫星系统(GPS/北斗等),最高精度时间源

TimeZoneDatabaseEnum

描述设备内置的时区数据库能力,决定设备能否自行推算夏令时规则。

0
Full 完整 IANA 时区数据库 —— 设备可自动推算夏令时,SetTimeZone 后通常不需要手动设置 DSTOffset
1
Partial 部分时区数据库 —— 仅覆盖部分地区,不在覆盖范围内的仍需手动设置 DSTOffset
2
None 无时区数据库 —— 完全依赖 Commissioner 手动下发时区和夏令时配置

事件(Events)

TimeSynchronization Cluster 定义了 5 个事件,用于通知 Commissioner 或自动化系统时间状态的变化。

事件名称 严重级别 所需特性 说明
DSTTableEmpty Info TZ 夏令时表已耗尽 —— 所有 DSTOffset 条目都已过期,设备无法继续正确计算本地时间。Commissioner 需要下发新的 DSTOffset 列表
DSTStatus Info TZ 夏令时状态变更 —— 设备进入或退出夏令时。包含一个 DSTOffsetActive 布尔字段,true = 夏令时生效中
TimeZoneStatus Info TZ 时区切换 —— 时区列表中的下一条生效了(ValidAt 到达)。包含新的 Offset 和 Name 字段
TimeFailure Info 无 时间同步失败 —— 设备无法从任何时间源获取或验证时间。可能是 NTP 不可达、可信时间源离线等原因
MissingTrustedTimeSource Info 无 缺少可信时间源 —— 设备需要时间同步但没有配置 TrustedTimeSource,也没有可用的 NTP。提醒 Commissioner 配置时间源
事件订阅建议

建议 Commissioner 订阅 DSTTableEmpty 和 TimeFailure 事件。 前者在夏令时表过期时触发,如果不及时更新,设备的本地时间会出错(影响定时自动化等功能); 后者在时间同步链路断裂时触发,可及时发现并修复问题。

示例数据

属性数据示例

以下是一个支持 TZ + NTPC 的智能灯(中国地区)的 TimeSynchronization Cluster 典型属性数据:

{
  // --- 时间状态 ---
  "0x0000": 1695312000000000,    // UTCTime = 2023-09-21T16:00:00Z(微秒级 epoch)
  "0x0001": 3,                   // Granularity = MillisecondsGranularity
  "0x0002": 7,                   // TimeSource = MatterNTP

  // --- 信任时间源 ---
  "0x0003": {                    // TrustedTimeSource
    "fabricIndex": 1,
    "nodeID": "0x0000000000000001",
    "endpoint": 0
  },
  "0x0004": "pool.ntp.org",      // DefaultNTP

  // --- 时区与夏令时 ---
  "0x0005": [{                   // TimeZone
    "offset": 28800,             //   UTC+8(秒)
    "validAt": 0,
    "name": "Asia/Shanghai"
  }],
  "0x0006": [{                   // DSTOffset
    "offset": 0,                 //   无夏令时
    "validStarting": 0,
    "validUntil": null
  }],

  // --- 本地时间 ---
  "0x0007": 1695340800000000,    // LocalTime(已加时区偏移)

  // --- 能力与限制 ---
  "0x0008": 1,                   // TimeZoneDatabase = Full
  "0x0009": false,               // NTPServerAvailable = false
  "0x000A": 2,                   // TimeZoneListMaxSize = 2
  "0x000B": 2,                   // DSTOffsetListMaxSize = 2
  "0x000C": true                 // SupportsDNSResolve = true
}

SetUTCTime 交互示例

Commissioner 在配网完成后为设备设置初始时间:

// Commissioner → Device:设置 UTC 时间
{
  "invokeRequests": [{
    "commandPath": {
      "endpointId": 0,
      "clusterId": "0x0038",
      "commandId": "0x00"            // SetUTCTime
    },
    "commandFields": {
      "UTCTime": 1695312000000000,   // 2023-09-21T16:00:00Z(微秒)
      "granularity": 3,              // MillisecondsGranularity
      "timeSource": 2                // Admin
    }
  }]
}

SetTimeZone 交互示例

为设备设置中国时区(UTC+8):

// Commissioner → Device:设置时区
{
  "invokeRequests": [{
    "commandPath": {
      "endpointId": 0,
      "clusterId": "0x0038",
      "commandId": "0x02"            // SetTimeZone
    },
    "commandFields": {
      "timeZone": [{
        "offset": 28800,             // UTC+8(秒)
        "validAt": 0,                // 立即生效
        "name": "Asia/Shanghai"      // IANA 时区名(可选)
      }]
    }
  }]
}

// Device → Commissioner:确认时区设置
{
  "DSTOffsetRequired": true          // 需要跟进设置夏令时偏移
}
开发提示

大多数 Matter SDK(如 connectedhomeip)在配网流程中会自动处理基础的时间设置。 App 开发者通常只需要关注时区配置(特别是用户更换地区时),以及夏令时表的定期更新。 订阅 DSTTableEmpty 事件可以在需要更新时得到通知。

常见场景

场景 1:配网时设置初始时间
  1. 配网完成(CommissioningComplete 成功)后,读取设备的 FeatureMap (0xFFFC) 确认时间同步能力
  2. 发送 SetUTCTime (0x00),注入当前 UTC 时间,Granularity = SecondsGranularity (2),TimeSource = Admin (2)
  3. 发送 SetTrustedTimeSource (0x01),指定 Fabric 中的 Hub 作为可信时间源
  4. 如果设备支持 NTPC,发送 SetDefaultNTP (0x05) 配置 NTP 服务器
  5. 验证:读取 UTCTime (0x0000) 确认时间已设置,Granularity (0x0001) 不再是 0

设备后续会自动从 NTP 或 TrustedTimeSource 同步时间,精度会逐步提升。

场景 2:时区配置(用户搬家到新时区)
  1. 确认设备支持 TZ 特性(FeatureMap Bit 0 = 1)
  2. 读取 TimeZoneListMaxSize (0x000A) 确认列表容量
  3. 发送 SetTimeZone (0x02),传入新时区信息:
    • 从北京搬到纽约:Offset = -18000(UTC-5),Name = "America/New_York"
  4. 检查响应的 DSTOffsetRequired:
    • 如果 true:设备没有内置时区数据库,需要接着调用 SetDSTOffset (0x04) 手动设置美东夏令时规则
    • 如果 false:设备有内置数据库,已自动推算夏令时,无需额外操作
  5. 验证:读取 LocalTime (0x0007) 确认本地时间已正确反映新时区
场景 3:NTP 自动同步配置
  1. 确认设备支持 NTPC 特性(FeatureMap Bit 1 = 1)
  2. 检查 SupportsDNSResolve (0x000C):
    • true:可以传域名,如 "pool.ntp.org"
    • false:只能传 IPv6 地址
  3. 发送 SetDefaultNTP (0x05),设置 NTP 服务器地址
  4. 等待一段时间后,读取 Granularity (0x0001) 和 TimeSource (0x0002), 确认已从 NTP 成功同步(Granularity 应提升到 MillisecondsGranularity,TimeSource 变为 NTP 相关值)

推荐的 NTP 服务器:pool.ntp.org(全球)、ntp.aliyun.com(中国)、time.google.com(全球)。 对于企业环境,可以使用内部 NTP 服务器以确保安全性。

场景 4:处理 DSTTableEmpty 事件(夏令时表过期)
  1. 订阅设备的 DSTTableEmpty 事件
  2. 收到事件后,说明所有 DSTOffset 条目已过期
  3. 根据设备所在时区查询未来的夏令时切换时间
  4. 发送 SetDSTOffset (0x04),下发新的夏令时偏移列表
  5. 最后一条的 ValidUntil 设为 null,确保列表覆盖到下次更新

注意:如果不及时处理此事件,设备的 LocalTime 会因为缺少夏令时信息而出错, 影响所有依赖本地时间的自动化规则(如「每天早上 7 点开灯」实际上会提前或延后一小时)。

场景 5:Thread 设备的时间同步策略

Thread 设备通常没有直接的互联网访问能力,无法使用 NTP。它们依赖以下时间同步链路:

  1. 配网阶段:Commissioner 通过 SetUTCTime 注入初始时间
  2. 运行阶段:通过 SetTrustedTimeSource 指向 Thread 边界路由器(Border Router), 边界路由器从互联网获取 NTP 时间后转发给 Thread 设备
  3. 如果 TrustedTimeSource 离线,设备会触发 MissingTrustedTimeSource 事件
  4. 时间精度会逐渐降低(Granularity 可能从 Milliseconds 退化到 Seconds 甚至 Minutes)

最佳实践:确保 Fabric 中至少有一个可靠的时间源节点(如 Hub 或边界路由器), 并在配网时为所有设备配置 TrustedTimeSource 指向它。