DIY Matter Bridge 和智慧鎖簡單聯動的實踐

我说不上岸不改名發表於2024-10-14

一. 寫在前面

在之前的部落格文章 《基於樂鑫 ESP32-C3 的 Matter Light 實踐》中,我們利用樂鑫的硬體和 SDK 方案實現了簡單的 Light 例程,並對 Matter 協議進行了簡要介紹。在開始本篇文章之前,我還是打算重新聊一聊 Matter,順便談談自己對它的理解,這也能說明為何這段時間我一直執著於這個事情。

1.1 Matter 的誕生背景

其實說到智慧家居這個領域,我們應該能聯想到很多目前做的不錯的品牌,比如國內的華為、綠米 Aqara、歐博瑞,海外的 APPLE、Google Nest 等等。同時,它們又有著自己的一套生態協議,就像 Apple 有 Homekit、Amazon 有 alexa、華為有 Hilink 一樣。

這些生態本身的發展,從今天來看都是比較成熟的。但是對於消費者和製造商來說,可能會面臨一些頭疼的情況:

(1)對於消費者:家裡裝了多個生態的產品,比如小米的燈和感測器、華為的門鎖以及蘋果的音響,這意味著你想要管理它們就不得不使用各自的應用程式,同時在這種場景下構建家庭自動化也會困難重重。當然,可能有人會說引入一個 Home Assistant 閘道器來嘗試解決這些問題,這對部分 Geeker 來說是沒有問題的,但是面對與普通消費者,這無疑提高了很高的使用門檻。

(2)對於裝置廠商:針對割裂的生態,在產品設計時就要考慮未來所需對接的環境。比如,出海的智慧產品往往需要做 Amazon 的 work with alexa (WWA)認證以及谷歌的 Work with Google Assistant (WWGA) 認證。如果是中高階產品,可能還需要考慮 Apple HomeKit 和其他第三方生態的認證。這無疑增加了產品開發的難度和週期,以及帶來成本增加。

那麼有什麼辦法能夠讓一臺裝置無縫工作在若干種不同生態下,並且能為使用者提供統一的使用介面呢?於是,Matter 出現了。

1.2 它解決了什麼問題

Matter 本質是由 CSA 聯盟(連線標準聯盟)制定的一個應用層面的標準,旨在打造一個統一的智慧家居應用標準,以消除智慧家居市場的碎片化。

而 CSA 聯盟的前身,是2019 年,由亞馬遜、蘋果、谷歌、三星 SmartThings 和 Zigbee 聯盟合作組建的 Project Connected Home over IP (CHIP)組織。當時組織推出了一個 CHIP 的開源專案,並經過一些時間的準備和發展之後,在 21 年正式命名為 Matter,並由 CSA 聯盟運營和發展。再往前推,還會發現 CSA 聯盟的前身就是 Zigbee 聯盟。

用相對官方的話來表述,Matter 只是一個應用標準,它的傳輸是建立在支援 IPv6 的 TCP 和 UDP 協議上的,Matter 不對傳輸層進行約定,Matter 也不對網路進行約定,但是 Matter 約定了只能使用Thread、Wi-Fi 或Ethernet 三種連線協議。

通俗點給人的理解是,Matter 定義了一系列的裝置模型和互動模型,舉個例子來說,智慧燈是標準裝置型別之一,它定義了很多操作,例如:on/off cluster 可以完成開關燈動作,Level control cluster 可以完成調節亮度的動作。 Color control cluster 可以完成顏色調節的動作。對於裝置來說,只要遵循了這些標準模型,那麼在支援 Matter 協議的生態當中就可以被理解和使用,這就打破了傳統私有協議帶來的壁壘。

而現在,包括 Apple、三星、谷歌、亞馬遜、小米等越來越多的品牌和廠商加入到該聯盟當中。假以時日,對於消費者來說,只需選擇自己喜歡的帶有 Matter 標識的產品,就將能輕鬆構建互聯的智慧家居生態,構建自己的家庭自動化,而不用擔心具體裝置的品牌問題。

1.3 最近的動態

