場合によっては、Matter仕様に不足している機能に対処するために新しいクラスタを作成することが最善の選択肢となります。しかし、ユーザーとして、使用できるクラスタは存在するものの、必要な機能のごく一部が欠けているという状況に直面することがあります。そのような場合、新しいクラスタを作成するのではなく、既存のクラスタに不足している機能を追加して拡張する方が適切な場合があります。
クラスタ拡張の処理方法は、拡張したいクラスタがコード駆動型アプローチを使用しているか、ZAP生成コード(レガシー)を使用しているかによって異なります。
この演習では、ZAP生成コードに基づくアプローチを使用してOnOffクラスタ拡張を作成することを目標とします。クラスタ拡張は、本レッスンの演習1および演習2で作成したOnOff Plugサンプルに追加されます。
コード駆動型アプローチを使用したクラスタ拡張の追加には、本コースの範囲外となるより複雑な実装が必要です。詳細については、専用ドキュメント技術ドキュメント:Matterアプリケーションにおけるメーカー固有クラスタの作成を参照してください。
0. この演習のベースコードを取得してください。
Visual Studio Codeの「WELCOME」パネルで、Open an existing applicationを選択し、コースのGitHubリポジトリに移動して、l3/l3_e3ディレクトリを開いてください。アプリケーションはAPPLICATIONSパネルに表示されます。
この演習のベースコードは、前回の演習の解答に、この演習のコードスニペットを入力する場所の指示を追加したものです。
1. Matter Cluster Editorを起動してください
nRF Connect for Desktopで、Matter Cluster Editorアプリケーションを開いてください。
2. OnOffクラスタの拡張を作成してください
2.1 Load from fileをクリックし、<install_path>/modules/lib/matter/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xmlファイルを選択してOnOffクラスタのベースファイルを読み込んでください。
2.2 ATTRIBUTESタブに移動し、Add Attributeボタンをクリックしてください。
以下の情報をフィールドに入力して、CustomOnOffAttribute属性を作成してください:

Codeは32ビット値で、上位16ビットがメーカーコード、下位16ビットが属性IDです。クラスタの場合と同様に、この演習ではテストコード範囲のコード0xFFF1を使用しました。コマンドIDは0x0000~0x4FFFの範囲内の値である必要があるため、この演習では例として0x0000の値を使用しました。
属性のSideはserverに設定する必要があります。これは、nRFデバイスがサーバーロールを実行し、属性の状態を保持するためです。
Typeは例としてbooleanを選択しましたが、これは属性の用途によって異なります。
Writableオプションを有効にしました。これにより、クライアントデバイスを使用して属性の値を変更できるようになります。
Saveボタンをクリックしてください。属性がATTRIBUTESビューに表示されます。
2.3 COMMANDSタブに移動し、Add Commandボタンをクリックしてください。
以下の情報をフィールドに入力して、CustomOnOffCommandコマンドを作成してください:

Codeは32ビット値で、上位16ビットがメーカーコード、下位16ビットがコマンドIDを表します。この演習のクラスタには、テスト用に予約されたID 0xFFF1を使用してください。コマンドIDは0x0000~0x00FFの範囲内の値である必要があるため、この演習ではランダムな0x0000の値を選択できます。
コマンドのSourceはclientに設定する必要があります。これは、Nordic DKがOn/Offサーバーロールを実行しており、このコマンドを送信するのは外部クライアントデバイス(特にMatterコントローラー)であるためです。
Saveボタンをクリックすると、コマンドがCOMMANDSビューに表示されます。
2.4 Save extension to fileボタンをクリックし、サンプルディレクトリ(この場合はC:/ncs/matt-fund/l3/l3_e3)からの相対パスであるsrc/default_zap/onoff-cluster_extension.xmlのファイル位置を選択してください。
3. ZAP Toolを使用して拡張機能を有効にしてください
3.1 Visual Studio CodeのAPPLICATIONSパネルで、アプリケーションを右クリックし、「Start New Terminal」を選択し、nRF Connect SDKバージョンと対応するツールチェーンバージョンを選択してください。これにより、サンプルディレクトリでターミナルが開きます。
拡張機能を含む.xmlファイル(および演習2で使用したRandomNumberGenerator.xmlファイル)を含む以下のコマンドを使用してZAP Toolを実行してください:
west zap-gui -j src/default_zap/zcl.json --clusters ./src/default_zap/RandomNumberGenerator.xml ./src/default_zap/onoff-cluster_extension.xmlTerminal command3.2 エンドポイント1のOn/Offクラスタを見つけ、歯車アイコンをクリックして設定ビューに移動してください。

