Skip to content

Commit 0099e9e

Browse files
committed
Add logic to handle the oven-mode change
1 parent d891fd8 commit 0099e9e

File tree

5 files changed

+151
-15
lines changed

5 files changed

+151
-15
lines changed

examples/oven-app/oven-app-common/include/OvenEndpoint.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ class OvenModeDelegate : public ModeBase::Delegate
5757
CHIP_ERROR GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) override;
5858
CHIP_ERROR GetModeTagsByIndex(uint8_t modeIndex, DataModel::List<detail::Structs::ModeTagStruct::Type> & tags) override;
5959

60+
// Public helper to query support status without exposing internal tables
61+
static bool IsSupportedMode(uint8_t mode);
62+
6063
private:
6164
EndpointId mEndpointId;
6265

63-
// Static arrays moved to implementation file to reduce header size
6466
static const detail::Structs::ModeTagStruct::Type sModeTagsBake[];
6567
static const detail::Structs::ModeTagStruct::Type sModeTagsConvection[];
6668
static const detail::Structs::ModeTagStruct::Type sModeTagsGrill[];

examples/oven-app/oven-app-common/src/OvenEndpoint.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
#include "OvenEndpoint.h"
2020
#include <app-common/zap-generated/cluster-objects.h>
21+
#include <app-common/zap-generated/attributes/Accessors.h>
22+
23+
#include "OvenManager.h"
2124
#include <app/clusters/mode-base-server/mode-base-cluster-objects.h>
2225
#include <lib/core/CHIPError.h>
2326
#include <lib/support/CodeUtils.h>
@@ -92,9 +95,8 @@ CHIP_ERROR OvenModeDelegate::Init()
9295

9396
void OvenModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response)
9497
{
95-
ChipLogProgress(Zcl, "OvenModeDelegate::HandleChangeToMode: NewMode=%d", NewMode);
96-
// TODO: Implement logic to change the oven mode.
97-
response.status = to_underlying(ModeBase::StatusCode::kSuccess);
98+
ChipLogProgress(Zcl, "OvenModeDelegate forwarding mode change to OvenManager (ep=%u newMode=%u)", mEndpointId, NewMode);
99+
OvenManager::GetInstance().ProcessOvenModeChange(mEndpointId, NewMode, response);
98100
}
99101

100102
CHIP_ERROR OvenModeDelegate::GetModeLabelByIndex(uint8_t modeIndex, MutableCharSpan & label)
@@ -147,3 +149,16 @@ CHIP_ERROR OvenEndpoint::Init()
147149
{
148150
return CHIP_NO_ERROR;
149151
}
152+
153+
bool OvenModeDelegate::IsSupportedMode(uint8_t mode)
154+
{
155+
for (auto const & opt : skModeOptions)
156+
{
157+
if (opt.mode == mode)
158+
{
159+
return true;
160+
}
161+
}
162+
return false;
163+
}
164+

examples/oven-app/silabs/include/OvenManager.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include <app-common/zap-generated/ids/Attributes.h>
3838
#include <app/clusters/on-off-server/on-off-server.h>
39+
#include <app/clusters/mode-base-server/mode-base-cluster-objects.h>
3940
#include <lib/core/DataModelTypes.h>
4041

4142
class OvenManager
@@ -80,6 +81,14 @@ class OvenManager
8081
CHIP_ERROR SetTemperatureControlledCabinetInitialState(chip::EndpointId temperatureControlledCabinetEndpoint);
8182
void TempCtrlAttributeChangeHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value, uint16_t size);
8283
void OnOffAttributeChangeHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value, uint16_t size);
84+
void OvenModeAttributeChangeHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value, uint16_t size);
85+
86+
/**
87+
* @brief Central handler for OvenMode delegate requests. Applies validation, blocked-transition policy,
88+
* and writes the CurrentMode attribute if allowed.
89+
*/
90+
void ProcessOvenModeChange(chip::EndpointId endpointId, uint8_t newMode,
91+
chip::app::Clusters::ModeBase::Commands::ChangeToModeResponse::Type & response);
8392

8493
private:
8594
static OvenManager sOvenMgr;

examples/oven-app/silabs/src/DataModelCallbacks.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attrib
5656
ChipLogValueMEI(attributeId), type, *value, size);
5757
OvenManager::GetInstance().TempCtrlAttributeChangeHandler(attributePath.mEndpointId, attributeId, value, size);
5858
break;
59+
case app::Clusters::OvenMode::Id:
60+
ChipLogProgress(Zcl, "OvenMode cluster ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u",
61+
ChipLogValueMEI(attributeId), type, *value, size);
62+
OvenManager::GetInstance().OvenModeAttributeChangeHandler(attributePath.mEndpointId, attributeId, value, size);
63+
break;
5964
default:
6065
break;
6166
}

