blob: 00da5930594b85bd8c9c67169ba1df3266a17436 [file]
/*
*
* Copyright (c) 2026 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/clusters/microwave-oven-control-server/CodegenIntegration.h>
#include <app/util/attribute-storage.h>
#include <data-model-providers/codegen/CodegenDataModelProvider.h>
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using Status = Protocols::InteractionModel::Status;
namespace chip::app::Clusters::MicrowaveOvenControl {
using namespace Attributes;
using namespace Commands;
CodegenIntegrationDelegate::CodegenIntegrationDelegate(Clusters::OperationalState::Instance & aOpStateInstance,
Clusters::ModeBase::Instance & aMicrowaveOvenModeInstance) :
mOpStateInstance(aOpStateInstance),
mMicrowaveOvenModeInstance(aMicrowaveOvenModeInstance)
{}
uint8_t CodegenIntegrationDelegate::GetCurrentOperationalState() const
{
return mOpStateInstance.GetCurrentOperationalState();
}
CHIP_ERROR CodegenIntegrationDelegate::GetNormalOperatingMode(uint8_t & mode) const
{
return mMicrowaveOvenModeInstance.GetModeValueByModeTag(to_underlying(MicrowaveOvenMode::ModeTag::kNormal), mode);
}
bool CodegenIntegrationDelegate::IsSupportedMode(uint8_t mode) const
{
return mMicrowaveOvenModeInstance.IsSupportedMode(mode);
}
bool CodegenIntegrationDelegate::IsSupportedOperationalStateCommand(EndpointId endpointId, CommandId commandId) const
{
ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> acceptedCommandsList;
CodegenDataModelProvider & model = CodegenDataModelProvider::Instance();
VerifyOrReturnValue(model.AcceptedCommands(ConcreteClusterPath(endpointId, OperationalState::Id), acceptedCommandsList) ==
CHIP_NO_ERROR,
false);
auto acceptedCommands = acceptedCommandsList.TakeBuffer();
return std::find_if(acceptedCommands.begin(), acceptedCommands.end(),
[commandId](const DataModel::AcceptedCommandEntry & entry) { return entry.commandId == commandId; }) !=
acceptedCommands.end();
}
Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClusterId, BitMask<Feature> aFeature,
OperationalState::Instance & aOpStateInstance, ModeBase::Instance & aMicrowaveOvenModeInstance) :
mDelegate(aDelegate),
mClusterPath(aEndpointId, aClusterId), mFeature(aFeature), mIntegrationDelegate(aOpStateInstance, aMicrowaveOvenModeInstance)
{
VerifyOrDie(aClusterId == MicrowaveOvenControl::Id);
}
Instance::~Instance()
{
// Call Deinit() to clean up and unregister the cluster if it is constructed.
// Return value is safely ignored because we are in the destructor and this is just
// a cleanup and we do not want to Log the error because Deinit() is part of the API
// and could be called directly by the app.
// If the cluster is not constructed, Deinit() will return CHIP_ERROR_INCORRECT_STATE.
RETURN_SAFELY_IGNORED Deinit();
}
CHIP_ERROR Instance::Init()
{
// Check if the cluster has been selected in zap
VerifyOrReturnError(emberAfContainsServer(mClusterPath.mEndpointId, mClusterPath.mClusterId), CHIP_ERROR_INVALID_ARGUMENT,
ChipLogError(Zcl, "Microwave Oven Control: The cluster with ID %lu was not enabled in zap.",
long(mClusterPath.mClusterId)));
// Exactly one of the PowerAsNumber and PowerInWatts features must be supported, per spec.
VerifyOrReturnError(
mFeature.Has(Feature::kPowerAsNumber) || mFeature.Has(Feature::kPowerInWatts), CHIP_ERROR_INVALID_ARGUMENT,
ChipLogError(Zcl, "Microwave Oven Control: feature bits error, feature must support one of PowerInWatts or PowerAsNumber"));
// Check that the feature bits do not include both PowerAsNumber and PowerInWatts
VerifyOrReturnError(
!(mFeature.Has(Feature::kPowerAsNumber) && mFeature.Has(Feature::kPowerInWatts)), CHIP_ERROR_INVALID_ARGUMENT,
ChipLogError(Zcl, "Microwave Oven Control: feature bits error, PowerAsNumber and PowerInWatts are mutually exclusive"));
// Per spec, the PowerNumberLimits feature is only allowed if the PowerAsNumber feature is supported.
VerifyOrReturnError(
!mFeature.Has(Feature::kPowerNumberLimits) || mFeature.Has(Feature::kPowerAsNumber), CHIP_ERROR_INVALID_ARGUMENT,
ChipLogError(Zcl, "Microwave Oven Control: feature bits error, PowerNumberLimits feature requires PowerAsNumber"));
if (emberAfContainsAttribute(mClusterPath.mEndpointId, mClusterPath.mClusterId, WattRating::Id))
{
mOptionalAttributeSet.Set<WattRating::Id>();
}
const EmberAfCluster * cluster = emberAfFindServerCluster(mClusterPath.mEndpointId, mClusterPath.mClusterId);
VerifyOrReturnValue(cluster != nullptr, CHIP_ERROR_NOT_FOUND);
bool supportsAddMoreTime = false;
// NOTE: acceptedCommandList is KNOWN to not be nullptr because MicrowaveOvenControl should have mandatory commands
// as such we iterate here directly without an 'empty list' (i.e. nullptr) check.
for (const CommandId * cmd = cluster->acceptedCommandList; *cmd != kInvalidCommandId; cmd++)
{
if (*cmd == Commands::AddMoreTime::Id)
{
supportsAddMoreTime = true;
break;
}
}
VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
mDelegate->SetInstance(this);
MicrowaveOvenControlCluster::Config config{ .feature = mFeature,
.optionalAttributeSet = mOptionalAttributeSet,
.supportsAddMoreTime = supportsAddMoreTime,
.integrationDelegate = mIntegrationDelegate,
.appDelegate = *mDelegate };
mCluster.Create(mClusterPath.mEndpointId, config);
return CodegenDataModelProvider::Instance().Registry().Register(mCluster.Registration());
}
CHIP_ERROR Instance::Deinit()
{
if (mDelegate)
{
mDelegate->SetInstance(nullptr);
}
VerifyOrReturnError(mCluster.IsConstructed(), CHIP_ERROR_INCORRECT_STATE);
CHIP_ERROR err = CodegenDataModelProvider::Instance().Registry().Unregister(&(mCluster.Cluster()));
LogErrorOnFailure(err);
mCluster.Destroy();
return err;
}
uint8_t Instance::GetCountOfSupportedWattLevels() const
{
VerifyOrDie(mCluster.IsConstructed());
return mCluster.Cluster().GetCountOfSupportedWattLevels();
}
uint32_t Instance::GetCookTimeSec() const
{
VerifyOrDie(mCluster.IsConstructed());
return mCluster.Cluster().GetCookTimeSec();
}
void Instance::SetCookTimeSec(uint32_t cookTimeSec)
{
VerifyOrDie(mCluster.IsConstructed());
RETURN_SAFELY_IGNORED mCluster.Cluster().SetCookTimeSec(cookTimeSec);
}
} // namespace chip::app::Clusters::MicrowaveOvenControl
void MatterMicrowaveOvenControlClusterInitCallback(EndpointId) {}
void MatterMicrowaveOvenControlClusterShutdownCallback(EndpointId, MatterClusterShutdownType) {}
void MatterMicrowaveOvenControlPluginServerInitCallback() {}
void MatterMicrowaveOvenControlPluginServerShutdownCallback() {}