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

applications: Matter Bridge: added BLE environmental sensor support #12074

Merged
merged 1 commit into from
Aug 25, 2023
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
21 changes: 20 additions & 1 deletion applications/matter_bridge/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ target_sources(app PRIVATE
src/main.cpp
src/bridge_shell.cpp
${COMMON_ROOT}/src/bridge/bridge_manager.cpp
${COMMON_ROOT}/src/bridge/bridged_device.cpp
${COMMON_ROOT}/src/bridge/matter_bridged_device.cpp
${COMMON_ROOT}/src/bridge/bridge_storage_manager.cpp
${COMMON_ROOT}/src/bridge/bridged_device_data_provider.cpp
src/zap-generated/IMClusterCommandHandler.cpp
Expand All @@ -63,6 +63,25 @@ if(CONFIG_BRIDGE_ONOFF_LIGHT_BRIDGED_DEVICE)
)
endif() # CONFIG_BRIDGE_ONOFF_LIGHT_BRIDGED_DEVICE

if(CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE)
target_sources(app PRIVATE
src/bridged_device_types/humidity_sensor.cpp
)
endif() # CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE

if(CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE)
target_sources(app PRIVATE
src/bridged_device_types/temperature_sensor.cpp
)
endif() # CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE

# Assume it makes no sense to support BLE environmental sensor without all Matter counterparts
if(CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE AND CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE)
target_sources(app PRIVATE
src/bridged_device_types/ble_environmental_data_provider.cpp
)
endif() # CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE AND CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE

