blob: 2bbecb46d18c9ad266add925253ae67383a2f8ef [file]
/*
* 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.
*/
#pragma once
#include <app/clusters/scenes-server/SceneHandlerImpl.h>
#include <app/data-model/Nullable.h>
#include <app/persistence/AttributePersistenceProvider.h>
#include <app/server-cluster/DefaultServerCluster.h>
#include <app/server-cluster/OptionalAttributeSet.h>
#include <clusters/ModeSelect/AttributeIds.h>
#include <clusters/ModeSelect/Enums.h>
#include <clusters/ModeSelect/Structs.h>
#include <lib/core/DataModelTypes.h>
#include <lib/support/BitMask.h>
#include <lib/support/Span.h>
#include <platform/DiagnosticDataProvider.h>
namespace chip {
namespace app {
namespace Clusters {
class ModeSelectCluster : public DefaultServerCluster, public scenes::DefaultSceneHandlerImpl
{
public:
using OptionalAttributeSet = app::OptionalAttributeSet<ModeSelect::Attributes::StartUpMode::Id>;
class Delegate
{
public:
virtual ~Delegate() = default;
virtual Span<const ModeSelect::Structs::ModeOptionStruct::Type> GetSupportedModes() const = 0;
// Called when CurrentMode changes (via ChangeToMode command or startup logic).
virtual void OnModeChanged(uint8_t newMode) {}
};
struct Config
{
BitMask<ModeSelect::Feature> featureMap;
OptionalAttributeSet optionalAttributeSet;
chip::CharSpan description;
DataModel::Nullable<uint16_t> standardNamespace;
bool onOffValueForStartUp = false;
DeviceLayer::DiagnosticDataProvider & diagnosticDataProvider;
};
ModeSelectCluster(EndpointId endpointId, Delegate & delegate, const Config & config);
// ServerClusterInterface overrides
CHIP_ERROR Startup(ServerClusterContext & context) override;
DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request,
AttributeValueEncoder & encoder) override;
DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request,
AttributeValueDecoder & decoder) override;
std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
TLV::TLVReader & input_arguments, CommandHandler * handler) override;
CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<DataModel::AttributeEntry> & builder) override;
CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path,
ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & builder) override;
// Attribute accessors
uint8_t GetCurrentMode() const { return mCurrentMode; }
DataModel::Nullable<uint8_t> GetStartUpMode() const { return mStartUpMode; }
DataModel::Nullable<uint8_t> GetOnMode() const { return mOnMode; }
// Setters: persist to NVM and notify attribute changes
Protocols::InteractionModel::Status UpdateCurrentMode(uint8_t newMode);
Protocols::InteractionModel::Status UpdateStartUpMode(DataModel::Nullable<uint8_t> newStartUpMode);
Protocols::InteractionModel::Status UpdateOnMode(DataModel::Nullable<uint8_t> newOnMode);
bool IsSupportedMode(uint8_t mode) const;
// scenes::SceneHandler overrides
bool SupportsCluster(EndpointId endpoint, ClusterId cluster) override;
CHIP_ERROR SerializeSave(EndpointId endpoint, ClusterId cluster, MutableByteSpan & serializedBytes) override;
CHIP_ERROR ApplyScene(EndpointId endpoint, ClusterId cluster, const ByteSpan & serializedBytes,
scenes::TransitionTimeMs timeMs) override;
protected:
// Apply startup mode logic (StartUpMode → CurrentMode, OnMode → CurrentMode).
// Called by the integration layer when supported modes become available.
void ApplyStartupModeLogic();
private:
void LoadPersistentAttributes(AttributePersistenceProvider & provider);
Delegate & mDelegate;
const BitMask<ModeSelect::Feature> mFeatureMap;
const OptionalAttributeSet mOptionalAttributeSet;
const chip::CharSpan mDescription;
const DataModel::Nullable<uint16_t> mStandardNamespace;
const bool mOnOffValueForStartUp;
DeviceLayer::DiagnosticDataProvider & mDiagnosticDataProvider;
uint8_t mCurrentMode = 0;
DataModel::Nullable<uint8_t> mStartUpMode{};
DataModel::Nullable<uint8_t> mOnMode{};
};
} // namespace Clusters
} // namespace app
} // namespace chip