examples/oven-app/silabs/src/OvenManager.cpp

Lines changed: 116 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include "CookTopEndpoint.h"
2323
#include "OvenEndpoint.h"
2424

25+
#include <app-common/zap-generated/cluster-objects.h>
26+
#include <app-common/zap-generated/attributes/Accessors.h>
27+
#include <app/clusters/mode-base-server/mode-base-cluster-objects.h>
28+
2529
#include "AppConfig.h"
2630
#include "AppTask.h"
2731

@@ -50,6 +54,24 @@ void OvenManager::Init()
5054

5155
VerifyOrReturn(mCookTopEndpoint.Init() == CHIP_NO_ERROR, ChipLogError(AppServer, "CookTopEndpoint Init failed"));
5256

57+
// Initialize TemperatureControl cluster numeric temperature attributes for endpoint 2 (silent on failure)
58+
{
59+
Status tcStatus = TemperatureControl::Attributes::TemperatureSetpoint::Set(kTemperatureControlledCabinetEndpoint2, 0);
60+
VerifyOrReturn(tcStatus == Status::Success,
61+
ChipLogError(AppServer, "Endpoint2 TemperatureSetpoint init failed"));
62+
63+
tcStatus = TemperatureControl::Attributes::MinTemperature::Set(kTemperatureControlledCabinetEndpoint2, 0);
64+
VerifyOrReturn(tcStatus == Status::Success,
65+
ChipLogError(AppServer, "Endpoint2 MinTemperature init failed"));
66+
67+
tcStatus = TemperatureControl::Attributes::MaxTemperature::Set(kTemperatureControlledCabinetEndpoint2, 30000);
68+
VerifyOrReturn(tcStatus == Status::Success,
69+
ChipLogError(AppServer, "Endpoint2 MaxTemperature init failed"));
70+
71+
tcStatus = TemperatureControl::Attributes::Step::Set(kTemperatureControlledCabinetEndpoint2, 500);
72+
VerifyOrReturn(tcStatus == Status::Success, ChipLogError(AppServer, "Endpoint2 Step init failed"));
73+
}
74+
5375
// Register the shared TemperatureLevelsDelegate for all the cooksurface endpoints
5476
TemperatureControl::SetInstance(&mTemperatureControlDelegate);
5577

