blob: 1340e703956d54fb9e3ddb2ea20f1b12c8bff239 [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.
*/
#pragma once
#include <app/ConcreteAttributePath.h>
#include <app/MessageDef/StatusIB.h>
#include <app/clusters/energy-evse-server/Constants.h>
#include <app/clusters/energy-evse-server/EnergyEvseDelegate.h>
#include <app/server-cluster/DefaultServerCluster.h>
#include <app/server-cluster/OptionalAttributeSet.h>
#include <clusters/EnergyEvse/Attributes.h>
#include <clusters/EnergyEvse/Commands.h>
#include <clusters/EnergyEvse/Enums.h>
#include <clusters/EnergyEvse/Events.h>
#include <clusters/EnergyEvse/Structs.h>
#include <lib/core/CHIPError.h>
#include <protocols/interaction_model/StatusCode.h>
namespace chip {
namespace app {
namespace Clusters {
namespace EnergyEvse {
enum class OptionalAttributes : uint32_t
{
kSupportsUserMaximumChargingCurrent = 0x1,
kSupportsRandomizationWindow = 0x2,
kSupportsApproximateEvEfficiency = 0x4
};
enum class OptionalCommands : uint32_t
{
kSupportsStartDiagnostics = 0x1
};
class EnergyEvseCluster : public DefaultServerCluster
{
public:
struct Config
{
EndpointId endpointId;
EnergyEvse::Delegate & delegate;
BitMask<EnergyEvse::Feature> feature;
BitMask<EnergyEvse::OptionalCommands> optionalCmds;
BitMask<EnergyEvse::OptionalAttributes> optionalAttrs;
Config(EndpointId aEndpointId, EnergyEvse::Delegate & aDelegate, BitMask<EnergyEvse::Feature> aFeature,
BitMask<EnergyEvse::OptionalAttributes> aOptionalAttrs, BitMask<EnergyEvse::OptionalCommands> aOptionalCmds) :
endpointId(aEndpointId),
delegate(aDelegate), feature(aFeature), optionalCmds(aOptionalCmds), optionalAttrs(aOptionalAttrs)
{}
};
// We don't want to allow the default constructor as this cluster requires a delegate to be set
EnergyEvseCluster() = delete;
EnergyEvseCluster(const Config & config) :
DefaultServerCluster({ config.endpointId, EnergyEvse::Id }), mDelegate(config.delegate), mFeatureFlags(config.feature),
mOptionalAttrs(config.optionalAttrs), mOptionalCmds(config.optionalCmds)
{
mDelegate.SetEndpointId(config.endpointId);
}
const BitFlags<EnergyEvse::Feature> & Features() const { return mFeatureFlags; }
const BitFlags<EnergyEvse::OptionalAttributes> & OptionalAttrs() const { return mOptionalAttrs; }
const BitFlags<EnergyEvse::OptionalCommands> & OptionalCmds() const { return mOptionalCmds; }
// Attribute getters and setters - cluster owns the data
StateEnum GetState() const { return mState; }
CHIP_ERROR SetState(StateEnum newValue);
SupplyStateEnum GetSupplyState() const { return mSupplyState; }
CHIP_ERROR SetSupplyState(SupplyStateEnum newValue);
FaultStateEnum GetFaultState() const { return mFaultState; }
CHIP_ERROR SetFaultState(FaultStateEnum newValue);
DataModel::Nullable<uint32_t> GetChargingEnabledUntil() const { return mChargingEnabledUntil; }
CHIP_ERROR SetChargingEnabledUntil(DataModel::Nullable<uint32_t> newValue);
DataModel::Nullable<uint32_t> GetDischargingEnabledUntil() const { return mDischargingEnabledUntil; }
CHIP_ERROR SetDischargingEnabledUntil(DataModel::Nullable<uint32_t> newValue);
int64_t GetCircuitCapacity() const { return mCircuitCapacity; }
CHIP_ERROR SetCircuitCapacity(int64_t newValue);
int64_t GetMinimumChargeCurrent() const { return mMinimumChargeCurrent; }
CHIP_ERROR SetMinimumChargeCurrent(int64_t newValue);
int64_t GetMaximumChargeCurrent() const { return mMaximumChargeCurrent; }
CHIP_ERROR SetMaximumChargeCurrent(int64_t newValue);
int64_t GetMaximumDischargeCurrent() const { return mMaximumDischargeCurrent; }
CHIP_ERROR SetMaximumDischargeCurrent(int64_t newValue);
int64_t GetUserMaximumChargeCurrent() const { return mUserMaximumChargeCurrent; }
CHIP_ERROR SetUserMaximumChargeCurrent(int64_t newValue);
uint32_t GetRandomizationDelayWindow() const { return mRandomizationDelayWindow; }
CHIP_ERROR SetRandomizationDelayWindow(uint32_t newValue);
DataModel::Nullable<uint32_t> GetNextChargeStartTime() const { return mNextChargeStartTime; }
CHIP_ERROR SetNextChargeStartTime(DataModel::Nullable<uint32_t> newValue);
DataModel::Nullable<uint32_t> GetNextChargeTargetTime() const { return mNextChargeTargetTime; }
CHIP_ERROR SetNextChargeTargetTime(DataModel::Nullable<uint32_t> newValue);
DataModel::Nullable<int64_t> GetNextChargeRequiredEnergy() const { return mNextChargeRequiredEnergy; }
CHIP_ERROR SetNextChargeRequiredEnergy(DataModel::Nullable<int64_t> newValue);
DataModel::Nullable<Percent> GetNextChargeTargetSoC() const { return mNextChargeTargetSoC; }
CHIP_ERROR SetNextChargeTargetSoC(DataModel::Nullable<Percent> newValue);
DataModel::Nullable<uint16_t> GetApproximateEVEfficiency() const { return mApproximateEVEfficiency; }
CHIP_ERROR SetApproximateEVEfficiency(DataModel::Nullable<uint16_t> newValue);
DataModel::Nullable<Percent> GetStateOfCharge() const { return mStateOfCharge; }
CHIP_ERROR SetStateOfCharge(DataModel::Nullable<Percent> newValue);
DataModel::Nullable<int64_t> GetBatteryCapacity() const { return mBatteryCapacity; }
CHIP_ERROR SetBatteryCapacity(DataModel::Nullable<int64_t> newValue);
DataModel::Nullable<CharSpan> GetVehicleID() const;
CHIP_ERROR SetVehicleID(DataModel::Nullable<CharSpan> newValue);
DataModel::Nullable<uint32_t> GetSessionID() const { return mSessionID; }
CHIP_ERROR SetSessionID(DataModel::Nullable<uint32_t> newValue);
DataModel::Nullable<uint32_t> GetSessionDuration() const { return mSessionDuration; }
CHIP_ERROR SetSessionDuration(DataModel::Nullable<uint32_t> newValue);
DataModel::Nullable<int64_t> GetSessionEnergyCharged() const { return mSessionEnergyCharged; }
CHIP_ERROR SetSessionEnergyCharged(DataModel::Nullable<int64_t> newValue);
DataModel::Nullable<int64_t> GetSessionEnergyDischarged() const { return mSessionEnergyDischarged; }
CHIP_ERROR SetSessionEnergyDischarged(DataModel::Nullable<int64_t> newValue);
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;
CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<CommandId> & builder) override;
private:
DataModel::ActionReturnStatus HandleDisable(const DataModel::InvokeRequest & request, TLV::TLVReader & input_arguments,
CommandHandler * handler);
DataModel::ActionReturnStatus HandleEnableCharging(const DataModel::InvokeRequest & request, TLV::TLVReader & input_arguments,
CommandHandler * handler);
DataModel::ActionReturnStatus HandleEnableDischarging(const DataModel::InvokeRequest & request,
TLV::TLVReader & input_arguments, CommandHandler * handler);
DataModel::ActionReturnStatus HandleStartDiagnostics(const DataModel::InvokeRequest & request, TLV::TLVReader & input_arguments,
CommandHandler * handler);
DataModel::ActionReturnStatus HandleSetTargets(const DataModel::InvokeRequest & request, TLV::TLVReader & input_arguments,
CommandHandler * handler);
std::optional<DataModel::ActionReturnStatus> HandleGetTargets(const DataModel::InvokeRequest & request,
TLV::TLVReader & input_arguments, CommandHandler * handler);
DataModel::ActionReturnStatus HandleClearTargets(const DataModel::InvokeRequest & request, TLV::TLVReader & input_arguments,
CommandHandler * handler);
Protocols::InteractionModel::Status
ValidateTargets(const DataModel::DecodableList<Structs::ChargingTargetScheduleStruct::DecodableType> & chargingTargetSchedules);
EnergyEvse::Delegate & mDelegate;
const BitFlags<EnergyEvse::Feature> mFeatureFlags;
const BitFlags<EnergyEvse::OptionalAttributes> mOptionalAttrs;
const BitFlags<EnergyEvse::OptionalCommands> mOptionalCmds;
// Attribute storage
StateEnum mState = StateEnum::kNotPluggedIn;
SupplyStateEnum mSupplyState = SupplyStateEnum::kDisabled;
FaultStateEnum mFaultState = FaultStateEnum::kNoError;
DataModel::Nullable<uint32_t> mChargingEnabledUntil = DataModel::NullNullable; // TODO Default to 0 to indicate disabled
DataModel::Nullable<uint32_t> mDischargingEnabledUntil = DataModel::NullNullable; // TODO Default to 0 to indicate disabled
int64_t mCircuitCapacity = 0;
int64_t mMinimumChargeCurrent = kMinimumChargeCurrent;
int64_t mMaximumChargeCurrent = 0;
int64_t mMaximumDischargeCurrent = 0;
int64_t mUserMaximumChargeCurrent = 0;
uint32_t mRandomizationDelayWindow = 600; // Default 600s per spec
// PREF attributes
DataModel::Nullable<uint32_t> mNextChargeStartTime = DataModel::NullNullable;
DataModel::Nullable<uint32_t> mNextChargeTargetTime = DataModel::NullNullable;
DataModel::Nullable<int64_t> mNextChargeRequiredEnergy = DataModel::NullNullable;
DataModel::Nullable<Percent> mNextChargeTargetSoC = DataModel::NullNullable;
DataModel::Nullable<uint16_t> mApproximateEVEfficiency = DataModel::NullNullable;
// SOC attributes
DataModel::Nullable<Percent> mStateOfCharge = DataModel::NullNullable;
DataModel::Nullable<int64_t> mBatteryCapacity = DataModel::NullNullable;
// PNC attributes
char mVehicleIDBuffer[kMaxVehicleIDBufSize] = { 0 };
DataModel::Nullable<CharSpan> mVehicleID = DataModel::NullNullable;
// Session attributes
DataModel::Nullable<uint32_t> mSessionID = DataModel::NullNullable;
DataModel::Nullable<uint32_t> mSessionDuration = DataModel::NullNullable;
DataModel::Nullable<int64_t> mSessionEnergyCharged = DataModel::NullNullable;
DataModel::Nullable<int64_t> mSessionEnergyDischarged = DataModel::NullNullable;
};
} // namespace EnergyEvse
} // namespace Clusters
} // namespace app
} // namespace chip