Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

samples: matter: Added custom events to the Matter MS sample #21066

Merged
merged 1 commit into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions doc/nrf/protocols/matter/getting_started/custom_clusters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,13 @@ See the description of each element in the following tabs:
<code>0xFFF1FC01</code>
<define>MY_NEW_CLUSTER</define>
<description>The MyNewCluster cluster showcases a cluster manufacturer extensions</description>
<attribute side="server" code="0x00" define="MY_ATTRIBUTE" type="boolean" writable="true" default="false" optional="false">MyAttribute</attribute>
<command source="client" code="0x02" name="MyCommand" response="MyCommandResponse" optional="false">
<attribute side="server" code="0xFFF10000" define="MY_ATTRIBUTE" type="boolean" writable="true" default="false" optional="false">MyAttribute</attribute>
<command source="client" code="0xFFF10000" name="MyCommand" response="MyCommandResponse" optional="false">
<description>Command that takes two uint8 arguments and returns their sum.</description>
<arg name="arg1" type="int8u"/>
<arg name="arg2" type="int8u"/>
</command>
<event source="server" code="0x01" name="MyEvent" optional="false">
<event source="server" code="0xFFF10000" name="MyEvent" priority="info" optional="false">
<description>Event that is generated by the server.</description>
<arg name="arg1" type="int8u"/>
</event>
Expand Down Expand Up @@ -153,6 +153,8 @@ See the description of each element in the following tabs:
* ``source`` - Specifies whether the event originates from the client or server.
* ``code`` - A unique identifier for the event within the cluster.
* ``name`` - The name of the event.
* ``priority`` - The priority of the event.
The valid values are ``debug``, ``info``, and ``critical``.
* ``optional`` - Indicates whether the event is optional.
* ``description`` - A brief description of the event's purpose and functionality.
* ``arg`` - An argument for the event, specifying its name and type.
Expand All @@ -169,7 +171,7 @@ See the description of each element in the following tabs:
<arg name="arg1" type="int8u"/>
<arg name="arg2" type="int8u"/>
</command>
<event source="server" code="0x04" name="ExtendedEvent" optional="false">
<event source="server" code="0x04" name="ExtendedEvent" priority="info" optional="false">
<description>Event that is generated by the server.</description>
<arg name="arg1" type="int8u"/>
</event>
Expand Down Expand Up @@ -297,13 +299,13 @@ You can use the following template for the :file:`MyCluster.xml` file:
<code>0xFFF1FC01</code>
<define>MY_NEW_CLUSTER</define>
<description>The MyNewCluster cluster showcases a cluster manufacturer extensions</description>
<attribute side="server" code="0x00" define="MY_ATTRIBUTE" type="boolean" writable="true" default="false" optional="false">MyAttribute</attribute>
<command source="client" code="0x02" name="MyCommand" optional="false">
<attribute side="server" code="0xFFF10000" define="MY_ATTRIBUTE" type="boolean" writable="true" default="false" optional="false">MyAttribute</attribute>
<command source="client" code="0xFFF10000" name="MyCommand" optional="false">
<description>Command that takes two uint8 arguments and returns their sum.</description>
<arg name="arg1" type="int8u"/>
<arg name="arg2" type="int8u"/>
</command>
<event source="server" code="0x01" name="MyEvent" optional="false">
<event source="server" code="0xFFF10000" name="MyEvent" priority="info" optional="false">
<description>Event that is generated by the server.</description>
<arg name="arg1" type="int8u"/>
</event>
Expand All @@ -315,7 +317,7 @@ You can use the following template for the :file:`MyCluster.xml` file:
<arg name="arg1" type="int8u"/>
<arg name="arg2" type="int8u"/>
</command>
<event source="server" code="0x04" name="ExtendedEvent" optional="false">
<event source="server" code="0x04" name="ExtendedEvent" priority="info" optional="false">
<description>Event that is generated by the server.</description>
<arg name="arg1" type="int8u"/>
</event>
Expand Down Expand Up @@ -361,7 +363,7 @@ This guide focuses on the :ref:`ug_matter_gs_tools_matter_west_commands_zap_tool

.. code-block::

west zap-gui -j ./zcl.json ./MyCluster.xml
west zap-gui -j ./zcl.json --clusters ./MyCluster.xml

This example command copies the original :file:`<default Matter SDK location>/src/app/zap-templates/zcl/zcl.json` file, adds the :file:`MyCluster.xml` cluster, and saves the new :file:`zcl.json` file in the sample directory.
The newly generated :file:`zcl.json` file is used as an input to the ZAP tool.
Expand Down
49 changes: 32 additions & 17 deletions samples/matter/manufacturer_specific/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,33 @@ The development kits for this sample offer the following IPv6 network support fo

Overview
********

The sample starts the Bluetooth® LE advertising automatically and prepares the Matter device for commissioning into a Matter-enabled IPv6 network.

.. tabs::

.. group-tab:: nRF52, nRF53 and nRF70 DKs

The sample starts the Bluetooth® LE advertising automatically and prepares the Matter device for commissioning into a Matter-enabled IPv6 network.
The sample uses the **LED 1** to show the state of the connection.
You can press **Button 1** to start the factory reset when needed.
**Button 2** is used to set the state of the ``NordicDevkit`` cluster's attribute, ``UserButton``.
Matter command ``SetLED`` is used to control the state of ``UserLED``.
It takes one argument - the action to be performed (``0`` to turn the LED off, ``1`` to turn it on, ``2`` to toggle the state).
**LED 2** reflects the state of the ``UserLED``.
The ``NordicDevkit`` cluster introduces a writable ``DevKitName`` attribute, of string type as well.
The sample additionally extends the ``Basic Information`` cluster with a ``RandomNumber`` attribute and ``GenerateRandom`` command that updates the ``RandomNumber`` with a random value.

.. group-tab:: nRF54 DKs

The sample starts the Bluetooth LE advertising automatically and prepares the Matter device for commissioning into a Matter-enabled IPv6 network.
The sample uses the **LED 0** to show the state of the connection.
You can press **Button 0** to start the factory reset when needed.
**Button 1** is used to set the state of the ``NordicDevkit`` cluster's attribute, ``UserButton``.
Matter command ``SetLED`` is used to control the state of ``UserLED``.
It takes one argument - the action to be performed (``0`` to turn the LED off, ``1`` to turn it on, ``2`` to toggle the state).
**LED 1** reflects the state of the ``UserLED``.
The ``NordicDevkit`` cluster introduces a writable ``DevKitName`` attribute, of string type as well.
The sample additionally extends the ``Basic Information`` cluster with a ``RandomNumber`` attribute and ``GenerateRandom`` command that updates the ``RandomNumber`` with a random value.

The Matter command ``SetLED`` is used to control the state of ``UserLED``.
It takes one argument - the action to be performed (``0`` to turn the LED off, ``1`` to turn it on, ``2`` to toggle the state).
The ``UserButtonChanged`` event is generated when the ``UserButton`` attribute is changed.

The ``NordicDevkit`` cluster introduces a writable ``DevKitName`` attribute, of string type as well.
The sample additionally extends the ``Basic Information`` cluster with a ``RandomNumber`` attribute and ``GenerateRandom`` command that updates the ``RandomNumber`` with a random value.
The ``RandomNumberChanged`` event is generated when the ``RandomNumber`` attribute is changed.
The ``RandomNumber`` attribute value is not persistent and it is generated on each application's boot.

Custom manufacturer-specific cluster
====================================
Expand Down Expand Up @@ -132,7 +133,7 @@ User interface
.. include:: /includes/matter_sample_button.txt

Button 2:
Sets the state of ``UserButton`` attribute in the ``NordicDevkit`` cluster.
Sets the state of ``UserButton`` attribute in the ``NordicDevkit`` cluster to ``true`` on press and ``false`` on release.

.. include:: /includes/matter_segger_usb.txt

Expand All @@ -148,7 +149,7 @@ User interface
.. include:: /includes/matter_sample_button.txt

Button 1:
Sets the state of ``UserButton`` attribute in the ``NordicDevkit`` cluster.
Sets the state of ``UserButton`` attribute in the ``NordicDevkit`` cluster to ``true`` on press and ``false`` on release.

.. include:: /includes/matter_segger_usb.txt

Expand Down Expand Up @@ -234,24 +235,24 @@ To test ``NordicDevkit`` cluster's attributes and commands, complete the followi
.. parsed-literal::
:class: highlight

any read-by-id read-by-id 0xFFF1FC01 *attribute-id* 1 1
any read-by-id 0xFFF1FC01 *attribute-id* 1 1

* *attribute-id* is the attribute's ID, equal to ``1`` for ``DevKitName``, ``2`` for ``UserLED`` and ``3`` for ``UserButton`` attributes for the ``NordicDevkit`` cluster in this sample.
* *attribute-id* is the attribute's ID, equal to ``0xFFF10000`` for ``DevKitName``, ``0xFFF10001`` for ``UserLED`` and ``0xFFF10002`` for ``UserButton`` attributes for the ``NordicDevkit`` cluster in this sample.
#. Verify that all attributes have been read correctly and are equal to the default values defined in cluster's configuration.
#. Write the ``DevkitName`` attribute:

.. parsed-literal::
:class: highlight

any write-by-id 0xFFF1FC01 1 "NewName" 1 1
any write-by-id 0xFFF1FC01 0xFFF10000 "NewName" 1 1

#. Read the ``DevkitName`` attribute again to check if it has changed.
#. Send the ``SetLED`` command to the device to control the LED state:

.. parsed-literal::
:class: highlight

any command-by-id 0xFFF1FC01 0 '{ "0x0": "u:*action*" }' 1 1
any command-by-id 0xFFF1FC01 0xFFF10000 '{ "0x0": "u:*action*" }' 1 1

* *action* is the action that should be performed on LED attribute: ``0`` to turn the LED off, ``1`` to turn it on, ``2`` to toggle the state.

Expand All @@ -261,9 +262,16 @@ To test ``NordicDevkit`` cluster's attributes and commands, complete the followi
.. parsed-literal::
:class: highlight

any subscribe-by-id 0xFFF1FC01 3 0 120 1 1
any subscribe-by-id 0xFFF1FC01 0xFFF10002 0 120 1 1

#. Press the button assigned to the ``UserButton`` and check if the attribute state is updated in the chip-tool.
#. Read the ``UserButtonChanged`` event to check that events were generated on ``UserButton`` attribute changes.

.. parsed-literal::
:class: highlight

any read-event-by-id 0xFFF1FC01 0xFFF10000 1 1

#. Read the ``Basic Information`` cluster's ``RandomNumber`` attribute:

.. parsed-literal::
Expand All @@ -279,6 +287,13 @@ To test ``NordicDevkit`` cluster's attributes and commands, complete the followi
any command-by-id 0x0028 0 '{}' 1 0

#. Verify that the random value has been generated and the attribute value is updated.
#. Read the ``Basic Information`` cluster's ``RandomNumberChanged`` event to check that events were generated on ``RandomNumber`` attribute changes.

.. parsed-literal::
:class: highlight

any read-event-by-id 0x0028 0x4 1 0

#. Reboot the device, restart the chip-tool, and check if the attributes are persisting after joining the network.

Upgrading the device firmware
Expand Down
34 changes: 28 additions & 6 deletions samples/matter/manufacturer_specific/src/app_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@

#include <app-common/zap-generated/attributes/Accessors.h>

#include <app/EventLogging.h>
#include <app/util/attribute-storage.h>
#include <setup_payload/OnboardingCodesUtil.h>

#include <zephyr/random/random.h>
#include <zephyr/logging/log.h>
#include <dk_buttons_and_leds.h>
#include <zephyr/logging/log.h>
#include <zephyr/random/random.h>

LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);

Expand All @@ -35,7 +37,7 @@ constexpr EndpointId kNordicDevKitEndpointId = 1;

static void ButtonEventHandler(Nrf::ButtonState /* unused */, Nrf::ButtonMask has_changed)
{
/* Handle button press */
/* Handle button press */
if (ConnectivityMgrImpl().IsIPv6NetworkProvisioned() && ConnectivityMgrImpl().IsIPv6NetworkEnabled() &&
BUTTON2_MASK & has_changed) {
AppTask::Instance().UpdateNordicDevkitClusterState();
Expand All @@ -50,19 +52,29 @@ void AppTask::UpdateNordicDevkitClusterState()

dk_read_buttons(&button_state, nullptr);

status = Clusters::NordicDevKit::Attributes::UserLED::Set(kNordicDevKitEndpointId,
Nrf::GetBoard().GetLED(Nrf::DeviceLeds::LED2).GetState());
status = Clusters::NordicDevKit::Attributes::UserLED::Set(
kNordicDevKitEndpointId, Nrf::GetBoard().GetLED(Nrf::DeviceLeds::LED2).GetState());

if (status != Protocols::InteractionModel::Status::Success) {
LOG_ERR("Updating NordicDevkit cluster failed: %x", to_underlying(status));
}

status = Clusters::NordicDevKit::Attributes::UserButton::Set(kNordicDevKitEndpointId,
BUTTON2_MASK & button_state);
BUTTON2_MASK & button_state);

if (status != Protocols::InteractionModel::Status::Success) {
LOG_ERR("Updating NordicDevkit cluster failed: %x", to_underlying(status));
}

for (auto endpoint : EnabledEndpointsWithServerCluster(Clusters::NordicDevKit::Id)) {
/* If NordicDevKit cluster is implemented on this endpoint */
Clusters::NordicDevKit::Events::UserButtonChanged::Type event;
EventNumber eventNumber;

if (CHIP_NO_ERROR != LogEvent(event, endpoint, eventNumber)) {
ChipLogError(Zcl, "Failed to emit UserButtonChanged event");
}
}
});
}

Expand All @@ -77,6 +89,16 @@ void AppTask::UpdateBasicInformationClusterState()
if (status != Protocols::InteractionModel::Status::Success) {
LOG_ERR("Updating Basic information cluster failed: %x", to_underlying(status));
}

for (auto endpoint : EnabledEndpointsWithServerCluster(Clusters::BasicInformation::Id)) {
/* If Basic cluster is implemented on this endpoint */
Clusters::BasicInformation::Events::RandomNumberChanged::Type event;
EventNumber eventNumber;

if (CHIP_NO_ERROR != LogEvent(event, endpoint, eventNumber)) {
ChipLogError(Zcl, "Failed to emit RandomNumberChanged event");
}
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,25 @@
<code>0xFFF1FC01</code>
<define>NORDIC_DEV_KIT_CLUSTER</define>
<description>The NordicDevKit cluster showcases a cluster manufacturer extensions</description>
<command source="client" code="0x00" name="SetLED" optional="false">
<command source="client" code="0xFFF10000" name="SetLED" optional="false">
<description>Change LED state</description>
<arg name="Action" type="LEDActionEnum" optional="false"/>
</command>
<attribute side="server" code="0x01" define="DEV_KIT_NAME" type="char_string" writable="true" optional="false" default="Nordic Development Kit">DevKitName</attribute>
<attribute side="server" code="0x02" define="USER_LED" type="boolean" length="0" writable="false" reportable="false" isNullable="false" default="false" optional="false" apiMaturity="NaN">UserLED<description/><access op="read" role="view"/></attribute>
<attribute side="server" code="0x03" define="USER_BUTTON" type="boolean" length="0" writable="false" reportable="false" isNullable="false" default="false" optional="false" apiMaturity="NaN">UserButton<description/><access op="read" role="view"/></attribute>
<attribute side="server" code="0xFFF10000" define="DEV_KIT_NAME" type="char_string" writable="true" optional="false" default="Nordic Development Kit">DevKitName</attribute>
<attribute side="server" code="0xFFF10001" define="USER_LED" type="boolean" length="0" writable="false" reportable="false" isNullable="false" default="false" optional="false" apiMaturity="NaN">UserLED<description/><access op="read" role="view"/></attribute>
<attribute side="server" code="0xFFF10002" define="USER_BUTTON" type="boolean" length="0" writable="false" reportable="false" isNullable="false" default="false" optional="false" apiMaturity="NaN">UserButton<description/><access op="read" role="view"/></attribute>
<event side="server" code="0xFFF10000" name="UserButtonChanged" priority="info" optional="false">
<description>The UserButtonChanged event SHALL be emitted by a Node as soon as the User Button is pressed or released.</description>
</event>
</cluster>
<clusterExtension code="0x0028">
<command source="client" code="0x00" name="GenerateRandom" optional="false">
<description>Generate random number</description>
</command>
<attribute side="server" code="0x17" define="RANDOM_NUMBER" type="int16u" writable="true" optional="false" default="0">RandomNumber</attribute>
<event side="server" code="0x4" name="RandomNumberChanged" priority="info" optional="true">
<description>The RandomNumberChanged event SHALL be emitted by a Node as soon as the RandomNumber attribute is changed.</description>
</event>
</clusterExtension>
<deviceType>
<name>nordic-dev-kit</name>
Expand Down
Loading