From e24f6deb1e020d9d3c03e2f357ec4869c1c6b9f7 Mon Sep 17 00:00:00 2001 From: PeterC1965 <101805108+PeterC1965@users.noreply.github.com> Date: Mon, 29 Jul 2024 07:37:20 +0100 Subject: [PATCH] Add water heater management cluster sdk support (#34339) * Add base water-heater-mode-cluster support into control files and regenerate files * Add support for the water-heater-management cluster SDK * Add support for the water-heater-management cluster SDK * Add support for the water-heater-management cluster SDK * Add support for the water-heater-management cluster SDK * Define chip_enable_water_heater_management_trigger and CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER * Restyled by isort * Add accidentally deleted Mode_WaterHeater.xml back * Address review comments from Tennessee Carmel-Veilleux * Add WaterHeaterManagementTestEventTriggerHandler.h * Apply various review comments from Boris Zbarsky * Apply various review comments from Boris Zbarsky * Addressing review comments from Boris * Addressing review comments from Boris * Restyled by whitespace * Restyled by clang-format * Address review comment from Tennessee * Update with review comments from Boris * Fix compilation introduced during merge --------- Co-authored-by: Restyled.io --- examples/platform/linux/AppMain.cpp | 7 + examples/platform/linux/BUILD.gn | 2 + src/app/chip_data_model.gni | 6 + ...rHeaterManagementTestEventTriggerHandler.h | 86 ++++ .../water-heater-management-server.cpp | 192 +++++++++ .../water-heater-management-server.h | 132 ++++++ src/app/util/util.cpp | 1 + .../zcl/zcl-with-test-extensions.json | 10 + src/app/zap-templates/zcl/zcl.json | 10 + src/app/zap_cluster_list.json | 2 + .../data_model/controller-clusters.zap | 61 +++ .../zap-generated/attributes/Accessors.cpp | 387 +----------------- .../zap-generated/attributes/Accessors.h | 65 +-- 13 files changed, 511 insertions(+), 450 deletions(-) create mode 100644 src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h create mode 100644 src/app/clusters/water-heater-management-server/water-heater-management-server.cpp create mode 100644 src/app/clusters/water-heater-management-server/water-heater-management-server.h diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 37bf2495f08736..6a6deae1473084 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -90,6 +90,9 @@ #if CHIP_DEVICE_CONFIG_ENABLE_ENERGY_REPORTING_TRIGGER #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER +#include +#endif #if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_ENERGY_MANAGEMENT_TRIGGER #include #endif @@ -556,6 +559,10 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl) static EnergyReportingTestEventTriggerHandler sEnergyReportingTestEventTriggerHandler; sTestEventTriggerDelegate.AddHandler(&sEnergyReportingTestEventTriggerHandler); #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER + static WaterHeaterManagementTestEventTriggerHandler sWaterHeaterManagementTestEventTriggerHandler; + sTestEventTriggerDelegate.AddHandler(&sWaterHeaterManagementTestEventTriggerHandler); +#endif #if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_ENERGY_MANAGEMENT_TRIGGER static DeviceEnergyManagementTestEventTriggerHandler sDeviceEnergyManagementTestEventTriggerHandler; sTestEventTriggerDelegate.AddHandler(&sDeviceEnergyManagementTestEventTriggerHandler); diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index f8a5334d78c47d..a63175b51200eb 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -24,6 +24,7 @@ declare_args() { chip_enable_boolean_state_configuration_trigger = false chip_enable_energy_evse_trigger = false chip_enable_energy_reporting_trigger = false + chip_enable_water_heater_management_trigger = false chip_enable_device_energy_management_trigger = false } @@ -125,6 +126,7 @@ source_set("app-main") { "CHIP_DEVICE_CONFIG_ENABLE_BOOLEAN_STATE_CONFIGURATION_TRIGGER=${chip_enable_boolean_state_configuration_trigger}", "CHIP_DEVICE_CONFIG_ENABLE_ENERGY_EVSE_TRIGGER=${chip_enable_energy_evse_trigger}", "CHIP_DEVICE_CONFIG_ENABLE_ENERGY_REPORTING_TRIGGER=${chip_enable_energy_reporting_trigger}", + "CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER=${chip_enable_water_heater_management_trigger}", "CHIP_DEVICE_CONFIG_ENABLE_DEVICE_ENERGY_MANAGEMENT_TRIGGER=${chip_enable_device_energy_management_trigger}", ] diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index da75e616aa1510..7a439a4141ce49 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -398,6 +398,12 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/thread-network-diagnostics-provider.cpp", "${_app_root}/clusters/${cluster}/thread-network-diagnostics-provider.h", ] + } else if (cluster == "water-heater-management-server") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/WaterHeaterManagementTestEventTriggerHandler.h", + ] } else if (cluster == "thread-network-directory-server") { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp", diff --git a/src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h b/src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h new file mode 100644 index 00000000000000..54b07cde0c2158 --- /dev/null +++ b/src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h @@ -0,0 +1,86 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 +#include + +/** + * @brief User handler for handling the test event trigger + * + * @note If TestEventTrigger is enabled, it needs to be implemented in the app + * + * @param eventTrigger Event trigger to handle + * + * @retval true on success + * @retval false if error happened + */ +bool HandleWaterHeaterManagementTestEventTrigger(uint64_t eventTrigger); + +namespace chip { + +/* + * These Test EventTrigger values can be used to produce artificial water heater configuration + * and water temperatures. + * + * They are sent along with the enableKey (manufacturer defined secret) + * in the General Diagnostic cluster TestEventTrigger command + */ +enum class WaterHeaterManagementTrigger : uint64_t +{ + // Simulate installation in a 100L tank full of water at 20C, with a target temperature of 60C, in OFF mode + kBasicInstallationTestEvent = 0x0094'0000'0000'0000, + + // End simulation of installation + kBasicInstallationTestEventClear = 0x0094'0000'0000'0001, + + // Simulate 100% of the water in the tank being at 20C + kWaterTemperature20CTestEvent = 0x0094'0000'0000'0002, + + // Simulate 100% of the water in the tank being at 61C + kWaterTemperature61CTestEvent = 0x0094'0000'0000'0003, + + // Simulate 100% of the water in the tank being at 66C + kWaterTemperature66CTestEvent = 0x0094'0000'0000'0004, + + // Simulate the Water Heater Mode being set to MANUAL + kManualModeTestEvent = 0x0094'0000'0000'0005, + + // Simulate the Water Heater Mode being set to OFF + kOffModeTestEvent = 0x0094'0000'0000'0006, + + // Simulate drawing off 25% of the tank volume of hot water, replaced with water at 20C + kDrawOffHotWaterTestEvent = 0x0094'0000'0000'0007, +}; + +class WaterHeaterManagementTestEventTriggerHandler : public TestEventTriggerHandler +{ +public: + WaterHeaterManagementTestEventTriggerHandler() {} + + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override + { + if (HandleWaterHeaterManagementTestEventTrigger(eventTrigger)) + { + return CHIP_NO_ERROR; + } + return CHIP_ERROR_INVALID_ARGUMENT; + } +}; + +} // namespace chip diff --git a/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp b/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp new file mode 100644 index 00000000000000..447a6646766452 --- /dev/null +++ b/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * 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 "water-heater-management-server.h" + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::WaterHeaterManagement; +using namespace chip::app::Clusters::WaterHeaterManagement::Attributes; + +using chip::Protocols::InteractionModel::Status; + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +constexpr uint16_t kClusterRevision = 1; + +CHIP_ERROR Instance::Init() +{ + ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + + return CHIP_NO_ERROR; +} + +void Instance::Shutdown() +{ + InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + unregisterAttributeAccessOverride(this); +} + +bool Instance::HasFeature(Feature aFeature) const +{ + return mFeature.Has(aFeature); +} + +// AttributeAccessInterface +CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + switch (aPath.mAttributeId) + { + case HeaterTypes::Id: + return aEncoder.Encode(mDelegate.GetHeaterTypes()); + case HeatDemand::Id: + return aEncoder.Encode(mDelegate.GetHeatDemand()); + case TankVolume::Id: + if (!HasFeature(Feature::kEnergyManagement)) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + return aEncoder.Encode(mDelegate.GetTankVolume()); + case EstimatedHeatRequired::Id: + if (!HasFeature(Feature::kEnergyManagement)) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + return aEncoder.Encode(mDelegate.GetEstimatedHeatRequired()); + case TankPercentage::Id: + if (!HasFeature(Feature::kTankPercent)) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + return aEncoder.Encode(mDelegate.GetTankPercentage()); + case BoostState::Id: + return aEncoder.Encode(mDelegate.GetBoostState()); + + /* FeatureMap - is held locally */ + case FeatureMap::Id: + return aEncoder.Encode(mFeature); + case ClusterRevision::Id: + return aEncoder.Encode(kClusterRevision); + } + + /* Allow all other unhandled attributes to fall through to Ember */ + return CHIP_NO_ERROR; +} + +void Instance::InvokeCommand(HandlerContext & handlerContext) +{ + using namespace Commands; + + switch (handlerContext.mRequestPath.mCommandId) + { + case Boost::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleBoost(ctx, commandData); }); + return; + case CancelBoost::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleCancelBoost(ctx, commandData); }); + return; + } +} + +void Instance::HandleBoost(HandlerContext & ctx, const Commands::Boost::DecodableType & commandData) +{ + uint32_t duration = commandData.duration; + Optional oneShot = commandData.oneShot; + Optional emergencyBoost = commandData.emergencyBoost; + Optional temporarySetpoint = commandData.temporarySetpoint; + Optional targetPercentage = commandData.targetPercentage; + Optional targetReheat = commandData.targetReheat; + + // Notify the appliance if the appliance hardware cannot be adjusted, then return Failure + if (HasFeature(WaterHeaterManagement::Feature::kTankPercent)) + { + if (targetPercentage.HasValue()) + { + if (targetPercentage.Value() > 100) + { + ChipLogError(Zcl, "Bad targetPercentage %u", targetPercentage.Value()); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + } + + if (targetReheat.HasValue()) + { + if (targetReheat.Value() > 100) + { + ChipLogError(Zcl, "Bad targetReheat %u", targetReheat.Value()); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + if (!targetPercentage.HasValue()) + { + ChipLogError(Zcl, "targetPercentage must be specified if targetReheat specified"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + if (oneShot.HasValue()) + { + ChipLogError(Zcl, "Cannot specify targetReheat with targetPercentage and oneShot. oneShot must be excluded"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + } + } + else if (targetPercentage.HasValue() || targetReheat.HasValue()) + { + ChipLogError(Zcl, "Cannot specify targetPercentage or targetReheat if the feature TankPercent is not supported"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + Status status = mDelegate.HandleBoost(duration, oneShot, emergencyBoost, temporarySetpoint, targetPercentage, targetReheat); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + if (status != Status::Success) + { + ChipLogError(Zcl, "WHM: Boost command failed. status " ChipLogFormatIMStatus, ChipLogValueIMStatus(status)); + } +} + +void Instance::HandleCancelBoost(HandlerContext & ctx, const Commands::CancelBoost::DecodableType & commandData) +{ + Status status = mDelegate.HandleCancelBoost(); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + if (status != Status::Success) + { + ChipLogError(Zcl, "WHM: CancelBoost command failed. status " ChipLogFormatIMStatus, ChipLogValueIMStatus(status)); + return; + } +} + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/water-heater-management-server/water-heater-management-server.h b/src/app/clusters/water-heater-management-server/water-heater-management-server.h new file mode 100644 index 00000000000000..a0a48ab900c200 --- /dev/null +++ b/src/app/clusters/water-heater-management-server/water-heater-management-server.h @@ -0,0 +1,132 @@ +/* + * + * Copyright (c) 2024 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + void SetEndpointId(EndpointId aEndpoint) { mEndpointId = aEndpoint; } + + /** + * @brief Delegate should implement a handler to start boosting the water temperature as required. + * Upon receipt, the Water Heater SHALL transition into the BOOST state, which SHALL cause the water in the + * tank (or the TargetPercentage of the water, if included) to be heated towards the set point (or the + * TemporarySetpoint, if included), which in turn may cause a call for heat, even if the mode is OFF, or + * is TIMED and it is during one of the Off periods. + * + * @param duration Indicates the time period in seconds for which the BOOST state is activated before it automatically reverts + * to the previous mode (e.g. OFF, MANUAL or TIMED). + * @param oneShot Indicates whether the BOOST state should be automatically canceled once the hot water has first reached the + * set point temperature (or the TemporarySetpoint temperature, if specified) for the TargetPercentage (if + * specified). + * @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable. This MAY cause + * multiple heat sources to be activated (e.g. a heat pump and direct electric heating element). + * @param temporarySetpoint Indicates the target temperature to which to heat the hot water for this Boost command. It SHALL be + * used instead of the normal set point temperature whilst the BOOST state is active. + * @param targetPercentage If the tank supports the TankPercent feature, this field indicates the amount of water that SHALL be + * heated by this Boost command before the heater is switched off. + * @param targetReheat If the tank supports the TankPercent feature, and the heating by this Boost command has ceased because + * the TargetPercentage of the water in the tank has been heated to the set point (or TemporarySetpoint if + * included), this field indicates the percentage to which the hot water in the tank SHALL be allowed to + * fall before again beginning to reheat it. + * + * @return Success if the boost command is accepted; otherwise the command SHALL be rejected with appropriate error. + */ + virtual Protocols::InteractionModel::Status HandleBoost(uint32_t duration, Optional oneShot, + Optional emergencyBoost, Optional temporarySetpoint, + Optional targetPercentage, Optional targetReheat) = 0; + + /** + * @brief Delegate should implement a handler to cancel a boost command. + * Upon receipt, the Water Heater SHALL transition back from the BOOST state to the previous mode (e.g. OFF, + * MANUAL or TIMED). + * + * @return It should report SUCCESS if successful and FAILURE otherwise. + */ + virtual Protocols::InteractionModel::Status HandleCancelBoost() = 0; + + // ------------------------------------------------------------------ + // Get attribute methods + virtual BitMask GetHeaterTypes() = 0; + virtual BitMask GetHeatDemand() = 0; + virtual uint16_t GetTankVolume() = 0; + virtual int64_t GetEstimatedHeatRequired() = 0; + virtual Percent GetTankPercentage() = 0; + virtual BoostStateEnum GetBoostState() = 0; + +protected: + EndpointId mEndpointId = 0; +}; + +class Instance : public AttributeAccessInterface, public CommandHandlerInterface +{ +public: + Instance(EndpointId aEndpointId, Delegate & aDelegate, Feature aFeature) : + AttributeAccessInterface(MakeOptional(aEndpointId), Id), CommandHandlerInterface(MakeOptional(aEndpointId), Id), + mDelegate(aDelegate), mFeature(aFeature) + { + /* set the base class delegates endpointId */ + mDelegate.SetEndpointId(aEndpointId); + } + + ~Instance() { Shutdown(); } + + CHIP_ERROR Init(); + void Shutdown(); + + bool HasFeature(Feature aFeature) const; + +private: + Delegate & mDelegate; + BitMask mFeature; + + // AttributeAccessInterface + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + // NOTE there are no writable attributes + + // CommandHandlerInterface + void InvokeCommand(HandlerContext & handlerContext) override; + + void HandleBoost(HandlerContext & ctx, const Commands::Boost::DecodableType & commandData); + void HandleCancelBoost(HandlerContext & ctx, const Commands::CancelBoost::DecodableType & commandData); +}; + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index 6a23c48a43f6bf..f903b5b52ea8da 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -139,6 +139,7 @@ void MatterEnergyEvseModePluginServerInitCallback() {} void MatterPowerTopologyPluginServerInitCallback() {} void MatterElectricalEnergyMeasurementPluginServerInitCallback() {} void MatterElectricalPowerMeasurementPluginServerInitCallback() {} +void MatterWaterHeaterManagementPluginServerInitCallback() {} void MatterWaterHeaterModePluginServerInitCallback() {} bool emberAfContainsAttribute(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId) diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 6e74457062e946..2207303e1ab7b7 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -645,6 +645,16 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Management": [ + "HeaterTypes", + "HeatDemand", + "TankVolume", + "EstimatedHeatRequired", + "TankPercentage", + "BoostState", + "FeatureMap", + "ClusterRevision" + ], "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Wi-Fi Network Management": ["SSID"], "Thread Network Directory": [ diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 9e6efec76b686d..c2bcc194e8611f 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -643,6 +643,16 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Management": [ + "HeaterTypes", + "HeatDemand", + "TankVolume", + "EstimatedHeatRequired", + "TankPercentage", + "BoostState", + "FeatureMap", + "ClusterRevision" + ], "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Wi-Fi Network Management": ["SSID"], "Thread Network Directory": [ diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 4852b22b3bfa68..eb9db222477ffe 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -132,6 +132,7 @@ "WAKE_ON_LAN_CLUSTER": [], "LAUNDRY_WASHER_CONTROLS_CLUSTER": [], "LAUNDRY_DRYER_CONTROLS_CLUSTER": [], + "WATER_HEATER_MANAGEMENT_CLUSTER": [], "WATER_HEATER_MODE_CLUSTER": [], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": [], "WINDOW_COVERING_CLUSTER": [], @@ -317,6 +318,7 @@ "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WIFI_NETWORK_MANAGEMENT_CLUSTER": ["wifi-network-management-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], + "WATER_HEATER_MANAGEMENT_CLUSTER": ["water-heater-management-server"], "WATER_HEATER_MODE_CLUSTER": ["mode-base-server"], "ZLL_COMMISSIONING_CLUSTER": [] } diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 71f77c8d6159b5..eb527e60667894 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -3189,6 +3189,67 @@ } ] }, + { + "name": "Water Heater Management", + "code": 148, + "mfgCode": null, + "define": "WATER_HEATER_MANAGEMENT_CLUSTER", + "side": "client", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "Boost", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CancelBoost", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Device Energy Management", "code": 152, diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index d68e2fc7ddaffc..0c974b62593860 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -15002,392 +15002,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace ElectricalEnergyMeasurement namespace WaterHeaterManagement { -namespace Attributes { - -namespace HeaterTypes { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} - -} // namespace HeaterTypes - -namespace HeatDemand { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} - -} // namespace HeatDemand - -namespace TankVolume { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace TankVolume - -namespace EstimatedHeatRequired { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENERGY_MWH_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENERGY_MWH_ATTRIBUTE_TYPE); -} - -} // namespace EstimatedHeatRequired - -namespace TankPercentage { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE); -} - -} // namespace TankPercentage - -namespace BoostState { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::WaterHeaterManagement::BoostStateEnum * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); -} - -} // namespace BoostState - -namespace FeatureMap { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); -} - -} // namespace FeatureMap - -namespace ClusterRevision { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace ClusterRevision - -} // namespace Attributes +namespace Attributes {} // namespace Attributes } // namespace WaterHeaterManagement namespace DemandResponseLoadControl { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 6ce01a1ac232d3..45b29d719e47eb 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -2468,70 +2468,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace ElectricalEnergyMeasurement namespace WaterHeaterManagement { -namespace Attributes { - -namespace HeaterTypes { -Protocols::InteractionModel::Status -Get(chip::EndpointId endpoint, - chip::BitMask * value); // WaterHeaterTypeBitmap -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty); -} // namespace HeaterTypes - -namespace HeatDemand { -Protocols::InteractionModel::Status -Get(chip::EndpointId endpoint, - chip::BitMask * value); // WaterHeaterDemandBitmap -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty); -} // namespace HeatDemand - -namespace TankVolume { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); -} // namespace TankVolume - -namespace EstimatedHeatRequired { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_t * value); // energy_mwh -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value, MarkAttributeDirty markDirty); -} // namespace EstimatedHeatRequired - -namespace TankPercentage { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent * value); // percent -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value, MarkAttributeDirty markDirty); -} // namespace TankPercentage - -namespace BoostState { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::WaterHeaterManagement::BoostStateEnum * value); // BoostStateEnum -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value, - MarkAttributeDirty markDirty); -} // namespace BoostState - -namespace FeatureMap { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); -} // namespace FeatureMap - -namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); -} // namespace ClusterRevision - -} // namespace Attributes +namespace Attributes {} // namespace Attributes } // namespace WaterHeaterManagement namespace DemandResponseLoadControl {