(1) 在今年的早些時候, 聯盟釋出了 Matter 1.3 版本,對以下方面做了一定的改進:

  • 對水和能源管理裝置的新支援,包括能源管理、電動汽車充電和水資源管理。
  • 增加了新的家電型別,如微波爐、烤箱、灶具、抽油煙機和洗衣機、乾衣機。
  • 增強媒體裝置和智慧家居的管理功能。
  • 增強使用者體驗。
  • 改進開發和除錯體驗。

具體的規範內容可以參考以下網址:Matter 1.3 規範釋出

(2)蘋果在 ios 18 開發者版本降低了對家庭中樞的限制。在上年嘗試 ESP 方案時,想把裝置新增到 iPhone Home 會提示需要先新增一箇中樞裝置,而現在使用最新的 IOS 18 系統則可以直接新增 Matter 裝置。

二、實踐背景

我們之前定義和開發的 Smart Deadbolt 產品現在已經接近尾聲了。在過去,我們希望它能夠支援 Alexa 和 WWGA 以實現對海外生態的相容,而如今我們看到了 Matter,這或許是一個新的解決方案。

尤其是對於裝置製造商來說,過去我們需要面向不同生態進行的 N 項認證,這增加了因為不同技術棧對開發人員的要求。在過去,可能需要工程師團隊瞭解 Alexa Skill 開發,又要對蘋果的 HomeKit 有一定的瞭解,這是有一些挑戰的。同時,多項認證的費用也不容小覷。而隨著 Matter 的出現,如今可以大大簡化這些認證流程並壓縮成本,同時還能為消費者提供更加友好的體驗,何樂而不為。

2.1 關於 Bridge

自 1.0 版本以來,Matter Bridge 一直作為標準中的一個產品類別。它的任務是翻譯 "外部" 的協議和技術,以便Matter 能夠理解它們。這是智慧家居標準成功的重要先決條件,因為並非每個已購買裝置的人都想丟棄它們並用新的與 Matter 相容的裝置替換它們。

(1)官方對 bridge 的描述

非 Matter 裝置作為橋接裝置暴露給 Fabric 上的節點。Matter 節點既可以與(本地)Matter 裝置通訊,也可以與橋接裝置通訊(透過Matter bridge在 Matter 和其他協議之間進行轉換)。

比如,利用 CHIP 的 ZAP 工具,構建一個 Matter 的 Bridge 裝置:

(2)本次採用的方案:

我們知道,在去年 Yale Assure Lock 方案中,他們支援到了一顆可拔插的 Matter 模組以適配外部生態。從分析來看,這個模組也是起到了一個 Bridge 的功能,並透過串列埠和 Lock 裝置進行通訊以響應外部指令。

這次實踐參考了這種形式,但是由於 Lock 已經是成品裝置,所以不在鎖體上實現串列埠接入。而是透過藍芽的形式同 Lock 的私有協議進行通訊,原理如下所示:

簡單理解,實際上就是把 Bridge 對映成了一個虛擬的 Matter 裝置,並透過私有協議和藍芽將 Matter 指令轉換成裝置指令。

至於這裡為什麼會使用到兩塊 CCK (Nordic 開發板)以及具體的流程,在第三部分會進行解釋。

2.2 開發平臺

(1)軟體環境:VSCODE + nRF Connect SDK,其中:

  • toolChains 版本為 v2.6.1。

  • nRF Connect SDK 版本為 v2.6.1。

  • 關於這套 SDK 的安裝方法,可以參考官方的一篇文件:開發 nRF Connect SDK(NCS)/Zephyr應用程式

(2)開發板:

  • 兩塊 Nordic CCK 開發板,CCK 板載有 nRF5340 和nRF7002 兩顆晶片。其中,nRF7002/nRF7001 是 Wi-Fi 6 協同 IC,他們只執行 Wi-Fi 有關的 MAC 層,Matter 的其他部分還是跑在 nRF5340 上。

(3)生態應用及配件:

  • Alexa Echo 4 日版。

  • Samsung 海外版手機。

  • Alexa App。

三、過程記錄

3.1 配置開發環境

