Skip to content

Chef: Add APIs to provide deviceType info on Endpoints. Make chef static temperature levels (temperature control cluster) endpoint agnostic. #38142

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

Merged
merged 53 commits into from
Apr 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
88f6797
Chef: Add APIs to provide deviceType info on Endpoints. Fix compositi…
sxb427 Mar 27, 2025
3441ee1
+
sxb427 Mar 27, 2025
bf2fde7
+
sxb427 Mar 27, 2025
8a441e2
Fix: two elements should not have common bits in an enum used as bitmask
sxb427 Mar 27, 2025
210234c
Merge branch 'master' into oven
sxb427 Mar 27, 2025
dc03344
Restyled by clang-format
restyled-commits Mar 27, 2025
b2f7220
Refactoring
sxb427 Mar 27, 2025
4641c8a
compilation err
sxb427 Mar 27, 2025
e2dd9f4
compilation err
sxb427 Mar 27, 2025
d8cf98a
compilation err
sxb427 Mar 27, 2025
7252e81
compilation err
sxb427 Mar 28, 2025
5e13d4b
compilation err
sxb427 Mar 28, 2025
e528154
compilation err
sxb427 Mar 28, 2025
0a04f6c
compilation err
sxb427 Mar 28, 2025
187407b
compilation err
sxb427 Mar 28, 2025
dd52e75
compilation err
sxb427 Mar 28, 2025
a1a8756
compilation err
sxb427 Mar 28, 2025
487ce16
compilation err
sxb427 Mar 28, 2025
0e1d905
compilation err
sxb427 Mar 28, 2025
f0fb2b9
compilation err
sxb427 Mar 28, 2025
d6a1a8c
compilation err
sxb427 Mar 28, 2025
e0a688a
compilation err
sxb427 Mar 28, 2025
a95ac81
compilation err
sxb427 Mar 28, 2025
49fb24f
compilation err
sxb427 Mar 28, 2025
81bfbf1
compilation err
sxb427 Mar 28, 2025
af847e1
compilation err
sxb427 Mar 28, 2025
137cdb0
compilation err
sxb427 Mar 28, 2025
50c084a
compilation err
sxb427 Mar 28, 2025
48cfc55
compilation err
sxb427 Mar 28, 2025
6aaf697
Merge branch 'master' into oven
sxb427 Mar 28, 2025
8426fb2
compilation err
sxb427 Mar 28, 2025
27faf55
compilation err
sxb427 Mar 28, 2025
faaee88
Merge branch 'master' into oven
sxb427 Mar 28, 2025
fbed38a
+
sxb427 Mar 28, 2025
b6fbf5e
Rename DataModelUtils to DeviceTypes
sxb427 Mar 28, 2025
9a688f7
Document the new methods
sxb427 Mar 28, 2025
a208953
Fix invalid memory.
sxb427 Mar 28, 2025
fa062ed
Fix compilation
sxb427 Mar 28, 2025
f954b82
Comments for EndpointPair struct. New chef namespace for cluster conf…
sxb427 Mar 28, 2025
f731b94
+
sxb427 Mar 28, 2025
b32ee18
Merge branch 'master' into oven
sxb427 Apr 3, 2025
2bb9099
Do not silently ignore CHIP_ERROR return value
sxb427 Apr 3, 2025
dcc6b0c
Review suggestion
sxb427 Apr 3, 2025
cdb5c3b
Review suggestion
sxb427 Apr 3, 2025
fd556ec
Use Enums for expected endpoint IDs
sxb427 Apr 3, 2025
c348009
Avoid enums due to casting issue
sxb427 Apr 3, 2025
01b50ae
Use Span for temperature levels
sxb427 Apr 4, 2025
3b8200d
Use Span for temperature levels
sxb427 Apr 4, 2025
dd544d4
Fix compilation
sxb427 Apr 4, 2025
69e71f0
nit: Rename constant.
sxb427 Apr 4, 2025
b204b5e
Merge branch 'master' into oven
sxb427 Apr 4, 2025
7336521
Merge branch 'master' into oven
sxb427 Apr 8, 2025
b0dd140
Merge branch 'master' into oven
sxb427 Apr 9, 2025
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
69 changes: 69 additions & 0 deletions examples/chef/common/DeviceTypes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "DeviceTypes.h"
#include <app/InteractionModelEngine.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <lib/support/CodeUtils.h>

using namespace chef;
using namespace chip;
using namespace chip::app;

