esp-matter:light project

编译

拷贝 ~/esp/esp-matter/examples 到指定目录

1
2
3
mkdir ~/esp/example-matter
cp -r ~/esp/esp-matter/examples/* ~/esp/example-matter
cd ~/esp/example-matter/light

设置目标

开发板Soc是esp32-c3,故设置目标选择:esp32c3

1
2
3
4
5
6
# 激活esp-idf和esp-matter环境
get_idf
get_matter

# 设置目标
idf.py set-target esp32c3

编译固件

直接开始编译固件

1
idf.py build

烧录固件

将开发板插入PC的USB接口,修改串口权限,开始烧录

1
2
3
4
5
6
7
8
9
10
11
# 查找串口权限
ls -l /dev/ttyUSB0

# 修改串口权限
sudo chmod 664 /dev/ttyUSB0

# 烧录固件
idf.py -p /dev/ttyUSB0 flash

# 若想完全重新编译,需要先删除build目录下所有文件
idf.py fullclean

注意:不同开发板的接入PC后,串口名称可能不同,目前已知的两种名称:/dev/ttyUSB0/dev/ttyACM0

乐鑫esp32c3开发板串口名称:/dev/ttyUSB0

合宙esp32c3开发板串口名称:/dev/ttyACM0

配网

通过BLE方式给设备配网:指通过低功耗蓝牙(即BLE)将SSID和密码发送给WiFi设备,然后WiFi连接到指定的WiFi网络。

什么是配网?

配网指的是外部向 WiFi 设备提供 SSID和密码,以便 WiFi 设备可以连接指定的AP并加入AP所建立的 WiFi 网络。配网的核心问题是通过各种方法(SoftAP配网、一键配网、蓝牙配网、其他方式配网),将WiFi的 SSID和密码发送到需要联网的WiFi设备,然后由WiFi设备去连接指定的WiFi网络,达到接入局域网或互联网的目的。

chip-tool命令配网

启动Terminal A用于monitor串口数据,启动Terminal B用于执行chip-tool命令。其中chip-tool工具有两种使用方式:单次执行 和 交互执行。交互执行控制设备时,响应速度非常快,并且不容易产生超时报错。单次执行某条指令需要再一定时间周期内完成,否则chip-tool将会报错:Timeout。

单次执行:

单次执行配网命令:

1
2
3
4
5
# 模版
chip-tool pairing ble-wifi <node_id> <ssid> <password> <pin_code> <discriminator>

# 示例
chip-tool pairing ble-wifi 0x7283 CUBEC_AP_2.4G cubec2015 20202021 3840

命令解释:

  • 0x7283 是自定义一个随机的 node_id

  • CUBEC_AP_2.4Gcubec2015:分别是wifi的 ssidpassword

  • 20202021pin_code

  • 3840discriminator

单次执行容易导致超时,建议使用交互执行!!!

交互执行(建议):

Terminal A处于等待配网状态,状态如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
I (1725) esp_matter_core: Dynamic endpoint 1 added
I (1735) chip[DL]: WIFI_EVENT_STA_START
W (1735) wifi:Haven't to connect to a suitable AP now!
I (1745) chip[DL]: Done driving station state, nothing else to do...
I (1745) chip[DL]: Configuring CHIPoBLE advertising (interval 25 ms, connectable)
I (1755) NimBLE: GAP procedure initiated: advertise;
I (1765) NimBLE: disc_mode=2
I (1765) NimBLE: adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=40 adv_itvl_max=40
I (1775) NimBLE:

I (1775) chip[DL]: CHIPoBLE advertising started
I (1785) app_main: Commissioning window opened
I (1855) main_task: Returned from app_main()
> I (4725) esp_matter_core: Store the deferred attribute 0x0 of cluster 0x8 on endpoint 0x1

注意:若想将设备清除所有的配网信息,可以将设备恢复出厂状态,在 Terminal A 执行命令:matter device factoryreset

Terminal B中执行命令:chip-tool interactive start

此时进入交互模式,状态如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  +-------------------------------------------------------------------------------------+
| Command sets: |
+-------------------------------------------------------------------------------------+
| * any |
| - Commands for sending IM messages based on cluster id, not cluster name. |
| * delay |
| - Commands for waiting for something to happen. |
| * discover |
| - Commands for device discovery. |
| * groupsettings |
| - Commands for manipulating group keys and memberships for chip-tool itself. |
| * icd |
| - Commands for client-side ICD management. |
| * pairing |
| - Commands for commissioning devices. |
| * payload |
| - Commands for parsing and generating setup payloads. |
| * sessionmanagement |
| - Commands for managing CASE and PASE session state. |
| * subscriptions |
| - Commands for shutting down subscriptions. |
| * interactive |
| - Commands for starting long-lived interactive modes. |
| * storage |
| - Commands for managing persistent data stored by chip-tool. |
+-------------------------------------------------------------------------------------+
>>>

在交互模式内执行命令为设备配网:

1
pairing ble-wifi 0x7283 CUBEC_AP_2.4G cubec2015 20202021 3840

若设备配网成功,在Terminal A会出现设备设备已获取IP地址,如下所示:

1
2
3
4
5
6
7
I (323035) wifi:<ba-add>idx:1 (ifx:0, fc:83:c6:00:8f:ae), tid:6, ssn:1, winSize:64
I (323075) chip[DL]: Confirm received for CHIPoBLE TX characteristic indication (con 1) status= 14
I (323845) esp_netif_handlers: sta ip: 192.168.5.201, mask: 255.255.255.0, gw: 192.168.5.1
I (323845) chip[DL]: IP_EVENT_STA_GOT_IP
I (323855) chip[DL]: IPv4 address changed on WiFi station interface: 192.168.5.201/255.255.255.0 gateway 192.168.5.1
I (323865) chip[DL]: IPv4 Internet connectivity ESTABLISHED

扫码配网

控制

chip-tool是什么?

chip-tool是用于开发和调试Matter设备的命令行工具。

设备配网成功后,接着可以在Terminal B通过chip-tool交互模式内控制设备,例如:打开LED、关闭LED、反转LED、调节亮度、调节颜色

单次执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 打开LED
chip-tool onoff on 0x7283 0x1

# 关闭LED
chip-tool onoff off 0x7283 0x1

# 反转LED
chip-tool onoff toggle 0x7283 0x1

# 调节亮度
## 设置亮度为10%(实际低于30%后,LED就熄灭了)
chip-tool levelcontrol move-to-level 10 0 0 0 0x7283 0x1
## 设置亮度为100%
chip-tool levelcontrol move-to-level 100 0 0 0 0x7283 0x1

# 调节颜色
## 设置暖色调色温
chip-tool colorcontrol move-to-color-temperature 500 0 0 0 0x7283 0x1
## 设置冷色调色温
chip-tool colorcontrol move-to-color-temperature 154 0 0 0 0x7283 0x1

交互执行(建议):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 打开LED
onoff on 0x7283 0x1

# 关闭LED
onoff off 0x7283 0x1

# 反转LED
onoff toggle 0x7283 0x1

# 调节亮度
## 设置亮度为10%(实际低于30%后,LED就熄灭了)
levelcontrol move-to-level 10 0 0 0 0x7283 0x1
## 设置亮度为100%
levelcontrol move-to-level 100 0 0 0 0x7283 0x1

# 调节颜色
## 设置暖色调色温
colorcontrol move-to-color-temperature 500 0 0 0 0x7283 0x1
## 设置冷色调色温
colorcontrol move-to-color-temperature 154 0 0 0 0x7283 0x1

命令解释:

1、onoff:表示OnOff Cluster

2、on、off、toggle:分别表示On、Off、Toggle命令

3、0x7283:表示Node ID,这是之前在配网时定义的值

4、0x01:表示Endpoint 1,这是Light Project项目代码中新建的一个Endpoint。

5、levelcontrol、colorcontorl:分别表示 LevelControl Cluster 和 ColorControl Cluster

6、move-to-level 、move-to-color-temperature:分别表示对应Cluster下的命令

chip-tool命令扩展:

从Matter设备读取(read)信息,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
>>> onoff read on-off 0x7283 0x01
[1726799530.981378][352215:352215] CHIP:TOO: Command: onoff read on-off 0x7283 0x01
[1726799530.981581][352215:352217] CHIP:TOO: Sending command to node 0x7283
[1726799530.981826][352215:352217] CHIP:CSM: FindOrEstablishSession: PeerId = [1:0000000000007283]
[1726799530.981836][352215:352217] CHIP:CSM: FindOrEstablishSession: No existing OperationalSessionSetup instance found
[1726799530.981852][352215:352217] CHIP:DIS: Found an existing secure session to [1:0000000000007283]!
[1726799530.981860][352215:352217] CHIP:DIS: OperationalSessionSetup[1:0000000000007283]: State change 1 --> 5
[1726799530.981875][352215:352217] CHIP:TOO: Sending ReadAttribute to:
[1726799530.982385][352215:352217] CHIP:TOO: cluster 0x0000_0006, attribute: 0x0000_0000, endpoint 1
[1726799530.982404][352215:352217] CHIP:DMG: SendReadRequest ReadClient[0x72cc4000a6c0]: Sending Read Request
[1726799530.982496][352215:352217] CHIP:EM: <<< [E:18684i S:41998 M:177312788] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0001:02 (IM:ReadRequest)
[1726799530.982607][352215:352217] CHIP:DMG: MoveToState ReadClient[0x72cc4000a6c0]: Moving to [AwaitingIn]
[1726799531.173092][352215:352217] CHIP:EM: >>> [E:18684i S:41998 M:189153990 (Ack:177312788)] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0001:05 (IM:ReportData)
[1726799531.173129][352215:352217] CHIP:EM: Found matching exchange: 18684i, Delegate: 0x72cc4000a6d0
[1726799531.173146][352215:352217] CHIP:EM: Rxd Ack; Removing MessageCounter:177312788 from Retrans Table on exchange 18684i
[1726799531.173182][352215:352217] CHIP:DMG: ReportDataMessage =
[1726799531.173193][352215:352217] CHIP:DMG: {
[1726799531.173206][352215:352217] CHIP:DMG: AttributeReportIBs =
[1726799531.173221][352215:352217] CHIP:DMG: [
[1726799531.173232][352215:352217] CHIP:DMG: AttributeReportIB =
[1726799531.173250][352215:352217] CHIP:DMG: {
[1726799531.173261][352215:352217] CHIP:DMG: AttributeDataIB =
[1726799531.173278][352215:352217] CHIP:DMG: {
[1726799531.173291][352215:352217] CHIP:DMG: DataVersion = 0xe0b02f82,
[1726799531.173307][352215:352217] CHIP:DMG: AttributePathIB =
[1726799531.173321][352215:352217] CHIP:DMG: {
[1726799531.173334][352215:352217] CHIP:DMG: Endpoint = 0x1,
[1726799531.173348][352215:352217] CHIP:DMG: Cluster = 0x6,
[1726799531.173363][352215:352217] CHIP:DMG: Attribute = 0x0000_0000,
[1726799531.173376][352215:352217] CHIP:DMG: }
[1726799531.173395][352215:352217] CHIP:DMG:
[1726799531.173409][352215:352217] CHIP:DMG: Data = false,
[1726799531.173422][352215:352217] CHIP:DMG: },
[1726799531.173436][352215:352217] CHIP:DMG:
[1726799531.173446][352215:352217] CHIP:DMG: },
[1726799531.173461][352215:352217] CHIP:DMG:
[1726799531.173470][352215:352217] CHIP:DMG: ],
[1726799531.173484][352215:352217] CHIP:DMG:
[1726799531.173495][352215:352217] CHIP:DMG: SuppressResponse = true,
[1726799531.173506][352215:352217] CHIP:DMG: InteractionModelRevision = 11
[1726799531.173515][352215:352217] CHIP:DMG: }
[1726799531.175422][352215:352217] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0006 Attribute 0x0000_0000 DataVersion: 3769642882
[1726799531.175440][352215:352217] CHIP:TOO: OnOff: FALSE
[1726799531.175518][352215:352217] CHIP:EM: <<< [E:18684i S:41998 M:177312789 (Ack:189153990)] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck)
[1726799531.175575][352215:352217] CHIP:EM: Flushed pending ack for MessageCounter:189153990 on exchange 18684i

从Matter设备订阅(subscribe)信息,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
>>> onoff subscribe on-off 5 30  0x7283 0x1
[1726799808.099530][352215:352215] CHIP:TOO: Command: onoff subscribe on-off 5 30 0x7283 0x1
[1726799808.099753][352215:352217] CHIP:TOO: Sending command to node 0x7283
[1726799808.100002][352215:352217] CHIP:CSM: FindOrEstablishSession: PeerId = [1:0000000000007283]
[1726799808.100011][352215:352217] CHIP:CSM: FindOrEstablishSession: No existing OperationalSessionSetup instance found
[1726799808.100026][352215:352217] CHIP:DIS: Found an existing secure session to [1:0000000000007283]!
[1726799808.100035][352215:352217] CHIP:DIS: OperationalSessionSetup[1:0000000000007283]: State change 1 --> 5
[1726799808.100051][352215:352217] CHIP:TOO: Sending SubscribeAttribute to:
[1726799808.100063][352215:352217] CHIP:TOO: cluster 0x0000_0006, attribute: 0x0000_0000, endpoint 1
[1726799808.100169][352215:352217] CHIP:EM: <<< [E:18685i S:41998 M:177312790] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0001:03 (IM:SubscribeRequest)
[1726799808.100270][352215:352217] CHIP:DMG: MoveToState ReadClient[0x72cc4000a6c0]: Moving to [AwaitingIn]
[1726799808.273067][352215:352217] CHIP:EM: >>> [E:18685i S:41998 M:189153991 (Ack:177312790)] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0001:05 (IM:ReportData)
[1726799808.273108][352215:352217] CHIP:EM: Found matching exchange: 18685i, Delegate: 0x72cc4000a6d0
[1726799808.273135][352215:352217] CHIP:EM: Rxd Ack; Removing MessageCounter:177312790 from Retrans Table on exchange 18685i
[1726799808.273179][352215:352217] CHIP:DMG: ReportDataMessage =
[1726799808.273192][352215:352217] CHIP:DMG: {
[1726799808.273204][352215:352217] CHIP:DMG: SubscriptionId = 0xef8890e9,
[1726799808.273218][352215:352217] CHIP:DMG: AttributeReportIBs =
[1726799808.273237][352215:352217] CHIP:DMG: [
[1726799808.273248][352215:352217] CHIP:DMG: AttributeReportIB =
[1726799808.273267][352215:352217] CHIP:DMG: {
[1726799808.273279][352215:352217] CHIP:DMG: AttributeDataIB =
[1726799808.273295][352215:352217] CHIP:DMG: {
[1726799808.273313][352215:352217] CHIP:DMG: DataVersion = 0xe0b02f82,
[1726799808.273332][352215:352217] CHIP:DMG: AttributePathIB =
[1726799808.273351][352215:352217] CHIP:DMG: {
[1726799808.273369][352215:352217] CHIP:DMG: Endpoint = 0x1,
[1726799808.273389][352215:352217] CHIP:DMG: Cluster = 0x6,
[1726799808.273409][352215:352217] CHIP:DMG: Attribute = 0x0000_0000,
[1726799808.273424][352215:352217] CHIP:DMG: }
[1726799808.273440][352215:352217] CHIP:DMG:
[1726799808.273469][352215:352217] CHIP:DMG: Data = false,
[1726799808.273481][352215:352217] CHIP:DMG: },
[1726799808.273497][352215:352217] CHIP:DMG:
[1726799808.273508][352215:352217] CHIP:DMG: },
[1726799808.273523][352215:352217] CHIP:DMG:
[1726799808.273533][352215:352217] CHIP:DMG: ],
[1726799808.273549][352215:352217] CHIP:DMG:
[1726799808.273559][352215:352217] CHIP:DMG: InteractionModelRevision = 11
[1726799808.273569][352215:352217] CHIP:DMG: }
[1726799808.273644][352215:352217] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0006 Attribute 0x0000_0000 DataVersion: 3769642882
[1726799808.273682][352215:352217] CHIP:TOO: OnOff: FALSE
[1726799808.273711][352215:352217] CHIP:DMG: MoveToState ReadClient[0x72cc4000a6c0]: Moving to [AwaitingSu]
[1726799808.273944][352215:352217] CHIP:EM: <<< [E:18685i S:41998 M:177312791 (Ack:189153991)] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0001:01 (IM:StatusResponse)
[1726799808.624854][352215:352217] CHIP:EM: Retransmitting MessageCounter:177312791 on exchange 18685i Send Cnt 1
[1726799808.654348][352215:352217] CHIP:EM: >>> [E:18685i S:41998 M:189153992 (Ack:177312791)] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0001:04 (IM:SubscribeResponse)
[1726799808.654383][352215:352217] CHIP:EM: Found matching exchange: 18685i, Delegate: 0x72cc4000a6d0
[1726799808.654408][352215:352217] CHIP:EM: Rxd Ack; Removing MessageCounter:177312791 from Retrans Table on exchange 18685i
[1726799808.654433][352215:352217] CHIP:DMG: SubscribeResponse is received
[1726799808.654462][352215:352217] CHIP:DMG: SubscribeResponseMessage =
[1726799808.654475][352215:352217] CHIP:DMG: {
[1726799808.654487][352215:352217] CHIP:DMG: SubscriptionId = 0xef8890e9,
[1726799808.654501][352215:352217] CHIP:DMG: MaxInterval = 0x1e,
[1726799808.654514][352215:352217] CHIP:DMG: InteractionModelRevision = 11
[1726799808.654526][352215:352217] CHIP:DMG: }
[1726799808.654544][352215:352217] CHIP:DMG: Subscription established with SubscriptionID = 0xef8890e9 MinInterval = 5s MaxInterval = 30s Peer = 01:0000000000007283
[1726799808.654562][352215:352217] CHIP:DMG: MoveToState ReadClient[0x72cc4000a6c0]: Moving to [Subscripti]
[1726799808.654597][352215:352217] CHIP:DMG: Refresh LivenessCheckTime for 34224 milliseconds with SubscriptionId = 0xef8890e9 Peer = 01:0000000000007283
[1726799808.654708][352215:352217] CHIP:EM: <<< [E:18685i S:41998 M:177312792 (Ack:189153992)] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck)
[1726799808.654836][352215:352217] CHIP:EM: Flushed pending ack for MessageCounter:189153992 on exchange 18685i
[1726799809.093742][352215:352217] CHIP:EM: >>> [E:18685i S:41998 M:189153993 (Ack:177312791)] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0000:10 (SecureChannel:StandaloneAck)
[1726799809.093839][352215:352217] CHIP:IN: Received a duplicate message with MessageCounter:189153992 on exchange 18685i
[1726799809.093855][352215:352217] CHIP:EM: >>> [E:18685i S:41998 M:189153992 (Ack:177312791)] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0001:04 (IM:SubscribeResponse)
[1726799809.093875][352215:352217] CHIP:EM: Generating StandaloneAck via exchange: 18685i
[1726799809.093885][352215:352217] CHIP:EM: Forcing tx of solitary ack for duplicate MessageCounter:189153992 on exchange 18685i
[1726799809.093964][352215:352217] CHIP:EM: <<< [E:18685i S:41998 M:177312793 (Ack:189153992)] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck)
[1726799814.284411][352215:352217] CHIP:EM: >>> [E:64465r S:41998 M:189153994] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0001:05 (IM:ReportData)
[1726799814.284442][352215:352217] CHIP:EM: Handling via exchange: 64465r, Delegate: 0x59c53aff2ea8
[1726799814.284474][352215:352217] CHIP:DMG: ReportDataMessage =
[1726799814.284491][352215:352217] CHIP:DMG: {
[1726799814.284498][352215:352217] CHIP:DMG: SubscriptionId = 0xef8890e9,
[1726799814.284502][352215:352217] CHIP:DMG: AttributeReportIBs =
[1726799814.284509][352215:352217] CHIP:DMG: [
[1726799814.284513][352215:352217] CHIP:DMG: AttributeReportIB =
[1726799814.284519][352215:352217] CHIP:DMG: {
[1726799814.284523][352215:352217] CHIP:DMG: AttributeDataIB =
[1726799814.284528][352215:352217] CHIP:DMG: {
[1726799814.284533][352215:352217] CHIP:DMG: DataVersion = 0xe0b02f83,
[1726799814.284538][352215:352217] CHIP:DMG: AttributePathIB =
[1726799814.284544][352215:352217] CHIP:DMG: {
[1726799814.284549][352215:352217] CHIP:DMG: Endpoint = 0x1,
[1726799814.284555][352215:352217] CHIP:DMG: Cluster = 0x6,
[1726799814.284561][352215:352217] CHIP:DMG: Attribute = 0x0000_0000,
[1726799814.284567][352215:352217] CHIP:DMG: }
[1726799814.284573][352215:352217] CHIP:DMG:
[1726799814.284583][352215:352217] CHIP:DMG: Data = true,
[1726799814.284589][352215:352217] CHIP:DMG: },
[1726799814.284595][352215:352217] CHIP:DMG:
[1726799814.284598][352215:352217] CHIP:DMG: },
[1726799814.284603][352215:352217] CHIP:DMG:
[1726799814.284607][352215:352217] CHIP:DMG: ],
[1726799814.284612][352215:352217] CHIP:DMG:
[1726799814.284616][352215:352217] CHIP:DMG: InteractionModelRevision = 11
[1726799814.284620][352215:352217] CHIP:DMG: }
[1726799814.284686][352215:352217] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0006 Attribute 0x0000_0000 DataVersion: 3769642883
[1726799814.284712][352215:352217] CHIP:TOO: OnOff: TRUE
[1726799814.284738][352215:352217] CHIP:DMG: Refresh LivenessCheckTime for 34224 milliseconds with SubscriptionId = 0xef8890e9 Peer = 01:0000000000007283
[1726799814.284998][352215:352217] CHIP:EM: <<< [E:64465r S:41998 M:177312794 (Ack:189153994)] (S) Msg TX to 1:0000000000007283 [428F] [UDP:[fe80::f29e:9eff:fe99:1260%wlp1s0]:5540] --- Type 0001:01 (IM:StatusResponse)
[1726799814.371141][352215:352217] CHIP:EM: >>> [E:64465r S:41998 M:189153995 (Ack:177312794)] (S) Msg RX from 1:0000000000007283 [428F] --- Type 0000:10 (SecureChannel:StandaloneAck)
[1726799814.371163][352215:352217] CHIP:EM: Found matching exchange: 64465r, Delegate: (nil)
[1726799814.371177][352215:352217] CHIP:EM: Rxd Ack; Removing MessageCounter:177312794 from Retrans Table on exchange 64465r

解读

light project示例演示了Extended Color Light设备的开发。以下就是对代码的理解:

  • 创建一个Matter节点

    1
    2
    3
    4
    // 创建一个Matter节点和增加endpoint 0
    node::config_t node_config;

    node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb);
  • 创建Endpoint

    在本实例中创建 extended_color_light 设备类型的Endpoint。所有的Endpoint定义都在这个文件中:esp/esp-matter/components/esp_matter/esp_matter_endpoint.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 在Matter节点下增加Endpoint,默认从1开始
    extended_color_light::config_t light_config;
    light_config.on_off.on_off = DEFAULT_POWER;
    light_config.on_off.lighting.start_up_on_off = nullptr;
    light_config.level_control.current_level = DEFAULT_BRIGHTNESS;
    light_config.level_control.on_level = DEFAULT_BRIGHTNESS;
    light_config.level_control.lighting.start_up_current_level = DEFAULT_BRIGHTNESS;
    light_config.color_control.color_mode = (uint8_t)ColorControl::ColorMode::kColorTemperature;
    light_config.color_control.enhanced_color_mode = (uint8_t)ColorControl::ColorMode::kColorTemperature;
    light_config.color_control.color_temperature.startup_color_temperature_mireds = nullptr;

    endpoint_t *endpoint = extended_color_light::create(node, &light_config, ENDPOINT_FLAG_NONE, light_handle);
  • 快速变化的属性标记延迟持久性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 通过Endpoint 1获取其Level Control集群,然后通过对应的集群获取Attribute值,最后标记属性的延迟持久性
    cluster_t *level_control_cluster = cluster::get(endpoint, LevelControl::Id);
    attribute_t *current_level_attribute = attribute::get(level_control_cluster, LevelControl::Attributes::CurrentLevel::Id);
    attribute::set_deferred_persistence(current_level_attribute);

    cluster_t *color_control_cluster = cluster::get(endpoint, ColorControl::Id);
    attribute_t *current_x_attribute = attribute::get(color_control_cluster, ColorControl::Attributes::CurrentX::Id);
    attribute::set_deferred_persistence(current_x_attribute);

    attribute_t *current_y_attribute = attribute::get(color_control_cluster, ColorControl::Attributes::CurrentY::Id);
    attribute::set_deferred_persistence(current_y_attribute);

    attribute_t *color_temp_attribute = attribute::get(color_control_cluster,ColorControl::Attributes::ColorTemperatureMireds::Id);
    attribute::set_deferred_persistence(color_temp_attribute);
  • 属性回调

    每当用户通过Matter客户端对Matter设备(作为Matter Server)进行控制时,其控制值最终都会更新设备数据模型中的属性值。

    当属性更新时,回调函数 app_attribute_update_cb() 用户通知应用程序(Matter设备)属性有更改。若回调函数类型为 PRE_UPDATE ,则更新Matter设备驱动程序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    static esp_err_t app_attribute_update_cb(attribute::callback_type_t type,
    uint16_t endpoint_id,
    uint32_t cluster_id,
    uint32_t attribute_id,
    esp_matter_attr_val_t *val,
    void *priv_data)
    {
    esp_err_t err = ESP_OK;

    if (type == PRE_UPDATE) {
    /* Driver update */
    app_driver_handle_t driver_handle = (app_driver_handle_t)priv_data;
    err = app_driver_attribute_update(driver_handle, endpoint_id, cluster_id, attribute_id, val);
    }

    return err;
    }
  • 设备驱动

    首先判断改变的是否为目标设备:light_endpoint_id,然后根据集群下的属性更新状态。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    // Attribute(属性) Update
    esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle,
    uint16_t endpoint_id,
    uint32_t cluster_id,
    uint32_t attribute_id,
    esp_matter_attr_val_t *val)
    {
    esp_err_t err = ESP_OK;
    // Endpoint匹配
    if (endpoint_id == light_endpoint_id)
    {
    led_indicator_handle_t handle = (led_indicator_handle_t)driver_handle;
    // Cluster匹配
    if (cluster_id == OnOff::Id)
    {
    // Attribute匹配
    if (attribute_id == OnOff::Attributes::OnOff::Id)
    {
    err = app_driver_light_set_power(handle, val);
    }
    }
    else if (cluster_id == LevelControl::Id)
    {
    if (attribute_id == LevelControl::Attributes::CurrentLevel::Id)
    {
    err = app_driver_light_set_brightness(handle, val);
    }
    }
    else if (cluster_id == ColorControl::Id)
    {
    if (attribute_id == ColorControl::Attributes::CurrentHue::Id)
    {
    err = app_driver_light_set_hue(handle, val);
    }
    else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id)
    {
    err = app_driver_light_set_saturation(handle, val);
    }
    else if (attribute_id == ColorControl::Attributes::ColorTemperatureMireds::Id)
    {
    err = app_driver_light_set_temperature(handle, val);
    }
    }
    }
    return err;
    }

参考

1、Developing with the SDK of ESP-MATTER