(1)首先本地已經安裝了 Microsoft Visual Studio Code,然後開啟它進入 “擴充套件” 搜尋 “nRF Connect for VS Code Extension Pack” 進行安裝。該項擴充安裝時,其它所需的 nRF 外掛也會被自動安裝。

(2)然後點選外掛圖示,進入後看到 Manage SDKs,選擇安裝 nRF Connect SDK。目前最新的版本是 2.6.1,預設選擇最新的版本。這裡值得注意的是, SDK 被官方放到了 Github 的伺服器上,所以需要一些科學的方法,否則容易發生下載失敗的情況。

(3)接下來安裝 Toolchain,也可以直接透過 Vscode 進行安裝。根據剛才選擇的 nRF Connect SDK 版本選擇對應版本的 Toolchain,這裡安裝的也是 2.6.1 版本。

(4)繼續安裝必須的 Python 指令碼,nRF Connect SDK 雖然已經預裝了大部分的 Python 指令碼,但是 Matter 模組裡面有些Python指令碼還沒有安裝。為了防止我們電腦本地的 Python 環境對安裝造成干擾,這裡推薦使用 VS code 終端來執行命令,這樣就保證了該命令列的環境是 nRF Connect SDK Toolchain 設定的環境。命令參考如下:

pip3 install -r C:/ncs/v2.6.1/modules/lib/matter/scripts/setup/requirements.nrfconnect.txt

這樣系統就會自動補全nRF Connect SDK Toolchain 缺少的 Python 包。

(5)按照官方指引,最後安裝一個 ZAP 工具。進入 modules\lib\matter 的倉庫主目錄中,然後執行以下指令,並將安裝的根目錄新增到作業系統變數中。

python scripts/setup/nrfconnect/get_zap.py -l C:\Nordic\Tools\zap-win-x64 -o

3.2 開發私有藍芽協議

新建一個專案,參考官方藍芽的 central 例程編寫一個簡單的業務程式。即指定一個目標 Lock 的藍芽地址,並嘗試與其建立藍芽連線。連線建立後根據安全協議向其傳遞認證資訊,並透過 nodify 獲得 Lock 的返回。如果認證透過,則連線將持續保持並等待接收藍芽指令。否則,認證失敗,藍芽連線將被釋放。

(1)給定一個我們目標裝置的藍芽 MAC:

D8:5F:77:26:1A:0A

(2)當程式開始執行時,開啟藍芽並開啟掃描:

static void start_scan(void)
{
	int err ;

	bool ble_status = bt_is_ready;

	printk("ble status is %s\n", ble_status ? "true" : "false");

	struct bt_le_scan_param scan_param = {
		.type      = BT_LE_SCAN_TYPE_ACTIVE,
		.options    = BT_LE_SCAN_OPT_NONE,
		.interval   = BT_GAP_SCAN_FAST_INTERVAL,
		.window     = BT_GAP_SCAN_FAST_WINDOW,
	};

	err = bt_le_scan_start(&scan_param, device_found);

	if (err) {
		printk("Scanning failed to start (err %0d)\n", err);
		return;
	}

	printk("Scanning successfully started\n");
}

(3)然後,透過裝置發現過濾掉那些離我們過遠的藍芽裝置並從中篩選出目標裝置,並嘗試建立藍芽連線。

static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
			 struct net_buf_simple *ad)
{
	char addr_str[BT_ADDR_LE_STR_LEN];
	int err ;

	if (default_conn) {
		return;
	}

	if (type != BT_GAP_ADV_TYPE_ADV_IND &&
	    type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
		return;
	}

	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
 
	if (addr -> type != BT_ADDR_LE_PUBLIC){
		return ;
	}

	/* filter the  target bluetooth address */
	if (!strstr(addr_str, lock_ble_mac)){

		return ;
	}

	printk("Device found: %s (RSSI %d)\n", addr_str, rssi);

	/* connect only to devices in close proximity */

	if (rssi < -70) {
		return;
	}


	if (bt_le_scan_stop()) {
		return;
	}

