间歇连接设备管理 Cluster(IcdManagement)
Cluster ID: 0x0046 |
所在 Endpoint: 固定在 Endpoint 0(根端点)
ICD Management 管理「间歇连接设备」(Intermittently Connected Device,简称 ICD), 也就是俗称的「休眠设备」或「Sleepy Device」—— 门窗传感器、温湿度传感器、电池供电的按钮等。 这些设备为了省电,大部分时间处于休眠状态,只在固定周期或特定事件时短暂唤醒通信。 ICD Management 负责定义设备的休眠/唤醒周期、管理订阅者注册、以及通过 Check-In 协议保持连接。
ICD 设备有两种运行模式:SIT(Short Idle Time)短空闲时间模式和 LIT(Long Idle Time)长空闲时间模式。 SIT 设备的空闲间隔较短(通常不超过 15 秒),Controller 可以在正常 MRP 重试窗口内等到设备醒来; LIT 设备的空闲间隔更长(可达数小时),Controller 必须依赖 Check-In 协议才能与设备建立通信。 LIT 模式显著延长电池寿命,但交互响应速度更慢。
命令(Commands)
ICD Management 共有 4 个命令。RegisterClient 和 UnregisterClient 用于管理
Check-In 消息的订阅者列表;StayActiveRequest 让设备临时保持唤醒。
点击下方表格中的命令 ID 可跳转到对应的详细说明。
| ID | 名称 | 方向 | 说明 | 所需特性 |
|---|---|---|---|---|
0x00 |
RegisterClient | Client → Server | 注册一个 Check-In 客户端 | CIP |
0x01 |
RegisterClientResponse | Server → Client | 注册结果,返回 ICDCounter | CIP |
0x02 |
UnregisterClient | Client → Server | 取消注册一个 Check-In 客户端 | CIP |
0x03 |
StayActiveRequest | Client → Server | 请求设备保持活跃一段时间 | LITS |
0x04 |
StayActiveResponse | Server → Client | 返回设备实际承诺的活跃时长 | LITS |
RegisterClient —— 注册客户端(0x00)
向 ICD 设备注册一个 Check-In 客户端。注册成功后,设备每次从休眠中唤醒时都会向该客户端发送 Check-In 消息,告知「我醒了,有什么事赶紧说」。这是 LIT 设备与 Controller 保持连接的核心机制。
| 参数 | 类型 | 说明 |
|---|---|---|
| CheckInNodeID | uint64 | 接收 Check-In 消息的目标节点 ID —— 通常是 Controller 或 Hub 的 NodeID |
| MonitoredSubject | uint64 | 被监控的 Subject(Case-AuthTag 或 NodeID)—— 标识哪个用户/实体在关注此设备 |
| Key | octstr (16 bytes) | HMAC 验证密钥 —— 用于验证 Check-In 消息的真实性,防止伪造 |
| VerificationKey | octstr (16 bytes) | 可选。验证密钥 —— 用于在注册时验证发起方的身份。如果设备要求验证,此字段必填 |
使用场景
配网完成后,Hub/Controller 向电池传感器注册自己为 Check-In 客户端。 之后传感器每次醒来时发送 Check-In 消息,Hub 收到后在设备短暂的活跃窗口内发送订阅请求或读取数据。
RegisterClientResponse —— 注册响应(0x01)
设备对 RegisterClient 的响应。返回当前的 ICDCounter 值, 客户端用它来验证后续收到的 Check-In 消息的新鲜度(防重放攻击)。
| 字段 | 类型 | 说明 |
|---|---|---|
| ICDCounter | uint32 | 设备当前的 Check-In 计数器值。客户端应保存此值,后续收到的 Check-In 消息的 Counter 必须大于此值 |
UnregisterClient —— 取消注册(0x02)
从 ICD 设备的注册列表中移除一个 Check-In 客户端。 移除后,设备不再向该客户端发送 Check-In 消息。
| 参数 | 类型 | 说明 |
|---|---|---|
| CheckInNodeID | uint64 | 要移除的客户端的节点 ID —— 必须与注册时使用的 CheckInNodeID 一致 |
| VerificationKey | octstr (16 bytes) | 可选。验证密钥 —— 同注册时的用途,防止未授权的取消注册 |
使用场景
用户从家庭中移除一个 Hub,该 Hub 需要先调用 UnregisterClient 将自己从所有已注册的 ICD 设备上注销, 避免设备继续向一个不存在的节点发送 Check-In 消息浪费电量。
StayActiveRequest —— 请求保持活跃(0x03)
请求 ICD 设备在活跃模式下额外保持一段时间,暂时不要回到休眠状态。 适用于需要与设备进行一系列交互(如 OTA 升级、批量配置)但设备默认活跃时间太短的场景。
| 参数 | 类型 | 说明 |
|---|---|---|
| StayActiveDuration | uint32 | 请求的额外活跃时长,单位毫秒。设备会在当前活跃周期结束后继续保持唤醒至少这么久 |
使用场景
Controller 需要对门窗传感器进行 OTA 固件升级。传感器的默认活跃窗口只有 10 秒,不够传输固件。 Controller 发送 StayActiveRequest(StayActiveDuration = 120000,即 2 分钟), 传感器回复 StayActiveResponse 告知实际可以维持多久,Controller 在此窗口内完成升级。
StayActiveResponse —— 保持活跃响应(0x04)
设备对 StayActiveRequest 的响应。设备可能无法完全满足请求的时长(例如电池电量不足), 响应中包含设备实际承诺的活跃时长。
| 字段 | 类型 | 说明 |
|---|---|---|
| PromisedActiveDuration | uint32 | 设备实际承诺的活跃时长,单位毫秒。可能小于请求值。Controller 应在此时间内完成所有操作 |
属性详解
ICD Management 的属性按功能分为四组。点击下方汇总表中的属性 ID 可跳转到对应的详细说明。
| ID | 名称 | 类型 | 分组 | 说明 |
|---|---|---|---|---|
0x0000 |
IdleModeDuration | uint32 | 休眠/唤醒参数 | 空闲模式持续时间(秒) |
0x0001 |
ActiveModeDuration | uint32 | 休眠/唤醒参数 | 活跃模式持续时间(毫秒) |
0x0002 |
ActiveModeThreshold | uint16 | 休眠/唤醒参数 | 活跃模式延长阈值(毫秒) |
0x0003 |
RegisteredClients | list<MonitoringRegistrationStruct> | 注册管理 | 已注册的监控客户端列表 |
0x0004 |
ICDCounter | uint32 | 注册管理 | Check-In 消息计数器 |
0x0005 |
ClientsSupportedPerFabric | uint16 | 注册管理 | 每个 Fabric 支持的最大注册客户端数 |
0x0006 |
UserActiveModeTriggerHint | UserActiveModeTriggerBitmap | 用户唤醒提示 | 用户可用的唤醒方式提示位图 |
0x0007 |
UserActiveModeTriggerInstruction | string (max 128) | 用户唤醒提示 | 唤醒操作的文字说明 |
0x0008 |
OperatingMode | OperatingModeEnum | 运行模式 | 当前运行模式(SIT / LIT) |
0x0009 |
MaximumCheckInBackOff | uint32 | 运行模式 | Check-In 最大回退间隔(秒) |
休眠/唤醒参数(0x0000-0x0002)
定义设备的休眠与唤醒周期参数。这三个值直接决定了设备的省电程度和通信响应速度 —— 空闲时间越长越省电,但响应越慢。
IdleModeDuration 的单位是秒,
而 ActiveModeDuration 和 ActiveModeThreshold 的单位是毫秒。
例如 IdleModeDuration = 300 表示空闲 5 分钟,ActiveModeDuration = 10000 表示活跃 10 秒。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0000 |
IdleModeDuration 空闲模式时长 |
uint32 | 设备在空闲(休眠)模式下的持续时间,单位秒。这段时间内设备不主动收发消息。SIT 设备通常 ≤ 15 秒,LIT 设备可达数小时。最小值 1 秒 |
0x0001 |
ActiveModeDuration 活跃模式时长 |
uint32 | 设备在活跃模式下的持续时间,单位毫秒。设备每次醒来后至少保持这么久的通信窗口。最小值 300 毫秒 |
0x0002 |
ActiveModeThreshold 活跃模式延长阈值 |
uint16 | 设备在活跃模式下收到通信后,额外延长的活跃时间,单位毫秒。每次收到消息都会重新计时,避免正在交互时设备突然休眠。SIT 设备最小值 300ms,LIT 设备最小值 5000ms |
SIT 设备的 IdleModeDuration ≤ 15 秒,与 MRP 的 Idle Retransmission Timeout 对齐,
Controller 可以在正常重试窗口内等到设备醒来。
如果 IdleModeDuration > 15 秒,设备就是 LIT 模式,Controller 必须等 Check-In 消息才能通信。
注册管理(0x0003-0x0005)
管理 Check-In 客户端的注册列表。只有注册过的客户端才会收到设备的 Check-In 消息。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0003 |
RegisteredClients 已注册客户端 |
list<MonitoringRegistrationStruct> | 当前已注册的 Check-In 客户端列表。每个 Fabric 的注册数不超过 ClientsSupportedPerFabric。需要 CIP 特性 |
0x0004 |
ICDCounter Check-In 计数器 |
uint32 | 设备发送 Check-In 消息的单调递增计数器。客户端据此检测消息重放 —— 如果收到的 Counter ≤ 上次保存的值,说明可能是重放攻击。需要 CIP 特性 |
0x0005 |
ClientsSupportedPerFabric 每 Fabric 最大客户端数 |
uint16 | 每个 Fabric 最多可注册的 Check-In 客户端数量。最小值 1。受限于设备的存储和电量资源 —— 更多客户端意味着每次唤醒时要发更多 Check-In 消息。需要 CIP 特性 |
用户唤醒提示(0x0006-0x0007)
当 Controller 需要与 LIT 设备通信但不想等 Check-In 时,可以提示用户手动唤醒设备。 这两个属性告诉 App 如何指导用户操作 —— 比如「按一下设备上的按钮」或「打开/关闭门窗一次」。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0006 |
UserActiveModeTriggerHint 唤醒方式提示 |
UserActiveModeTriggerBitmap | 位图,标识用户可以通过哪些方式手动唤醒设备。App 应根据此位图显示对应的引导提示。需要 UAT 特性 |
0x0007 |
UserActiveModeTriggerInstruction 唤醒操作说明 |
string (max 128) | 厂商自定义的操作说明文字。当位图中设置了 ActuateSensorLightsBlink 等较特殊的触发方式时,此字段提供具体的操作指引(如「连续按顶部按钮 3 次」)。需要 UAT 特性 |
UserActiveModeTriggerBitmap 常见位
运行模式(0x0008-0x0009)
设备当前的运行模式和 Check-In 回退参数。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0008 |
OperatingMode 运行模式 |
OperatingModeEnum | 设备当前的 ICD 运行模式:SIT(短空闲)或 LIT(长空闲)。支持 DSLS 特性的设备可以在两种模式间动态切换。需要 LITS 特性 |
0x0009 |
MaximumCheckInBackOff 最大 Check-In 回退间隔 |
uint32 | 设备在没有已注册客户端时,Check-In 消息的最大发送间隔,单位秒。设备会逐渐拉长间隔直到此上限,用于在无人监听时进一步省电。需要 LITS 特性 |
枚举速查
OperatingModeEnum —— 运行模式
描述 ICD 设备的当前运行模式,对应 OperatingMode (0x0008) 属性。
数据结构
MonitoringRegistrationStruct
描述一个已注册的 Check-In 客户端的信息,是 RegisteredClients (0x0003) 属性中每个列表元素的结构。
| 字段 | 类型 | 说明 |
|---|---|---|
| CheckInNodeID | uint64 | 接收 Check-In 消息的节点 ID —— 通常是注册时的 Controller 或 Hub |
| MonitoredSubject | uint64 | 被监控的 Subject —— 标识哪个用户或实体关注此设备 |
| FabricIndex | uint8 | 该注册所属的 Fabric 索引 |
MonitoringRegistrationStruct 数据示例:
{
"CheckInNodeID": 1, // Check-In 消息目标节点 ID
"MonitoredSubject": 112233, // 被监控的 Subject(通常是用户的 NodeID)
"FabricIndex": 1 // 所属 Fabric 索引
}
Feature 位图
ICD Management 通过 FeatureMap(0xFFFC)声明设备支持的 ICD 能力:
LITS 依赖 CIP(长空闲设备必须支持 Check-In 协议才能被找到),DSLS 依赖 LITS(动态切换必须先支持 LIT 模式)。
因此,一个支持 DSLS 的设备的 FeatureMap 至少是 0b1111(CIP + UAT + LITS + DSLS)。
示例数据
一个运行在 LIT 模式下的电池门窗传感器的 ICD Management Cluster 读取结果:
{
// --- 休眠/唤醒时间参数 ---
"0x0000": 300, // IdleModeDuration = 300 秒(空闲模式持续 5 分钟)
"0x0001": 10, // ActiveModeDuration = 10000 毫秒(活跃模式持续 10 秒)
"0x0002": 5000, // ActiveModeThreshold = 5000 毫秒(活跃模式延长阈值 5 秒)
// --- 注册管理 ---
"0x0003": [ // RegisteredClients(已注册的监控客户端列表)
{
"CheckInNodeID": 1,
"MonitoredSubject": 1,
"FabricIndex": 1
}
],
"0x0004": 42, // ICDCounter = 42(Check-In 消息计数器)
"0x0005": 2, // ClientsSupportedPerFabric = 2(每个 Fabric 最多注册 2 个客户端)
// --- 用户唤醒提示 ---
"0x0006": 1, // UserActiveModeTriggerHint = PowerCycle(提示用户通过重新上电唤醒)
"0x0007": "", // UserActiveModeTriggerInstruction = ""(无额外说明)
// --- 运行模式 ---
"0x0008": 1, // OperatingMode = LIT(长空闲时间模式)
"0x0009": 3600 // MaximumCheckInBackOff = 3600 秒(最大 Check-In 回退间隔 1 小时)
}
读取 ICD Management 属性时需注意设备可能正在休眠。
对于 SIT 设备,Controller 可以在 MRP 重试窗口内等到设备醒来并完成读取;
对于 LIT 设备,需要先收到 Check-In 消息或用户手动唤醒后才能读取。
读取前可先检查 OperatingMode (0x0008) 判断设备的运行模式。
常见场景
场景 1:配网后注册 Check-In 监控
- 完成设备配网后,读取
FeatureMap (0xFFFC)确认设备支持 CIP 特性 - 读取
ClientsSupportedPerFabric (0x0005)确认还有注册名额 - 发送
RegisterClient (0x00),传入 Hub 的 NodeID 作为 CheckInNodeID,并生成一个 16 字节的 HMAC Key - 保存
RegisterClientResponse中返回的 ICDCounter 值,用于后续 Check-In 消息验证 - 设备每次醒来时,Hub 会收到 Check-In 消息,在活跃窗口内完成数据同步
场景 2:OTA 升级 —— 延长活跃窗口
- 等待 LIT 设备发送 Check-In 消息(或提示用户手动唤醒设备)
- 在设备活跃窗口内,发送
StayActiveRequest (0x03),请求足够长的活跃时间(如 120 秒) - 检查
StayActiveResponse中的PromisedActiveDuration,确认设备实际承诺的时长 - 在承诺的时间窗口内执行 OTA 升级流程
- 如果一次不够,可在窗口结束前再发一次 StayActiveRequest 续时