物理开关 Cluster(Switch)
Cluster ID: 0x003B |
所在 Endpoint: 通常在 Endpoint 1(功能端点)
Switch Cluster 描述的是物理输入设备 —— 墙壁上的拨动开关、门铃按钮、调光旋钮等。 它不控制任何输出(开灯、关灯那是 OnOff Cluster 的事),而是把用户的物理操作转化为事件, 由绑定的目标设备或自动化规则来决定具体动作。
容易混淆的两个 Cluster:Switch(0x003B)是物理输入设备,负责上报「用户按了什么」; OnOff(0x0006)是输出控制,负责执行「设备开还是关」。 一个墙壁开关面板通常同时包含两者 —— Switch 检测按压动作,OnOff 执行开关控制。 但 Switch Cluster 本身没有任何命令,它是纯粹的事件源。
Switch Cluster 是 Matter 中最典型的事件驱动 Cluster。 它没有命令(不接受外部指令),所有信息通过事件上报。 控制器(手机、Hub)需要订阅事件来感知用户操作,而不是轮询属性变化。
Feature 位图
Switch Cluster 的 Feature Map 非常重要 —— 它决定了设备是哪种类型的开关,以及会上报哪些事件。 设备必须声明 LS(锁定开关)或 MS(瞬时开关)中的一个,且两者互斥。
LS 和 MS 二选一,不能同时声明。
MSR 依赖 MS(只有瞬时开关才有「松手」概念)。
MSL 和 MSM 都依赖 MS + MSR(需要精确的按下/释放时机才能判断长按或连击)。
Feature 组合示例
| 设备类型 | Feature 值 | 启用的 Feature | 支持的事件 |
|---|---|---|---|
| 传统墙壁拨动开关 | 0x01 |
LS | SwitchLatched |
| 简单按钮 | 0x06 |
MS + MSR | InitialPress, ShortRelease |
| 支持长按的按钮 | 0x0E |
MS + MSR + MSL | InitialPress, ShortRelease, LongPress, LongRelease |
| 全功能按钮(长按 + 连击) | 0x1E |
MS + MSR + MSL + MSM | 全部瞬时事件 |
属性详解
Switch Cluster 只有 3 个属性,都是只读的。开关的核心信息通过事件上报,属性主要用于描述设备能力。
| ID | 名称 | 类型 | 必选 | 说明 |
|---|---|---|---|---|
0x0000 |
NumberOfPositions | uint8 | 是 | 开关的位置总数。最小值为 2。普通开关是 2(开/关),多档旋钮可以更多 |
0x0001 |
CurrentPosition | uint8 | 是 | 当前所在位置,范围 0 ~ NumberOfPositions - 1。对于锁定式开关,这个值在拨动后持久保持;对于瞬时开关,按下时变化、松手后可能回到 0 |
0x0002 |
MultiPressMax | uint8 | MSM | 设备支持的最大连续按压次数。例如值为 3 表示最多识别三连击。仅在启用 MSM Feature 时存在 |
位置编号从 0 开始。一个两位拨动开关的位置是 0 和 1,不是 1 和 2。
如果是一个 4 档旋钮,位置就是 0、1、2、3。
事件详解(Events)
事件是 Switch Cluster 的核心。所有用户操作都通过事件上报给控制器。 不同 Feature 组合决定设备会上报哪些事件。点击下方表格中的事件 ID 可跳转到详细说明。
| ID | 名称 | 所需 Feature | 说明 |
|---|---|---|---|
0x00 |
SwitchLatched | LS | 锁定式开关拨到新位置 |
0x01 |
InitialPress | MS | 瞬时按钮被按下 |
0x02 |
LongPress | MS + MSL | 按钮被长按(超过阈值未松手) |
0x03 |
ShortRelease | MS + MSR | 按钮短按后松手 |
0x04 |
LongRelease | MS + MSL | 按钮长按后松手 |
0x05 |
MultiPressOngoing | MS + MSM | 连续按压进行中(每次按下都上报) |
0x06 |
MultiPressComplete | MS + MSM | 连续按压结束(上报总次数) |
SwitchLatched —— 锁定开关拨动(0x00)
当锁定式开关(Latching Switch)被拨到一个新位置时触发。 这是 LS 类型设备唯一会上报的事件 —— 简单直接:拨了就报,报完就没了。
| 字段 | 类型 | 说明 |
|---|---|---|
| NewPosition | uint8 | 开关被拨到的新位置 |
典型场景
传统墙壁拨动开关:用户把开关从「下」拨到「上」,设备上报 SwitchLatched {'{ NewPosition: 1 }'}。
控制器收到后通过绑定关系向灯发送 On 命令。
InitialPress —— 按下(0x01)
瞬时按钮被按下的瞬间触发。这是所有瞬时开关(MS)操作序列的起点 —— 无论后续是短按、长按还是连击,都从 InitialPress 开始。
| 字段 | 类型 | 说明 |
|---|---|---|
| NewPosition | uint8 | 按下后的位置(通常为 1) |
典型场景
用户按下门铃按钮,设备立即上报 InitialPress {'{ NewPosition: 1 }'}。
控制器可以在这个时刻就触发门铃响铃,不用等松手。
LongPress —— 长按(0x02)
按钮被持续按住,超过设备内部的长按阈值后触发。 在 InitialPress 之后、松手之前上报。需要 MSL Feature。
| 字段 | 类型 | 说明 |
|---|---|---|
| NewPosition | uint8 | 按住时的位置(与 InitialPress 的 NewPosition 一致) |
典型场景
调光按钮:短按切换开关,长按开始调亮度。 用户按住不放,收到 LongPress 后控制器开始持续调整灯的亮度(通过 LevelControl Cluster 的 MoveWithOnOff 命令), 直到收到 LongRelease 时停止调整。
ShortRelease —— 短按松手(0x03)
按钮在触发 LongPress 之前被松开时触发(即:这是一次短按)。 需要 MSR Feature。
| 字段 | 类型 | 说明 |
|---|---|---|
| PreviousPosition | uint8 | 按下时的位置(即松手前的位置) |
ShortRelease 和 LongRelease 的字段是 PreviousPosition(松手前的位置), 而 InitialPress 和 LongPress 的字段是 NewPosition(按下后的位置)。 虽然数值通常相同,但语义不同 —— 一个描述「按下去到哪」,一个描述「从哪松开」。
典型场景
智能按钮:收到 ShortRelease 确认这是一次短按,执行对应的短按动作(如 Toggle 开关灯)。 如果启用了 MSM Feature,设备会等待判断是否有后续按压(连击),此时 ShortRelease 可能不会立即触发。
LongRelease —— 长按松手(0x04)
在 LongPress 触发之后松手时触发(即:长按结束)。 需要 MSL Feature。
| 字段 | 类型 | 说明 |
|---|---|---|
| PreviousPosition | uint8 | 长按时的位置(即松手前的位置) |
典型场景
调光按钮长按松手:收到 LongRelease 后,控制器停止亮度调整(发送 StopWithOnOff 命令),灯保持在当前亮度。
MultiPressOngoing —— 连续按压进行中(0x05)
在连续快速按压过程中,每次按下都会触发此事件,携带当前已累计的按压次数。 需要 MSM Feature。
| 字段 | 类型 | 说明 |
|---|---|---|
| NewPosition | uint8 | 按下后的位置 |
| CurrentNumberOfPressesCounted | uint8 | 到目前为止已累计的按压次数(从 2 开始,因为第一次按压是 InitialPress) |
典型场景
用户快速三连击按钮。事件序列:
InitialPress {'{ NewPosition: 1 }'}—— 第一次按下MultiPressOngoing {'{ NewPosition: 1, CurrentNumberOfPressesCounted: 2 }'}—— 第二次按下MultiPressOngoing {'{ NewPosition: 1, CurrentNumberOfPressesCounted: 3 }'}—— 第三次按下MultiPressComplete {'{ PreviousPosition: 1, TotalNumberOfPressesCounted: 3 }'}—— 连击结束
控制器通常等 MultiPressComplete 再执行动作,而不是对每个 Ongoing 都响应。
MultiPressComplete —— 连续按压结束(0x06)
连续按压结束后触发,携带最终的总按压次数。这是控制器判断用户意图的关键事件 —— 根据总次数决定执行什么动作(单击、双击、三击等)。 需要 MSM Feature。
| 字段 | 类型 | 说明 |
|---|---|---|
| PreviousPosition | uint8 | 按压时的位置 |
| TotalNumberOfPressesCounted | uint8 | 总按压次数。值为 1 表示单击,2 表示双击,以此类推。最大值不超过 MultiPressMax |
如果 TotalNumberOfPressesCounted 为 0,表示这次连续按压无效
(例如按压次数超过了 MultiPressMax,或者设备判定为误触)。控制器收到 0 时不应执行任何动作。
典型场景
Aqara 无线按钮:单击开灯、双击切换场景、三击关闭所有灯。 控制器等收到 MultiPressComplete 后,根据 TotalNumberOfPressesCounted 的值分发不同自动化动作。
事件序列对比
不同操作方式下的事件上报顺序:
| 操作 | 事件序列 |
|---|---|
| 拨动(LS) | SwitchLatched |
| 短按(MS+MSR) | InitialPress → ShortRelease |
| 长按(MS+MSR+MSL) | InitialPress → LongPress → LongRelease |
| 双击(MS+MSR+MSM) | InitialPress → MultiPressOngoing(2) → MultiPressComplete(2) |
| 单击(MS+MSR+MSM,等待后确认) | InitialPress → MultiPressComplete(1) |
示例数据
一个支持长按和双击的智能按钮(Feature: MS+MSR+MSL+MSM)的属性读取结果:
{
// --- 开关位置 ---
"0x0000": 2, // NumberOfPositions = 2(两个位置,如常见的上/下拨动开关)
"0x0001": 0, // CurrentPosition = 0(当前处于位置 0)
// --- 多次按压 ---
"0x0002": 3 // MultiPressMax = 3(最多识别 3 连按)
}
事件订阅与接收示例
订阅 Switch Cluster 的事件,以及收到事件时的数据格式:
// 事件订阅示例 —— 订阅 Switch Cluster 的所有事件
{
"subscribeRequest": {
"eventRequests": [{
"endpoint": 1,
"cluster": "0x003B" // Switch Cluster
}],
"minInterval": 0,
"maxInterval": 60
}
}
// 收到的 InitialPress 事件
{
"eventPath": {
"endpoint": 1,
"cluster": "0x003B",
"event": "0x01" // InitialPress
},
"eventData": {
"NewPosition": 1 // 按下后的位置
}
}
// 收到的 MultiPressComplete 事件
{
"eventPath": {
"endpoint": 1,
"cluster": "0x003B",
"event": "0x06" // MultiPressComplete
},
"eventData": {
"PreviousPosition": 1,
"TotalNumberOfPressesCounted": 2 // 总共按了 2 次(双击)
}
}
Switch Cluster 的属性很少,核心价值在事件。开发时重点关注:
- 先读
FeatureMap (0xFFFC)判断设备支持哪些操作模式 - 订阅事件而不是轮询
CurrentPosition - 如果支持 MSM,读取
MultiPressMax知道最多几连击 - 对于支持多种操作的按钮,建议在 UI 中提示用户可配置单击/双击/长按的动作
常见场景
场景 1:墙壁拨动开关(Latching Switch)
设备:传统上下拨动式墙壁开关,Feature = LS(0x01)
- 设备声明
NumberOfPositions = 2(上/下两个位置) - 用户把开关从下拨到上,设备上报
SwitchLatched {'{ NewPosition: 1 }'} - 控制器通过绑定关系找到对应的灯,发送
On命令 - 用户把开关从上拨到下,设备上报
SwitchLatched {'{ NewPosition: 0 }'} - 控制器发送
Off命令,灯关闭
这种开关最简单 —— 一个事件、一个动作,没有长按和连击的概念。开关位置和灯的状态是物理对应的。
场景 2:调光旋钮 / 调光按钮(Dimmer)
设备:带按压功能的旋钮或调光按钮,Feature = MS + MSR + MSL(0x0E)
- 用户短按:收到 InitialPress → ShortRelease,控制器执行 Toggle(切换开关)
- 用户长按:
- 收到 InitialPress —— 暂不动作,等后续事件
- 收到 LongPress —— 开始连续调亮度(发送 MoveWithOnOff 命令)
- 收到 LongRelease —— 停止调亮度(发送 StopWithOnOff 命令)
关键设计:不要在 InitialPress 时就执行 Toggle,否则长按也会先触发一次开关切换。 正确做法是等 ShortRelease 或 LongPress 再决定动作。
场景 3:多功能无线按钮(Multi Press)
设备:Aqara / Eve 等无线智能按钮,Feature = MS + MSR + MSL + MSM(0x1E),MultiPressMax = 3
- 单击(等待超时后确认):InitialPress → MultiPressComplete(1) → 执行动作 A(如开灯)
- 双击:InitialPress → MultiPressOngoing(2) → MultiPressComplete(2) → 执行动作 B(如切换场景)
- 三击:InitialPress → MultiPressOngoing(2) → MultiPressOngoing(3) → MultiPressComplete(3) → 执行动作 C(如全屋关灯)
- 长按:InitialPress → LongPress → LongRelease → 执行动作 D(如进入配对模式)
在 App 中,可以让用户自定义每种操作对应的自动化动作,类似 Apple HomeKit 的按钮配置界面。
注意:单击的确认有延迟 —— 设备要等一小段时间确认没有后续按压才上报 MultiPressComplete(1)。 这是为了区分单击和双击的第一下,用户能感知到轻微的响应延迟。