else()
if(CONFIG_BRIDGE_ONOFF_LIGHT_BRIDGED_DEVICE)
target_sources(app PRIVATE
Expand Down
10 changes: 7 additions & 3 deletions applications/matter_bridge/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ config BRIDGE_ONOFF_LIGHT_BRIDGED_DEVICE

config BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE
bool "Support for Temperature Sensor bridged device"
default y if BRIDGED_DEVICE_SIMULATED
default y

config BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE
bool "Support for Humidity Sensor bridged device"
default y if BRIDGED_DEVICE_SIMULATED
default y

choice BRIDGED_DEVICE_IMPLEMENTATION
prompt "Bridged Device implementation"
Expand Down Expand Up @@ -53,14 +53,18 @@ config BT_SCAN_FILTER_ENABLE

# Configure how many Bluetooth LE service UUIDs the Matter bridge can scan.
config BT_SCAN_UUID_CNT
default 1
default 2
ArekBalysNordic marked this conversation as resolved.
Show resolved Hide resolved

config BT_GATT_CLIENT
default y

config BT_GATT_DM
default y

config BRIDGE_BLE_DEVICE_POLLING_INTERVAL
int "BLE humidity measurement readout polling interval in ms"
default 3000

endif

if BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE
Expand Down
35 changes: 31 additions & 4 deletions applications/matter_bridge/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ The application supports the following development kits:

To test the Matter bridge application with the :ref:`Bluetooth LE bridged device <matter_bridge_app_bridged_support>`, you also need the following:

* An additional development kit compatible with the :ref:`peripheral_lbs` sample.
* A micro USB cable to connect the development kit to the PC.
* An additional development kit compatible with one of the following Bluetooth LE samples:

* :ref:`peripheral_lbs`
* :ref:`peripheral_esp`

* A micro-USB cable to connect the development kit to the PC.

To commission the Matter bridge device and control it remotely through a Wi-Fi network, you also need a Matter controller device :ref:`configured on PC or smartphone <ug_matter_configuring>`.
This requires additional hardware depending on your setup.
Expand Down Expand Up @@ -182,6 +186,7 @@ Adding a Bluetooth LE bridged device to the Matter bridge
The argument is mandatory and accepts the following values:

* ``256`` - On/Off Light.
* ``291`` - Environmental Sensor (a combination of Temperature Sensor and Humidity Sensor).

* *<ble_device_index>* is the Bluetooth LE device index on the list returned by the ``scan`` command.
The argument is mandatory and accepts only the values returned by the ``scan`` command.
Expand Down Expand Up @@ -329,8 +334,12 @@ After building the sample and programming it to your development kit, complete t

.. group-tab:: Testing with Bluetooth LE bridged devices

a. Build and program the :ref:`peripheral_lbs` sample to an additional development kit compatible with the sample.
#. Connect the development kit that is running the :ref:`peripheral_lbs` sample to the PC.
a. Build and program the one of the following Bluetooth LE samples to an additional development kit compatible with the sample:

* :ref:`peripheral_lbs`
* :ref:`peripheral_esp`
markaj-nordic marked this conversation as resolved.
Show resolved Hide resolved

#. Connect the development kit that is running the Bluetooth LE sample to the PC.
#. Using the terminal emulator connected to the bridge, run the following :ref:`Matter CLI command <matter_bridge_cli>` to scan for available Bluetooth LE devices:

.. code-block:: console
Expand Down Expand Up @@ -373,6 +382,8 @@ After building the sample and programming it to your development kit, complete t
I: Adding OnOff Light bridged device
I: Added device to dynamic endpoint 3 (index=0)

For the Environmental Sensor, two endpoints are created: one implements the Temperature Sensor, and the other implements the Humidity Sensor.

#. Write down the value for the bridged device dynamic endpoint ID.
This is going to be used in the next steps (*<bridged_device_endpoint_ID>*).
#. Use the :doc:`CHIP Tool <matter:chip_tool_guide>` to read the value of an attribute from the bridged device endpoint.
Expand All @@ -383,6 +394,22 @@ After building the sample and programming it to your development kit, complete t

./chip-tool onoff read on-off *<bridge_node_ID>* *<bridged_device_endpoint_ID>*

In case of the Environmental Sensor, the current temperature and humidity measurements forwarded by the Bluetooth LE Environmental Sensor can be read as follows:

* temperature:

.. parsed-literal::
:class: highlight

./chip-tool temperaturemeasurement read measured-value *<bridge_node_ID>* *<bridged_device_endpoint_ID>*

* humidity:

.. parsed-literal::
:class: highlight

./chip-tool relativehumiditymeasurement read measured-value *<bridge_node_ID>* *<bridged_device_endpoint_ID>*

Enabling remote control
=======================

Expand Down
3 changes: 2 additions & 1 deletion applications/matter_bridge/src/app_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ bool sHaveBLEConnections = false;

#ifdef CONFIG_BRIDGED_DEVICE_BT
static bt_uuid *sUuidLbs = BT_UUID_LBS;
static bt_uuid *sUuidServices[] = { sUuidLbs };
static bt_uuid *sUuidEs = BT_UUID_ESS;
static bt_uuid *sUuidServices[] = { sUuidLbs, sUuidEs };
static constexpr uint8_t kUuidServicesNumber = ARRAY_SIZE(sUuidServices);
#endif /* CONFIG_BRIDGED_DEVICE_BT */

Expand Down
62 changes: 43 additions & 19 deletions applications/matter_bridge/src/bridge_shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,44 +21,66 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
static BridgedDeviceDataProvider *CreateSimulatedProvider(int deviceType)
{
return BridgeFactory::GetSimulatedDataProviderFactory().Create(
static_cast<BridgedDevice::DeviceType>(deviceType), BridgeManager::HandleUpdate);
static_cast<MatterBridgedDevice::DeviceType>(deviceType), BridgeManager::HandleUpdate);
}
#endif /* CONFIG_BRIDGED_DEVICE_SIMULATED */

#ifdef CONFIG_BRIDGED_DEVICE_BT

static BridgedDeviceDataProvider *CreateBleProvider(int deviceType)
{
return BridgeFactory::GetBleDataProviderFactory().Create(static_cast<BridgedDevice::DeviceType>(deviceType),
BridgeManager::HandleUpdate);
return BridgeFactory::GetBleDataProviderFactory().Create(
static_cast<MatterBridgedDevice::DeviceType>(deviceType), BridgeManager::HandleUpdate);
}

struct BluetoothConnectionContext {
const struct shell *shell;
int deviceType;
char nodeLabel[BridgedDevice::kNodeLabelSize];
char nodeLabel[MatterBridgedDevice::kNodeLabelSize];
BLEBridgedDeviceProvider *provider;
};
#endif /* CONFIG_BRIDGED_DEVICE_BT */