3.3 On/Offクラスタの設定で、以下の画像に示すようにCustomOnOffAttribute属性を有効にしてください:

3.4 Commandsタブに切り替え、以下の画像に示すようにCustomOnOffCommandコマンドを有効にしてください:

3.5 上部バーのFile->Saveをクリックして設定を保存し、アプリケーションを終了してください。
3.6 ターミナルで以下のコマンドを実行して、.zapファイルに基づいてコードを生成してください:
west zap-generate --fullTerminal commandこれで、クラスタ拡張がアプリケーションに追加されました。
4. アプリケーションコードでOnOffクラスタ拡張を処理してください
変更されたコードはすべてapp_task.cppファイルに適用されます。
4.1 OnOffクラスタからCustomOnOffCommandコマンドを受信すると、データモデルによって自動的に呼び出されるコールバックの実装を定義してください。
この関数は、デバイスログにコマンド受信に関する情報を出力し、クライアントデバイスに結果を通知するためにデフォルトレスポンスにステータスを追加する必要があります。
以下のコードスニペットを追加してください
bool emberAfOnOffClusterCustomOnOffCommandCallback(CommandHandler *commandObj, const ConcreteCommandPath &commandPath, const OnOff::Commands::CustomOnOffCommand::DecodableType &commandData)
{
LOG_INF("CustomOnOffCommand received");
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
return true;
}C++4.2 演習1および演習2で使用したMatterPostAttributeChangeCallbackメソッドを変更してください。
clusterIdとattributeIdがOnOffクラスタとOnOff属性に設定されているかを検証するif条件を変更してください。これをclusterIdとattributeIdの個別のチェックに分割し、CustomOnOffAttributeのelse ifチェックを追加してください。実装は以下のようになります:
if (clusterId == OnOff::Id){
if (attributeId == OnOff::Attributes::OnOff::Id) {
LOG_INF("Cluster OnOff: attribute OnOff set to %" PRIu8 "", *value);
Nrf::GetBoard().GetLED(Nrf::DeviceLeds::LED2).Set(*value);
} else if (attributeId == OnOff::Attributes::CustomOnOffAttribute::Id) {
LOG_INF("Cluster OnOff: attribute CustomOnOffAttribute set to %" PRIu8 "", *value);
}
}C++5. アプリケーションをビルドしてDKにフラッシュしてください。
アプリケーションをビルドしてDKにフラッシュしてください。
6. CHIP Toolを使用してMatterデバイスをコミッショニングしてください。
前回の演習と同様に、CHIP Toolを使用してMatterデバイスをコミッショニングしてください。
5.1 Thread Border Routerがまだ実行されていることを確認してください。実行されていない場合:
5.1.1 新しいコマンドラインターミナルを開き、以下のコマンドを実行してOpenThread Border Routerを実行してください:
/dev/ttyACM0をThread Coprocessorが使用しているシリアルポート番号に置き換えてください。
sudo docker run -it --rm --privileged --name otbr --network otbr -p 8080:80 \
--sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" \
--volume /dev/ttyACM0:/dev/radio nrfconnect/otbr:fbde28a --radio-url spinel+hdlc+uart:///dev/radio?uart-baudrate=1000000Terminal command「The container name “/otbr” is already in use by container…」のようなエラーが発生した場合は、以下のコマンドを実行してください
sudo docker kill otbrsudo ip -6 route del "fd11:22::/64" dev otbr0 via "fd11:db8:1::2"sudo ip link set dev otbr0 downsudo docker network rm otbr5.1.2 Webブラウザでhttp://localhost:8080/アドレスを開き、OpenThread Border Routerのグラフィカルユーザーインターフェースにアクセスしてください。
5.1.3 サイドパネルからFormタブに移動し、挿入されたすべてのデータが以下の画像と同じであることを確認してください。次に、FORMボタンを押して、OpenThread Border RouterにThreadネットワークを形成してThreadリーダーになるよう要求してください。