	struct bt_conn_le_create_param create_param = {
		.options = BT_CONN_LE_OPT_NONE,
		.interval = BT_GAP_SCAN_FAST_INTERVAL,
		.window = BT_GAP_SCAN_FAST_WINDOW
	};

	struct bt_le_conn_param conn_param = {
		.interval_min = BT_GAP_INIT_CONN_INT_MIN,
		.interval_max = BT_GAP_INIT_CONN_INT_MAX,
		.latency = 0,
		.timeout = 400
	};


	err = bt_conn_le_create(addr, &create_param,
				&conn_param, &default_conn);
	if (err) {
		printk("Create conn to %s failed (%d)\n", addr_str, err);
		start_scan();
	}
	
}

(4)如果連線沒有建立成功,則會重新開始掃描並重試連線。如果能夠和目標裝置建立藍芽連線,則進入到服務發現過程。根據安全協議,在這個步驟中我們會對指定的 Service 和 Characteristic 進行一系列認證動作。在認證完成後,連線進入穩定狀態,並等待接收下一步指令。同時定義兩個方法,實現對指定 Lock 的鎖定 / 解鎖操作。由於這部分涉及產品的安全和內部協議,所以不做過多的細節表述。

(5)最後,定義兩個函式用以呼叫 lock 和 unlock 執行緒:

void unlock_thread_func(void){
	k_thread_create(&unlock_thread, unlock_stack_area, sizeof(unlock_stack_area),
	unlock_func, NULL,NULL,NULL,5,0,K_NO_WAIT);
	k_thread_start(&unlock_thread);
	return;

}

void lock_thread_func(void){
	k_thread_create(&lock_thread, lock_stack_area, sizeof(lock_stack_area),
	lock_func, NULL,NULL,NULL,5,0,K_NO_WAIT);
	k_thread_start(&lock_thread);
	return;
}

3.3 建立兩塊 CCK 開發板間的串列埠通訊

問:為什麼要用兩塊開發板?

答:因為我們在官方 DEMO 中編寫我們自己的私有藍芽業務時,Zephyr 會提示藍芽衝突問題。由於想要快速驗證且不想修改過多的 Matter 程式碼,加上咱產品人員畢竟不是專業的嵌入式開發,對於 RTOS 的掌握不夠熟練,所以乾脆透過串列埠的形式讓兩塊開發板各司其職,算是繞過了這個問題。但在後續正式方案中,使用一顆效能足夠,且支援 Matter 的 Wi-Fi 和 BLE 的多協議 MCU / SOC 應該就可以解決問題。

3.4 修改並燒錄官方的 Lock Demo。

(1) 修改 prj.conf,加入對串列埠的支援。

CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=n
CONFIG_RTT_CONSOLE=y
CONFIG_UART_ASYNC_API=y

(2)在 zcl_callback 檔案中,加入自定義的串列埠業務,以在 Lock 狀態變更時通知給另一塊 CCK。

(3)執行編譯-燒錄動作。

3.5 開發注意事項

在開發 Matter 的時候,使用的是 C++ 程式碼,而在開發藍芽業務的時候,使用的是 C 程式碼,這就意味著一個工程中可能會同時存在這兩種語言,這也是 Matter 應用非常突出的特性,因而也算是一份比較複雜且富有挑戰的工作。

四. 效果演示

這裡主要是嘗試亞馬遜對 Matter 接入的支援能力,開啟 Amazon Alexa 官方應用,註冊賬號後,右上角選擇新增裝置。在 Shortcuts 區域可以看到,有一個 Matter 的標識:

點進去之後,輸入充當 Matter 虛擬 Lock 的那塊 CCK 的 Matter Numeric Code,並開啟手機藍芽(這裡事先要先把 Alexa Echo 4 音響繫結到賬戶裡,並且保證配置完成可以正常使用)。然後 App 就會嘗試和 Matter 裝置建立通訊並傳遞校驗資訊。

這個過程會比較漫長,需要耐心等待,並根據 Alexa App 的提示進行操作。如果配置完成,你可以在 Home 頁面看到剛剛新增好的 Lock 裝置。

4.1 透過 Amazon APP 控制 Lock

4.2 透過 Alexa Echo 語音控制 Lock

相關文章