bool DeviceTypes::EndpointHasDeviceType(EndpointId endpoint, DeviceTypeId deviceTypeId)
{
DataModel::ListBuilder<DataModel::DeviceTypeEntry> deviceTypesList;
CHIP_ERROR err = InteractionModelEngine::GetInstance()->GetDataModelProvider()->DeviceTypes(endpoint, deviceTypesList);
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "GetDataModelProvider DeviceTypes returned error: %" CHIP_ERROR_FORMAT, err.Format());
return false;
}
auto deviceTypes = deviceTypesList.TakeBuffer();
for (const auto & type : deviceTypes)
{
if (type.deviceTypeId == deviceTypeId)
{
return true;
}
}
return false;
}

DataModel::ListBuilder<EndpointId> DeviceTypes::GetAllEndpointsHavingDeviceType(DeviceTypeId deviceTypeId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post merge review, also fixed in followup: this should return the data, not a builder.

{
DataModel::ListBuilder<DataModel::EndpointEntry> endpointsList;
CHIP_ERROR err = InteractionModelEngine::GetInstance()->GetDataModelProvider()->Endpoints(endpointsList);
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "GetDataModelProvider Endpoints returned error: %" CHIP_ERROR_FORMAT, err.Format());
return DataModel::ListBuilder<EndpointId>();
}
auto allEndpoints = endpointsList.TakeBuffer();

DataModel::ListBuilder<EndpointId> endpoints;

for (const auto & ep : allEndpoints)
{
if (EndpointHasDeviceType(ep.id, deviceTypeId))
{
endpoints.Append(ep.id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Post-merge review because #38364 noticed this:

  • we ignore CHIP_ERROR return here
  • Append requires a capacity reserve otherwise it does not work

}
}
return endpoints;
}
69 changes: 69 additions & 0 deletions examples/chef/common/DeviceTypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <app/data-model-provider/MetadataList.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>

namespace chef {
namespace DeviceTypes {

// Common location to store all device type IDs
// Official list is in the spec and a complete copy is in -
// https://github.com/project-chip/connectedhomeip/blob/master/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml
// TODO: Device type IDs must be code generated from matter-devices.xml
constexpr chip::DeviceTypeId kCookSurfaceDeviceId = 0x0077;
constexpr chip::DeviceTypeId kCooktopDeviceId = 0x0078;
constexpr chip::DeviceTypeId kOvenDeviceId = 0x007B;
constexpr chip::DeviceTypeId kRefrigeratorDeviceId = 0x0070;
constexpr chip::DeviceTypeId kTemperatureControlledCabinetDeviceId = 0x0071;

// Expected endpoint IDs for different device types
namespace ExpectedEndpointId {
// Oven
constexpr chip::EndpointId kOven = 1;
constexpr chip::EndpointId kTopCabinetPartOfOven = 2;
constexpr chip::EndpointId kCooktopPartOfOven = 3;
constexpr chip::EndpointId kCookSurfacePartOfCooktopOven = 4;

// Cooktop
constexpr chip::EndpointId kCooktopStandAlone = 1;
constexpr chip::EndpointId kCookSurfacePartOfCooktop = 2;

// Refrigerator
constexpr chip::EndpointId kRefrigerator = 1;
constexpr chip::EndpointId kColdCabinetPartOfRefrigerator = 2;
constexpr chip::EndpointId kFreezeCabinetPartOfRefrigerator = 3;
} // namespace ExpectedEndpointId

// Devicetype APIs

/**
* Returns true if the endpoint has the specified device type in its device types list.
* Device types list for the given endpoint is fetched using DataModelProvider.
*/
bool EndpointHasDeviceType(chip::EndpointId endpoint, chip::DeviceTypeId deviceTypeId);

/**
* Returns a list of all endpoints that have the specified device type in their respective device types list.
* Endpoints list is fetched using DataModelProvider. Device type match is checked using EndpointHasDeviceType.
*/
chip::app::DataModel::ListBuilder<chip::EndpointId> GetAllEndpointsHavingDeviceType(chip::DeviceTypeId deviceTypeId);

} // namespace DeviceTypes
} // namespace chef
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifdef MATTER_DM_PLUGIN_TEMPERATURE_CONTROL_SERVER
#include "static-supported-temperature-levels.h"
#include <app/clusters/temperature-control-server/supported-temperature-levels-manager.h>
#include <app/util/attribute-storage.h>
#include <lib/support/CodeUtils.h>

using namespace chip;
Expand All @@ -30,20 +31,25 @@ using chip::Protocols::InteractionModel::Status;

app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate;