@@ -123,24 +145,20 @@ CHIP_ERROR OvenManager::SetTemperatureControlledCabinetInitialState(EndpointId t
123145

124146
void OvenManager::TempCtrlAttributeChangeHandler(EndpointId endpointId, AttributeId attributeId, uint8_t * value, uint16_t size)
125147
{
126-
if (endpointId == kTemperatureControlledCabinetEndpoint2)
127-
{
128-
// Handle temperature control attribute changes for the temperature-controlled cabinet
129-
}
130-
else if (endpointId == kCookSurfaceEndpoint4 || endpointId == kCookSurfaceEndpoint5)
148+
if (endpointId == kCookSurfaceEndpoint4 || endpointId == kCookSurfaceEndpoint5)
131149
{
132150
// Handle temperature control attribute changes for the cook surface endpoints
133151
if (*value == 0) // low
134152
{
135-
153+
// TODO: Adjust the temperature-setpoint value in TemperatureControl Cluster accordingly
136154
}
137155
else if (*value == 1) // medium
138156
{
139-
157+
// TODO: Adjust the temperature-setpoint value in TemperatureControl Cluster accordingly
140158
}
141159
else if (*value == 2) // high
142160
{
143-
161+
// TODO: Adjust the temperature-setpoint value in TemperatureControl Cluster accordingly
144162
}
145163
}
146164
return;
@@ -160,11 +178,8 @@ void OvenManager::OnOffAttributeChangeHandler(EndpointId endpointId, AttributeId
160178
else if (endpointId == kCookSurfaceEndpoint4 || endpointId == kCookSurfaceEndpoint5)
161179
{
162180
// Handle On/Off attribute changes for the cook surface endpoints
163-
ChipLogProgress(AppServer, "OnOff command received for endpoint : %d", endpointId);
164181
bool cookSurfaceEndpoint4State = mCookSurfaceEndpoint4.GetOnOffState();
165182
bool cookSurfaceEndpoint5State = mCookSurfaceEndpoint5.GetOnOffState();
166-
ChipLogProgress(AppServer, "ep4 OnOff state : %d", cookSurfaceEndpoint4State);
167-
ChipLogProgress(AppServer, "ep5 OnOff state : %d", cookSurfaceEndpoint5State);
168183
// Check if both cooksurfaces are off. If yes, turn off the cooktop (call cooktop.TurnOffCookTop)
169184
if (cookSurfaceEndpoint4State == false && cookSurfaceEndpoint5State == false)
170185
{
@@ -174,6 +189,13 @@ void OvenManager::OnOffAttributeChangeHandler(EndpointId endpointId, AttributeId
174189
return;
175190
}
176191

192+
void OvenManager::OvenModeAttributeChangeHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value, uint16_t size)
193+
{
194+
VerifyOrReturn(endpointId == kTemperatureControlledCabinetEndpoint2,
195+
ChipLogError(AppServer, "Command received over Unsupported Endpoint"));
196+
// TODO: Update the LCD with the new Oven Mode
197+
return;
198+
}
177199

178200
void OvenManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB)
179201
{
@@ -246,3 +268,86 @@ void OvenManager::ActuatorMovementHandler(AppEvent * aEvent)
246268
}
247269
}
248270
}
271+
272+
// ---------------- Oven Mode Handling ----------------
273+
274+
namespace {
275+
struct BlockedTransition
276+
{
277+
uint8_t fromMode;
278+
uint8_t toMode;
279+
};
280+
281+
// Disallowed OvenMode Transitions.
282+
static constexpr BlockedTransition kBlockedTransitions[] = {
283+
{ TemperatureControlledCabinet::OvenModeDelegate::kModeGrill, TemperatureControlledCabinet::OvenModeDelegate::kModeProofing },
284+
{ TemperatureControlledCabinet::OvenModeDelegate::kModeProofing, TemperatureControlledCabinet::OvenModeDelegate::kModeClean },
285+
{ TemperatureControlledCabinet::OvenModeDelegate::kModeClean, TemperatureControlledCabinet::OvenModeDelegate::kModeBake },
286+
};
287+
288+
static bool IsTransitionBlocked(uint8_t fromMode, uint8_t toMode)
289+
{
290+
for (auto const & bt : kBlockedTransitions)
291+
{
292+
if (bt.fromMode == fromMode && bt.toMode == toMode)
293+
{
294+
return true;
295+
}
296+
}
297+
return false;
298+
}
299+
} // namespace
300+
301+
void OvenManager::ProcessOvenModeChange(chip::EndpointId endpointId, uint8_t newMode,
302+
chip::app::Clusters::ModeBase::Commands::ChangeToModeResponse::Type & response)
303+
{
304+
using namespace chip::app::Clusters;
305+
using chip::Protocols::InteractionModel::Status;
306+
ChipLogProgress(AppServer, "OvenManager::ProcessOvenModeChange ep=%u newMode=%u", endpointId, newMode);
307+
308+
// 1. Verify newMode is among supported modes
309+
bool supported = TemperatureControlledCabinet::OvenModeDelegate::IsSupportedMode(newMode);
310+
if (!supported)
311+
{
312+
response.status = to_underlying(ModeBase::StatusCode::kUnsupportedMode);
313+
return;
314+
}
315+
316+
// 2. Read current mode
317+
uint8_t currentMode;
318+
Status attrStatus = OvenMode::Attributes::CurrentMode::Get(endpointId, &currentMode);
319+
if (attrStatus != Status::Success)
320+
{
321+
ChipLogError(AppServer, "OvenManager: Failed to read CurrentMode");
322+
response.status = to_underlying(ModeBase::StatusCode::kGenericFailure);
323+
response.statusText.SetValue(CharSpan::fromCharString("Read CurrentMode failed"));
324+
return;
325+
}
326+
327+
// 3. No-op
328+
if (currentMode == newMode)
329+
{
330+
response.status = to_underlying(ModeBase::StatusCode::kSuccess);
331+
return;
332+
}
333+
334+
// 4. Policy check
335+
if (IsTransitionBlocked(currentMode, newMode))
336+
{
337+
ChipLogProgress(AppServer, "OvenManager: Blocked transition %u -> %u", currentMode, newMode);
338+
response.status = to_underlying(ModeBase::StatusCode::kGenericFailure);
339+
response.statusText.SetValue(CharSpan::fromCharString("Transition blocked"));
340+
return;
341+
}
342+
343+
// 5. Write new mode
344+
Status writeStatus = OvenMode::Attributes::CurrentMode::Set(endpointId, newMode);
345+
if (writeStatus != Status::Success)
346+
{
347+
ChipLogError(AppServer, "OvenManager: Failed to write CurrentMode");
348+
response.status = to_underlying(ModeBase::StatusCode::kGenericFailure);
349+
response.statusText.SetValue(CharSpan::fromCharString("Write CurrentMode failed"));
350+
return;
351+
}
352+
response.status = to_underlying(ModeBase::StatusCode::kSuccess);
353+
}

0 commit comments

Comments
 (0)