static void AddDevice(const struct shell *shell, int deviceType, const char *nodeLabel,
BridgedDeviceDataProvider *provider)
{
VerifyOrReturn(provider != nullptr,
shell_fprintf(shell, SHELL_INFO, "Cannot allocate data provider of given type\n"));
VerifyOrReturn(provider != nullptr, shell_fprintf(shell, SHELL_INFO, "No valid data provider!\n"));

auto *newBridgedDevice = BridgeFactory::GetBridgedDeviceFactory().Create(
static_cast<BridgedDevice::DeviceType>(deviceType), nodeLabel);
CHIP_ERROR err;
if (deviceType == MatterBridgedDevice::DeviceType::EnvironmentalSensor) {
/* Handle special case for environmental sensor */
auto *temperatureBridgedDevice = BridgeFactory::GetBridgedDeviceFactory().Create(
MatterBridgedDevice::DeviceType::TemperatureSensor, nodeLabel);

VerifyOrReturn(newBridgedDevice != nullptr, delete provider,
shell_fprintf(shell, SHELL_INFO, "Cannot allocate Matter device of given type\n"));
VerifyOrReturn(temperatureBridgedDevice != nullptr, delete provider,
shell_fprintf(shell, SHELL_INFO, "Cannot allocate Matter device of given type\n"));

auto *humidityBridgedDevice = BridgeFactory::GetBridgedDeviceFactory().Create(
MatterBridgedDevice::DeviceType::HumiditySensor, nodeLabel);

VerifyOrReturn(humidityBridgedDevice != nullptr, delete provider, delete temperatureBridgedDevice,
shell_fprintf(shell, SHELL_INFO, "Cannot allocate Matter device of given type\n"));

MatterBridgedDevice *newBridgedDevices[] = { temperatureBridgedDevice, humidityBridgedDevice };
err = BridgeManager::Instance().AddBridgedDevices(newBridgedDevices, provider,
ARRAY_SIZE(newBridgedDevices));

} else {
auto *newBridgedDevice = BridgeFactory::GetBridgedDeviceFactory().Create(
static_cast<MatterBridgedDevice::DeviceType>(deviceType), nodeLabel);

MatterBridgedDevice *newBridgedDevices[] = { newBridgedDevice };
VerifyOrReturn(newBridgedDevice != nullptr, delete provider,
shell_fprintf(shell, SHELL_INFO, "Cannot allocate Matter device of given type\n"));
err = BridgeManager::Instance().AddBridgedDevices(newBridgedDevices, provider,
ARRAY_SIZE(newBridgedDevices));
}

CHIP_ERROR err = BridgeManager::Instance().AddBridgedDevices(newBridgedDevice, provider);
if (err == CHIP_NO_ERROR) {
shell_fprintf(shell, SHELL_INFO, "Done\n");
} else if (err == CHIP_ERROR_INVALID_STRING_LENGTH) {
shell_fprintf(shell, SHELL_ERROR, "Error: too long node label (max %d)\n",
BridgedDevice::kNodeLabelSize);
MatterBridgedDevice::kNodeLabelSize);
} else if (err == CHIP_ERROR_NO_MEMORY) {
shell_fprintf(shell, SHELL_ERROR, "Error: no memory\n");
} else if (err == CHIP_ERROR_INVALID_ARGUMENT) {
Expand Down Expand Up @@ -119,6 +141,7 @@ static int AddBridgedDeviceHandler(const struct shell *shell, size_t argc, char
BridgedDeviceDataProvider *provider = CreateBleProvider(contextPtr->deviceType);

if (!provider) {
shell_fprintf(shell, SHELL_INFO, "Cannot allocate data provider of given type\n");
return -ENOMEM;
}

Expand Down Expand Up @@ -193,13 +216,14 @@ static int ScanBridgedDeviceHandler(const struct shell *shell, size_t argc, char
SHELL_STATIC_SUBCMD_SET_CREATE(
sub_matter_bridge,
#ifdef CONFIG_BRIDGED_DEVICE_BT
SHELL_CMD_ARG(add, NULL,
"Adds bridged device. \n"
"Usage: add <bridged_device_type> <ble_device_index> [node_label]\n"
"* bridged_device_type - the bridged device's type, e.g. 256 - OnOff Light\n"
"* ble_device_index - the Bluetooth LE device's index on the list returned by the scan command\n"
"* node_label - the optional bridged device's node label\n",
AddBridgedDeviceHandler, 3, 1),
SHELL_CMD_ARG(
add, NULL,
"Adds bridged device. \n"
"Usage: add <bridged_device_type> <ble_device_index> [node_label]\n"
"* bridged_device_type - the bridged device's type, e.g. 256 - OnOff Light, 291 - EnvironmentalSensor\n"
"* ble_device_index - the Bluetooth LE device's index on the list returned by the scan command\n"
"* node_label - the optional bridged device's node label\n",
AddBridgedDeviceHandler, 3, 1),
#else
SHELL_CMD_ARG(
add, NULL,
Expand Down
30 changes: 21 additions & 9 deletions applications/matter_bridge/src/bridged_device_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#pragma once

#include "bridge_util.h"
#include "bridged_device.h"
#include "bridged_device_data_provider.h"
#include "matter_bridged_device.h"
#include <lib/support/CHIPMem.h>

#ifdef CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE
Expand All @@ -35,11 +35,17 @@
#endif
#endif

#ifdef CONFIG_BRIDGED_DEVICE_BT
#if defined(CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE) && defined(CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE)
#include "ble_environmental_data_provider.h"
#endif
#endif

namespace BridgeFactory
{
using UpdateAttributeCallback = BridgedDeviceDataProvider::UpdateAttributeCallback;
using DeviceType = BridgedDevice::DeviceType;
using BridgedDeviceFactory = DeviceFactory<BridgedDevice, const char *>;
using DeviceType = MatterBridgedDevice::DeviceType;
using BridgedDeviceFactory = DeviceFactory<MatterBridgedDevice, const char *>;

#ifdef CONFIG_BRIDGED_DEVICE_SIMULATED
using SimulatedDataProviderFactory = DeviceFactory<BridgedDeviceDataProvider, UpdateAttributeCallback>;
Expand All @@ -51,7 +57,7 @@ using BleDataProviderFactory = DeviceFactory<BridgedDeviceDataProvider, UpdateAt

auto checkLabel = [](const char *nodeLabel) {
/* If node label is provided it must fit the maximum defined length */
if (!nodeLabel || (nodeLabel && (strlen(nodeLabel) < BridgedDevice::kNodeLabelSize))) {
if (!nodeLabel || (nodeLabel && (strlen(nodeLabel) < MatterBridgedDevice::kNodeLabelSize))) {
return true;
}
return false;
Expand All @@ -62,7 +68,7 @@ inline BridgedDeviceFactory &GetBridgedDeviceFactory()
static BridgedDeviceFactory sBridgedDeviceFactory{
#ifdef CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE
{ DeviceType::HumiditySensor,
[](const char *nodeLabel) -> BridgedDevice * {
[](const char *nodeLabel) -> MatterBridgedDevice * {
if (!checkLabel(nodeLabel)) {
return nullptr;
}
Expand All @@ -71,16 +77,16 @@ inline BridgedDeviceFactory &GetBridgedDeviceFactory()
#endif
#ifdef CONFIG_BRIDGE_ONOFF_LIGHT_BRIDGED_DEVICE
{ DeviceType::OnOffLight,
[](const char *nodeLabel) -> BridgedDevice * {
[](const char *nodeLabel) -> MatterBridgedDevice * {
if (!checkLabel(nodeLabel)) {
return nullptr;
}
return chip::Platform::New<OnOffLightDevice>(nodeLabel);
} },
#endif
#ifdef CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE
{ BridgedDevice::DeviceType::TemperatureSensor,
[](const char *nodeLabel) -> BridgedDevice * {
{ MatterBridgedDevice::DeviceType::TemperatureSensor,
[](const char *nodeLabel) -> MatterBridgedDevice * {
if (!checkLabel(nodeLabel)) {
return nullptr;
}
Expand Down Expand Up @@ -121,10 +127,16 @@ inline SimulatedDataProviderFactory &GetSimulatedDataProviderFactory()
#ifdef CONFIG_BRIDGED_DEVICE_BT
inline BleDataProviderFactory &GetBleDataProviderFactory()
{
static BleDataProviderFactory sDeviceDataProvider{
static BleDataProviderFactory sDeviceDataProvider
{
#ifdef CONFIG_BRIDGE_ONOFF_LIGHT_BRIDGED_DEVICE
{ DeviceType::OnOffLight,
[](UpdateAttributeCallback clb) { return chip::Platform::New<BleOnOffLightDataProvider>(clb); } },
#endif
#if defined(CONFIG_BRIDGE_TEMPERATURE_SENSOR_BRIDGED_DEVICE) && defined(CONFIG_BRIDGE_HUMIDITY_SENSOR_BRIDGED_DEVICE)
{ DeviceType::EnvironmentalSensor, [](UpdateAttributeCallback clb) {
return chip::Platform::New<BleEnvironmentalDataProvider>(clb);
} },
#endif
};
return sDeviceDataProvider;
Expand Down
Loading
Loading