CharSpan AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions[] = { "Low"_span, "Medium"_span, "High"_span };
namespace chef {
namespace Configuration {
namespace TemperatureControl {

const AppSupportedTemperatureLevelsDelegate::EndpointPair AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints
[MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT] = { EndpointPair(
1 /* endpointId */, AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions,
MATTER_ARRAY_SIZE(AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions)) };
static const CharSpan kTemperatureLevelOptions[3] = { "Low"_span, "Medium"_span, "High"_span };
} // namespace TemperatureControl
} // namespace Configuration
} // namespace chef

chef::Configuration::TemperatureControl::EndpointPair
AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints[MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT];

uint8_t AppSupportedTemperatureLevelsDelegate::Size()
{
for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints)
{
if (endpointPair.mEndpointId == mEndpoint)
{
return endpointPair.mSize;
return endpointPair.mTemperatureLevels.size();
}
}
return 0;
Expand All @@ -55,7 +61,7 @@ CHIP_ERROR AppSupportedTemperatureLevelsDelegate::Next(MutableCharSpan & item)
{
if (endpointPair.mEndpointId == mEndpoint)
{
if (endpointPair.mSize > mIndex)
if (endpointPair.mTemperatureLevels.size() > mIndex)
{
CHIP_ERROR err = CopyCharSpanToMutableCharSpan(endpointPair.mTemperatureLevels[mIndex], item);
if (err != CHIP_NO_ERROR)
Expand All @@ -72,7 +78,13 @@ CHIP_ERROR AppSupportedTemperatureLevelsDelegate::Next(MutableCharSpan & item)
}
void emberAfTemperatureControlClusterInitCallback(EndpointId endpoint)
{
static_assert(MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT == 1, "This cluster is only enabled for endpoint 1");
ChipLogDetail(DeviceLayer, "Initializing TemperatureControl cluster for Endpoint: %d", endpoint);
uint16_t epIndex = emberAfGetClusterServerEndpointIndex(endpoint, TemperatureControl::Id,
MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
sAppSupportedTemperatureLevelsDelegate.SetSupportedEndpointPair(
epIndex,
chef::Configuration::TemperatureControl::EndpointPair(
endpoint /* endpointId */, Span<const CharSpan>(chef::Configuration::TemperatureControl::kTemperatureLevelOptions)));

chip::app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,53 @@
#include <app/clusters/temperature-control-server/supported-temperature-levels-manager.h>
#include <app/util/config.h>

namespace chef {
namespace Configuration {
namespace TemperatureControl {

/**
* @brief Endpoint to temperature levels mapping. The endpoint must have a temperature control cluster.
* Represents a pair of endpoints and temperature levels supported by that endpoint.
*/
struct EndpointPair
{
/// An endpoint having temperature control cluster.
chip::EndpointId mEndpointId;

/// Temperature levels supported by the temperature control cluster at this endpoint.
/// This should point to a const char span array initialized statically.
chip::Span<const chip::CharSpan> mTemperatureLevels;

EndpointPair() : mEndpointId(chip::kInvalidEndpointId), mTemperatureLevels() {}

EndpointPair(chip::EndpointId aEndpointId, chip::Span<const chip::CharSpan> TemperatureLevels) :
mEndpointId(aEndpointId), mTemperatureLevels(TemperatureLevels)
{}
};
} // namespace TemperatureControl
} // namespace Configuration
} // namespace chef

namespace chip {
namespace app {
namespace Clusters {
namespace TemperatureControl {

class AppSupportedTemperatureLevelsDelegate : public SupportedTemperatureLevelsIteratorDelegate
{
struct EndpointPair
{
EndpointId mEndpointId;
CharSpan * mTemperatureLevels;
uint8_t mSize;

EndpointPair(EndpointId aEndpointId, CharSpan * TemperatureLevels, uint8_t size) :
mEndpointId(aEndpointId), mTemperatureLevels(TemperatureLevels), mSize(size)
{}
};

static CharSpan temperatureLevelOptions[3];
static const EndpointPair supportedOptionsByEndpoints[MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT];
static chef::Configuration::TemperatureControl::EndpointPair
supportedOptionsByEndpoints[MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT];

public:
uint8_t Size() override;

CHIP_ERROR Next(MutableCharSpan & item) override;

static void SetSupportedEndpointPair(uint16_t index, chef::Configuration::TemperatureControl::EndpointPair endpointPair)
{
supportedOptionsByEndpoints[index] = endpointPair;
}

~AppSupportedTemperatureLevelsDelegate() {}
};

Expand Down
Loading
Loading