5.1.4 新しいコマンドラインターミナルを開き、Docker内で実行されているThreadノードのステータスを確認してください:
sudo docker exec -it otbr sh -c "sudo ot-ctl state"Terminal command出力は以下のようになります:
leader
DoneTerminal5.2 CHIP Toolがまだ実行されていることを確認してください。実行されていない場合:
5.2.1 新しいコマンドラインターミナルを開き、前回の演習で取得したダウンロード済みバイナリファイルを以下のコマンドを使用して実行してください:
PCの場合:
./chip-tool_x64 interactive start
Raspberry Piの場合:
./chip-tool_arm64 interactive start
5.3 デバイスをネットワークにコミッショニングしてください。
5.3.1 Bluetooth LE経由のMatterアドバタイジングが実行されていることを確認してください。
デバイスのシリアルポートに以下のログが表示されます:
I: 730208 [DL]CHIPoBLE advertising started
I: 730212 [DL]NFC Tag emulation startedTerminalBluetooth LE経由のMatterアドバタイジングはMatter Templateサンプルで自動的に開始されますが、1時間後にタイムアウトします。アドバタイジングがタイムアウトした場合は、MatterデバイスのBUTTON0を押して再度開始してください。
5.3.2 CHIP Toolアプリケーションを実行しているターミナルウィンドウに戻ってください。
以下のコマンドを実行してコミッショニングプロセスを開始し、<thread dataset>引数にレッスン2演習1で取得してコンピュータに保存したThreadデータセットを入力してください。<your_selected_node_id>を他の演習で使用されていないランダムなノードID(例:4)に置き換えてください。この同じ番号は、CHIP Tool経由でデバイスにコマンドを送信する際に使用されます。
pairing ble-thread <your_selected_node_id> hex:<thread dataset> 20202021 3840Terminal commandその結果、MatterデバイスとCHIP Toolアプリケーションは、コミッショニングフローを示す多数の詳細メッセージをログに出力し始めます。これらは、ペアリングに問題がある場合に特に有用で、問題のトラブルシューティングに役立ちます。
5.1 CHIP Toolがまだ実行されていることを確認してください。実行されていない場合:
5.1.1 新しいコマンドラインターミナルを開き、前回の演習で取得したダウンロード済みバイナリファイルを以下のコマンドを使用して実行してください:
PCの場合:
./chip-tool_x64 interactive start
Raspberry Piの場合:
./chip-tool_arm64 interactive start
5.2 デバイスをネットワークにコミッショニングしてください。
5.2.1 MatterデバイスのBUTTON0を押して、Bluetooth LE経由のMatterアドバタイジングを開始してください。
デバイスのシリアルポートに以下のログが表示されます:
I: 730208 [DL]CHIPoBLE advertising started
I: 730212 [DL]NFC Tag emulation startedTerminal5.2.2 CHIP Toolアプリケーションを実行しているターミナルウィンドウに戻ってください。
以下のコマンドを実行し、<wifi_ssid>と<wifi_password>引数にWi-Fiネットワークデータを入力してください。
<your_selected_node_id>を他の演習で使用されていないランダムなノードID(例:4)に置き換えてください。この同じ番号は、CHIP Tool経由でデバイスにコマンドを送信する際に使用されます。
pairing ble-wifi <your_selected_node_id> <wifi_ssid> <wifi_password> 20202021 3840Terminal commandその結果、MatterデバイスとCHIP Toolアプリケーションは、コミッショニングフローを示す多数の詳細メッセージをログに出力し始めます。これらは、ペアリングに問題がある場合に特に有用で、問題のトラブルシューティングに役立ちます。
7. OnOff拡張機能をテストしてください。
7.1 OnOffクラスタからCustomOnOffAttribute属性の値を取得してください。演習2と同様に、CHIP Toolはカスタムクラスタと属性を名前で制御することをサポートしていません。ただし、クラスタ作成時に割り当てられたコードを使用して実行できます。たとえば、OnOffクラスタのコードは0x6で、CustomOnOffAttribute属性のコードは0xFFF10000です。属性の値を読み取るには、CHIP Toolターミナルで以下のコマンドを使用してください:
<your_selected_node_id>をこの演習のコミッショニング時に選択した番号に置き換えてください。
any read-by-id 0x6 0xFFF10000 <your_selected_node_id> 1Terminal commandCHIP Toolターミナルに以下のような出力が表示されます:
[1770792256.334] [17610:17612] [DMG] Data = false,
[1770792256.334] [17610:17612] [DMG] },
[1770792256.334] [17610:17612] [DMG]
[1770792256.334] [17610:17612] [DMG] },
[1770792256.334] [17610:17612] [DMG]
[1770792256.334] [17610:17612] [DMG] ],
[1770792256.334] [17610:17612] [DMG]
[1770792256.334] [17610:17612] [DMG] SuppressResponse = true,
[1770792256.334] [17610:17612] [DMG] InteractionModelRevision = 12
[1770792256.334] [17610:17612] [DMG] }
[1770792256.334] [17610:17612] [TOO] Endpoint: 1 Cluster: 0x0000_0006 Attribute 0xFFF1_0000 DataVersion: 3475485165
[1770792256.334] [17610:17612] [TOO] Don't know how to log attribute valueTerminalData = false属性は属性の値を示しており、デフォルトでfalseに設定されています。
7.2 以下のコマンドを使用して、CustomOnOffAttributeの値をtrueに設定してください:
any write-by-id 0x6 0xFFF10000 'true' <your_selected_node_id> 1Terminal commandMatterデバイスのログに以下のような出力が表示されます:
D: 196031 [IM]Received Write request
I: Cluster OnOff: attribute CustomOnOffAttribute set to 1TerminalD: 196031 [IM]Received Write request I: Cluster OnOff: attribute CustomOnOffAttribute set to 1
7.3 以下のコマンドを使用して、CustomOnOffAttribute属性の値を再度取得し、変更されたことを確認してください:
any read-by-id 0x6 0xFFF10000 <your_selected_node_id> 1Terminal commandCHIP Toolターミナルに以下のような出力が表示されます:
[1770792461.916] [17610:17612] [DMG] Data = true,
[1770792461.916] [17610:17612] [DMG] },
[1770792461.916] [17610:17612] [DMG]
[1770792461.916] [17610:17612] [DMG] },
[1770792461.916] [17610:17612] [DMG]
[1770792461.916] [17610:17612] [DMG] ],
[1770792461.916] [17610:17612] [DMG]
[1770792461.916] [17610:17612] [DMG] SuppressResponse = true,
[1770792461.916] [17610:17612] [DMG] InteractionModelRevision = 12
[1770792461.916] [17610:17612] [DMG] }
[1770792461.916] [17610:17612] [TOO] Endpoint: 1 Cluster: 0x0000_0006 Attribute 0xFFF1_0000 DataVersion: 3475485166
[1770792461.916] [17610:17612] [TOO] Don't know how to log attribute valueTerminalData = trueは属性の値を示しており、変更されてMatterデバイスのログに表示される値と一致しています。
7.4 以下のコマンドを使用してCustomOnOffCommandの送信を要求してください:
any command-by-id 0x6 0xFFF10000 '{}' <your_selected_node_id> 1Terminal commandMatterデバイスのログに以下のような出力が表示され、カスタムコマンドの受信が証明されます:
I: CustomOnOffCommand receivedTerminal