diff --git a/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp index 6acc81ac285b65..efaa19600bb9e9 100644 --- a/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp @@ -26,6 +26,11 @@ static std::unique_ptr gDelegate; static std::unique_ptr gEvseTargetsDelegate; static std::unique_ptr gInstance; +EndpointId GetEnergyDeviceEndpointId() +{ + return chip::EndpointId(1); +} + void emberAfEnergyEvseClusterInitCallback(chip::EndpointId endpointId) { VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index b62d154f0d58f7..22170885db1cbe 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -124,6 +124,7 @@ const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp3TagList[] = { { .tag = kTagSwitchesUp } }; const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp4TagList[] = { { .namespaceID = kNamespaceSwitches, .tag = kTagSwitchesDown } }; + } // namespace #ifdef MATTER_DM_PLUGIN_DISHWASHER_ALARM_SERVER @@ -256,7 +257,7 @@ void ApplicationInit() Clusters::ValveConfigurationAndControl::SetDefaultDelegate(chip::EndpointId(1), &sValveDelegate); Clusters::TimeSynchronization::SetDefaultDelegate(&sTimeSyncDelegate); - Clusters::WaterHeaterManagement::WhmApplicationInit(); + Clusters::WaterHeaterManagement::WhmApplicationInit(chip::EndpointId(1)); SetTagList(/* endpoint= */ 0, Span(gEp0TagList)); SetTagList(/* endpoint= */ 1, Span(gEp1TagList)); diff --git a/examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h b/examples/energy-management-app/energy-management-common/common/include/EnergyManagementAppCommonMain.h similarity index 54% rename from examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h rename to examples/energy-management-app/energy-management-common/common/include/EnergyManagementAppCommonMain.h index ac5cc5000e71b9..1a9ff734b6596f 100644 --- a/examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h +++ b/examples/energy-management-app/energy-management-common/common/include/EnergyManagementAppCommonMain.h @@ -19,5 +19,21 @@ #pragma once #include +#include +#include +#include +#include +// This app is configured by default with EP1 for EVSE and EP2 for WaterHeater, with only one endpoint +// enabled. On linux, there's a command line argument (--application) to dynamically enable +// "evse|water-heater", i.e. EP1 or EP2. On other platforms, it's a build time definition (#define). +chip::EndpointId GetEnergyDeviceEndpointId(); + +// The DEM Delegate is used for the TestEventTriggers chip::app::Clusters::DeviceEnergyManagement::DeviceEnergyManagementDelegate * GetDEMDelegate(); + +void EvseApplicationInit(); +void EvseApplicationShutdown(); + +void WaterHeaterApplicationInit(); +void WaterHeaterApplicationShutdown(); diff --git a/examples/energy-management-app/energy-management-common/common/src/EnergyManagementAppCommonMain.cpp b/examples/energy-management-app/energy-management-common/common/src/EnergyManagementAppCommonMain.cpp new file mode 100644 index 00000000000000..a6b8e6747debb7 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/common/src/EnergyManagementAppCommonMain.cpp @@ -0,0 +1,410 @@ +/* + * + * 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. + */ + +#include "EnergyManagementAppCommonMain.h" +#include "EnergyManagementAppCmdLineOptions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DeviceEnergyManagement; +using namespace chip::app::Clusters::ElectricalPowerMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement; +using namespace chip::app::Clusters::PowerTopology; +using namespace chip::app::Clusters::WaterHeaterManagement; + +namespace { + +std::unique_ptr gDEMDelegate; +std::unique_ptr gDEMInstance; +std::unique_ptr gEPMDelegate; +std::unique_ptr gEPMInstance; +std::unique_ptr gPTDelegate; +std::unique_ptr gPTInstance; +// Electrical Energy Measurement cluster uses ember to initialise +std::unique_ptr gEEMAttrAccess; +bool gCommonClustersInitialized = false; + +/* + * @brief Creates a Delegate and Instance for PowerTopology clusters + * + * The Instance is a container around the Delegate, so + * create the Delegate first, then wrap it in the Instance + * Then call the Instance->Init() to register the attribute and command handlers + */ +CHIP_ERROR PowerTopologyInit(chip::EndpointId endpointId) +{ + CHIP_ERROR err; + + if (gPTDelegate || gPTInstance) + { + ChipLogError(AppServer, "PowerTopology Instance or Delegate already exist."); + return CHIP_ERROR_INCORRECT_STATE; + } + + gPTDelegate = std::make_unique(); + if (!gPTDelegate) + { + ChipLogError(AppServer, "Failed to allocate memory for PowerTopology Delegate"); + return CHIP_ERROR_NO_MEMORY; + } + + gPTInstance = std::make_unique( + EndpointId(endpointId), *gPTDelegate, BitMask(PowerTopology::Feature::kNodeTopology), + BitMask(0)); + + if (!gPTInstance) + { + ChipLogError(AppServer, "Failed to allocate memory for PowerTopology Instance"); + gPTDelegate.reset(); + return CHIP_ERROR_NO_MEMORY; + } + + err = gPTInstance->Init(); /* Register Attribute & Command handlers */ + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Init failed on gPTInstance"); + gPTInstance.reset(); + gPTDelegate.reset(); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PowerTopologyShutdown() +{ + /* Do this in the order Instance first, then delegate + * Ensure we call the Instance->Shutdown to free attribute & command handlers first + */ + if (gPTInstance) + { + /* deregister attribute & command handlers */ + gPTInstance->Shutdown(); + gPTInstance.reset(); + } + + if (gPTDelegate) + { + gPTDelegate.reset(); + } + + return CHIP_NO_ERROR; +} + +/* + * @brief Creates a Delegate and Instance for Electrical Power Measurement cluster + * + * The Instance is a container around the Delegate, so + * create the Delegate first, then wrap it in the Instance + * Then call the Instance->Init() to register the attribute and command handlers + */ +CHIP_ERROR ElectricalPowerMeasurementInit(chip::EndpointId endpointId) +{ + CHIP_ERROR err; + + if (gEPMDelegate || gEPMInstance) + { + ChipLogError(AppServer, "EPM Instance or Delegate already exist."); + return CHIP_ERROR_INCORRECT_STATE; + } + + gEPMDelegate = std::make_unique(); + if (!gEPMDelegate) + { + ChipLogError(AppServer, "Failed to allocate memory for EPM Delegate"); + return CHIP_ERROR_NO_MEMORY; + } + + /* Manufacturer may optionally not support all features, commands & attributes */ + /* Turning on all optional features and attributes for test certification purposes */ + gEPMInstance = std::make_unique( + EndpointId(endpointId), *gEPMDelegate, + BitMask( + ElectricalPowerMeasurement::Feature::kDirectCurrent, ElectricalPowerMeasurement::Feature::kAlternatingCurrent, + ElectricalPowerMeasurement::Feature::kPolyphasePower, ElectricalPowerMeasurement::Feature::kHarmonics, + ElectricalPowerMeasurement::Feature::kPowerQuality), + BitMask( + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRanges, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeVoltage, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeActiveCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactiveCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactivePower, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentPower, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSVoltage, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSPower, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeFrequency, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributePowerFactor, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeNeutralCurrent)); + + if (!gEPMInstance) + { + ChipLogError(AppServer, "Failed to allocate memory for EPM Instance"); + gEPMDelegate.reset(); + return CHIP_ERROR_NO_MEMORY; + } + + err = gEPMInstance->Init(); /* Register Attribute & Command handlers */ + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Init failed on gEPMInstance"); + gEPMInstance.reset(); + gEPMDelegate.reset(); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ElectricalPowerMeasurementShutdown() +{ + /* Do this in the order Instance first, then delegate + * Ensure we call the Instance->Shutdown to free attribute & command handlers first + */ + if (gEPMInstance) + { + /* deregister attribute & command handlers */ + gEPMInstance->Shutdown(); + gEPMInstance.reset(); + } + + if (gEPMDelegate) + { + gEPMDelegate.reset(); + } + + return CHIP_NO_ERROR; +} + +/* + * @brief Creates a Delegate and Instance for DEM + * + * The Instance is a container around the Delegate, so + * create the Delegate first, then wrap it in the Instance + * Then call the Instance->Init() to register the attribute and command handlers + */ +CHIP_ERROR DeviceEnergyManagementInit(chip::EndpointId endpointId) +{ + if (gDEMDelegate || gDEMInstance) + { + ChipLogError(AppServer, "DEM Instance or Delegate already exist."); + return CHIP_ERROR_INCORRECT_STATE; + } + + gDEMDelegate = std::make_unique(); + if (!gDEMDelegate) + { + ChipLogError(AppServer, "Failed to allocate memory for DeviceEnergyManagementDelegate"); + return CHIP_ERROR_NO_MEMORY; + } + + chip::BitMask featureMap = GetFeatureMapFromCmdLine(); + + /* Manufacturer may optionally not support all features, commands & attributes */ + gDEMInstance = std::make_unique(endpointId, *gDEMDelegate, featureMap); + + if (!gDEMInstance) + { + ChipLogError(AppServer, "Failed to allocate memory for DeviceEnergyManagementManager"); + gDEMDelegate.reset(); + return CHIP_ERROR_NO_MEMORY; + } + + gDEMDelegate->SetDeviceEnergyManagementInstance(*gDEMInstance); + + CHIP_ERROR err = gDEMInstance->Init(); /* Register Attribute & Command handlers */ + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Init failed on gDEMInstance"); + gDEMInstance.reset(); + gDEMDelegate.reset(); + return err; + } + + return CHIP_NO_ERROR; +} + +void DeviceEnergyManagementShutdown() +{ + /* Do this in the order Instance first, then delegate + * Ensure we call the Instance->Shutdown to free attribute & command handlers first + */ + if (gDEMInstance) + { + /* deregister attribute & command handlers */ + gDEMInstance->Shutdown(); + gDEMInstance.reset(); + } + if (gDEMDelegate) + { + gDEMDelegate.reset(); + } +} + +CHIP_ERROR EnergyManagementCommonClustersInit(chip::EndpointId endpointId) +{ + if (!gCommonClustersInitialized) + { + DeviceEnergyManagementInit(endpointId); + ElectricalPowerMeasurementInit(endpointId); + PowerTopologyInit(endpointId); + } + VerifyOrReturnError(gDEMDelegate && gDEMInstance, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gEPMDelegate && gEPMInstance, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gPTDelegate && gPTInstance, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gEEMAttrAccess, CHIP_ERROR_INCORRECT_STATE); + gCommonClustersInitialized = true; + return CHIP_NO_ERROR; +} + +} // namespace + +void emberAfElectricalEnergyMeasurementClusterInitCallback(chip::EndpointId endpointId) +{ + /* emberAfElectricalEnergyMeasurementClusterInitCallback() is called for all endpoints + that include the EEM endpoint (even the one we disable dynamically). So here, we only + proceed when it's called for the right endpoint determined by GetEnergyDeviceEndpointId(). + */ + if (endpointId != GetEnergyDeviceEndpointId()) + { + return; + } + + VerifyOrDie(!gEEMAttrAccess); // Ensure it's not initialized yet. + + gEEMAttrAccess = std::make_unique( + BitMask( + ElectricalEnergyMeasurement::Feature::kImportedEnergy, ElectricalEnergyMeasurement::Feature::kExportedEnergy, + ElectricalEnergyMeasurement::Feature::kCumulativeEnergy, ElectricalEnergyMeasurement::Feature::kPeriodicEnergy), + BitMask( + ElectricalEnergyMeasurement::OptionalAttributes::kOptionalAttributeCumulativeEnergyReset)); + + // Create an accuracy entry which is between +/-0.5 and +/- 5% across the range of all possible energy readings + ElectricalEnergyMeasurement::Structs::MeasurementAccuracyRangeStruct::Type energyAccuracyRanges[] = { + { .rangeMin = 0, + .rangeMax = 1'000'000'000'000'000, // 1 million Mwh + .percentMax = MakeOptional(static_cast(500)), + .percentMin = MakeOptional(static_cast(50)) } + }; + + ElectricalEnergyMeasurement::Structs::MeasurementAccuracyStruct::Type accuracy = { + .measurementType = MeasurementTypeEnum::kElectricalEnergy, + .measured = true, + .minMeasuredValue = 0, + .maxMeasuredValue = 1'000'000'000'000'000, // 1 million Mwh + .accuracyRanges = + DataModel::List(energyAccuracyRanges) + }; + + // Example of setting CumulativeEnergyReset structure - for now set these to 0 + // but the manufacturer may want to store these in non volatile storage for timestamp (based on epoch_s) + ElectricalEnergyMeasurement::Structs::CumulativeEnergyResetStruct::Type resetStruct = { + .importedResetTimestamp = MakeOptional(MakeNullable(static_cast(0))), + .exportedResetTimestamp = MakeOptional(MakeNullable(static_cast(0))), + .importedResetSystime = MakeOptional(MakeNullable(static_cast(0))), + .exportedResetSystime = MakeOptional(MakeNullable(static_cast(0))), + }; + + if (gEEMAttrAccess) + { + gEEMAttrAccess->Init(); + + SetMeasurementAccuracy(endpointId, accuracy); + SetCumulativeReset(endpointId, MakeOptional(resetStruct)); + } +} + +DeviceEnergyManagement::DeviceEnergyManagementDelegate * GetDEMDelegate() +{ + VerifyOrDieWithMsg(gDEMDelegate.get() != nullptr, AppServer, "DEM Delegate is null"); + + return gDEMDelegate.get(); +} + +void EvseApplicationInit() +{ + auto endpointId = GetEnergyDeviceEndpointId(); + VerifyOrDie(EnergyManagementCommonClustersInit(endpointId) == CHIP_NO_ERROR); + VerifyOrDie(EnergyEvseInit(endpointId) == CHIP_NO_ERROR); + VerifyOrDie(EVSEManufacturerInit(*gEPMInstance.get(), *gPTInstance.get(), *gDEMInstance.get(), *gDEMDelegate.get()) == + CHIP_NO_ERROR); +} + +void EvseApplicationShutdown() +{ + ChipLogDetail(AppServer, "Energy Management App (EVSE): EvseApplicationShutdown()"); + + /* Shutdown in reverse order that they were created */ + EVSEManufacturerShutdown(); /* Free the EVSEManufacturer */ + PowerTopologyShutdown(); /* Free the PowerTopology */ + ElectricalPowerMeasurementShutdown(); /* Free the Electrical Power Measurement */ + EnergyEvseShutdown(); /* Free the EnergyEvse */ + DeviceEnergyManagementShutdown(); /* Free the DEM */ + + Clusters::DeviceEnergyManagementMode::Shutdown(); + Clusters::EnergyEvseMode::Shutdown(); +} + +void WaterHeaterApplicationInit() +{ + auto endpointId = GetEnergyDeviceEndpointId(); + VerifyOrDie(EnergyManagementCommonClustersInit(endpointId) == CHIP_NO_ERROR); + VerifyOrDie(WhmApplicationInit(endpointId) == CHIP_NO_ERROR); + + /* For Device Energy Management we need the ESA to be Online and ready to accept commands */ + gDEMDelegate->SetESAState(ESAStateEnum::kOnline); + gDEMDelegate->SetESAType(ESATypeEnum::kWaterHeating); + gDEMDelegate->SetDEMManufacturerDelegate(*GetWhmManufacturer()); + + // Set the abs min and max power + gDEMDelegate->SetAbsMinPower(1200000); // 1.2KW + gDEMDelegate->SetAbsMaxPower(7600000); // 7.6KW +} + +void WaterHeaterApplicationShutdown() +{ + ChipLogDetail(AppServer, "Energy Management App (WaterHeater): WaterHeaterShutdown()"); + + /* Shutdown in reverse order that they were created */ + PowerTopologyShutdown(); /* Free the PowerTopology */ + ElectricalPowerMeasurementShutdown(); /* Free the Energy Meter */ + DeviceEnergyManagementShutdown(); /* Free the DEM */ + WhmApplicationShutdown(); + + Clusters::DeviceEnergyManagementMode::Shutdown(); + Clusters::WaterHeaterMode::Shutdown(); +} diff --git a/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMTestEventTriggers.cpp b/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMTestEventTriggers.cpp index 58258b73cd50e8..23ed2afe1b994d 100644 --- a/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMTestEventTriggers.cpp +++ b/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMTestEventTriggers.cpp @@ -16,9 +16,10 @@ * limitations under the License. */ -#include #include +#include #include +#include #include @@ -28,19 +29,22 @@ using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::DeviceEnergyManagement; +namespace { -static constexpr uint16_t MAX_SLOTS = 10; -static constexpr uint16_t MAX_POWER_ADJUSTMENTS = 5; +constexpr uint16_t MAX_SLOTS = 10; +constexpr uint16_t MAX_POWER_ADJUSTMENTS = 5; -static chip::app::Clusters::DeviceEnergyManagement::Structs::SlotStruct::Type sSlots[MAX_SLOTS]; -static chip::app::Clusters::DeviceEnergyManagement::Structs::ForecastStruct::Type sForecastStruct; -static chip::app::DataModel::Nullable sForecast; +chip::app::Clusters::DeviceEnergyManagement::Structs::SlotStruct::Type sSlots[MAX_SLOTS]; +chip::app::Clusters::DeviceEnergyManagement::Structs::ForecastStruct::Type sForecastStruct; +chip::app::DataModel::Nullable sForecast; -static chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustStruct::Type sPowerAdjustments[MAX_POWER_ADJUSTMENTS]; -static chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustCapabilityStruct::Type sPowerAdjustCapabilityStruct; -static chip::app::DataModel::Nullable +chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustStruct::Type sPowerAdjustments[MAX_POWER_ADJUSTMENTS]; +chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustCapabilityStruct::Type sPowerAdjustCapabilityStruct; +chip::app::DataModel::Nullable sPowerAdjustmentCapability; +} // namespace + CHIP_ERROR ConfigureForecast(uint16_t numSlots) { uint32_t chipEpoch = 0; diff --git a/examples/energy-management-app/energy-management-common/device-energy-management/src/device-energy-management-mode.cpp b/examples/energy-management-app/energy-management-common/device-energy-management/src/device-energy-management-mode.cpp index d993e5c163ada1..330c0b0e389512 100644 --- a/examples/energy-management-app/energy-management-common/device-energy-management/src/device-energy-management-mode.cpp +++ b/examples/energy-management-app/energy-management-common/device-energy-management/src/device-energy-management-mode.cpp @@ -16,19 +16,27 @@ * limitations under the License. */ +#include +#include #include #include using namespace chip::app::Clusters; using namespace chip::app::Clusters::DeviceEnergyManagementMode; +using namespace chip::app::Clusters::DeviceEnergyManagement; + using chip::Protocols::InteractionModel::Status; template using List = chip::app::DataModel::List; using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; +namespace { + static std::unique_ptr gDeviceEnergyManagementModeDelegate; static std::unique_ptr gDeviceEnergyManagementModeInstance; +} // namespace + CHIP_ERROR DeviceEnergyManagementModeDelegate::Init() { return CHIP_NO_ERROR; @@ -77,11 +85,6 @@ CHIP_ERROR DeviceEnergyManagementModeDelegate::GetModeTagsByIndex(uint8_t modeIn return CHIP_NO_ERROR; } -ModeBase::Instance * DeviceEnergyManagementMode::Instance() -{ - return gDeviceEnergyManagementModeInstance.get(); -} - void DeviceEnergyManagementMode::Shutdown() { gDeviceEnergyManagementModeInstance.reset(); @@ -90,6 +93,16 @@ void DeviceEnergyManagementMode::Shutdown() void emberAfDeviceEnergyManagementModeClusterInitCallback(chip::EndpointId endpointId) { + /* emberAfDeviceEnergyManagementModeClusterInitCallback() is called for all endpoints + that include this cluster (even the one we disable dynamically). So here, we only + proceed when it's called for the right endpoint determined by GetEnergyDeviceEndpointId() + (a cmd line argument on linux or #define on other platforms). + */ + if (endpointId != GetEnergyDeviceEndpointId()) + { + return; + } + VerifyOrDie(!gDeviceEnergyManagementModeDelegate && !gDeviceEnergyManagementModeInstance); gDeviceEnergyManagementModeDelegate = std::make_unique(); gDeviceEnergyManagementModeInstance = std::make_unique(gDeviceEnergyManagementModeDelegate.get(), diff --git a/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseMain.h b/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseMain.h index 07dce510e9b38c..02427aec4dab92 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseMain.h +++ b/examples/energy-management-app/energy-management-common/energy-evse/include/EnergyEvseMain.h @@ -18,16 +18,20 @@ #pragma once +#include +#include +#include +#include #include -void EvseApplicationInit(); -void EvseApplicationShutdown(); +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ElectricalPowerMeasurement; +using namespace chip::app::Clusters::PowerTopology; +using namespace chip::app::Clusters::DeviceEnergyManagement; -CHIP_ERROR DeviceEnergyManagementInit(); -CHIP_ERROR DeviceEnergyManagementShutdown(); +CHIP_ERROR EnergyEvseInit(chip::EndpointId endpointId); +CHIP_ERROR EnergyEvseShutdown(); -CHIP_ERROR EnergyMeterInit(); -CHIP_ERROR EnergyMeterShutdown(); - -CHIP_ERROR PowerTopologyInit(); -CHIP_ERROR PowerTopologyShutdown(); +CHIP_ERROR EVSEManufacturerInit(ElectricalPowerMeasurementInstance & epmInstance, PowerTopologyInstance & ptInstance, + DeviceEnergyManagementManager & demInstance, DeviceEnergyManagementDelegate & demDelegate); +CHIP_ERROR EVSEManufacturerShutdown(); diff --git a/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseMain.cpp b/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseMain.cpp index 8e900c0948008a..37553144f2f026 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseMain.cpp +++ b/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseMain.cpp @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -31,115 +33,30 @@ #include #include #include -#include #include #include #include -#define ENERGY_EVSE_ENDPOINT 1 - using namespace chip; using namespace chip::app; using namespace chip::app::DataModel; using namespace chip::app::Clusters; -using namespace chip::app::Clusters::EnergyEvse; using namespace chip::app::Clusters::DeviceEnergyManagement; using namespace chip::app::Clusters::ElectricalPowerMeasurement; using namespace chip::app::Clusters::ElectricalEnergyMeasurement; +using namespace chip::app::Clusters::EnergyEvse; using namespace chip::app::Clusters::PowerTopology; static std::unique_ptr gEvseDelegate; static std::unique_ptr gEvseTargetsDelegate; static std::unique_ptr gEvseInstance; -static std::unique_ptr gDEMDelegate; -static std::unique_ptr gDEMInstance; static std::unique_ptr gEvseManufacturer; -static std::unique_ptr gEPMDelegate; -static std::unique_ptr gEPMInstance; -// Electrical Energy Measurement cluster uses ember to initialise -static std::unique_ptr gEEMAttrAccess; - -static std::unique_ptr gPTDelegate; -static std::unique_ptr gPTInstance; EVSEManufacturer * EnergyEvse::GetEvseManufacturer() { return gEvseManufacturer.get(); } -DeviceEnergyManagement::DeviceEnergyManagementDelegate * GetDEMDelegate() -{ - VerifyOrDieWithMsg(gDEMDelegate.get() != nullptr, AppServer, "DEM Delegate is null"); - - return gDEMDelegate.get(); -} - -/* - * @brief Creates a Delegate and Instance for DEM - * - * The Instance is a container around the Delegate, so - * create the Delegate first, then wrap it in the Instance - * Then call the Instance->Init() to register the attribute and command handlers - */ -CHIP_ERROR DeviceEnergyManagementInit() -{ - if (gDEMDelegate || gDEMInstance) - { - ChipLogError(AppServer, "DEM Instance or Delegate already exist."); - return CHIP_ERROR_INCORRECT_STATE; - } - - gDEMDelegate = std::make_unique(); - if (!gDEMDelegate) - { - ChipLogError(AppServer, "Failed to allocate memory for DeviceEnergyManagementDelegate"); - return CHIP_ERROR_NO_MEMORY; - } - - BitMask featureMap = GetFeatureMapFromCmdLine(); - - /* Manufacturer may optionally not support all features, commands & attributes */ - gDEMInstance = std::make_unique(EndpointId(ENERGY_EVSE_ENDPOINT), *gDEMDelegate, featureMap); - - if (!gDEMInstance) - { - ChipLogError(AppServer, "Failed to allocate memory for DeviceEnergyManagementManager"); - gDEMDelegate.reset(); - return CHIP_ERROR_NO_MEMORY; - } - - gDEMDelegate->SetDeviceEnergyManagementInstance(*gDEMInstance); - - CHIP_ERROR err = gDEMInstance->Init(); /* Register Attribute & Command handlers */ - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "Init failed on gDEMInstance"); - gDEMInstance.reset(); - gDEMDelegate.reset(); - return err; - } - - return CHIP_NO_ERROR; -} - -CHIP_ERROR DeviceEnergyManagementShutdown() -{ - /* Do this in the order Instance first, then delegate - * Ensure we call the Instance->Shutdown to free attribute & command handlers first - */ - if (gDEMInstance) - { - /* deregister attribute & command handlers */ - gDEMInstance->Shutdown(); - gDEMInstance.reset(); - } - if (gDEMDelegate) - { - gDEMDelegate.reset(); - } - return CHIP_NO_ERROR; -} - /* * @brief Creates a Delegate and Instance for EVSE cluster * @@ -147,7 +64,7 @@ CHIP_ERROR DeviceEnergyManagementShutdown() * create the Delegate first, then wrap it in the Instance * Then call the Instance->Init() to register the attribute and command handlers */ -CHIP_ERROR EnergyEvseInit() +CHIP_ERROR EnergyEvseInit(chip::EndpointId endpointId) { CHIP_ERROR err; @@ -174,7 +91,7 @@ CHIP_ERROR EnergyEvseInit() /* Manufacturer may optionally not support all features, commands & attributes */ gEvseInstance = std::make_unique( - EndpointId(ENERGY_EVSE_ENDPOINT), *gEvseDelegate, + EndpointId(endpointId), *gEvseDelegate, BitMask(EnergyEvse::Feature::kChargingPreferences, EnergyEvse::Feature::kRfid), BitMask(EnergyEvse::OptionalAttributes::kSupportsUserMaximumChargingCurrent, EnergyEvse::OptionalAttributes::kSupportsRandomizationWindow, @@ -232,160 +149,6 @@ CHIP_ERROR EnergyEvseShutdown() return CHIP_NO_ERROR; } -/* - * @brief Creates a Delegate and Instance for PowerTopology clusters - * - * The Instance is a container around the Delegate, so - * create the Delegate first, then wrap it in the Instance - * Then call the Instance->Init() to register the attribute and command handlers - */ -CHIP_ERROR PowerTopologyInit() -{ - CHIP_ERROR err; - - if (gPTDelegate || gPTInstance) - { - ChipLogError(AppServer, "PowerTopology Instance or Delegate already exist."); - return CHIP_ERROR_INCORRECT_STATE; - } - - gPTDelegate = std::make_unique(); - if (!gPTDelegate) - { - ChipLogError(AppServer, "Failed to allocate memory for PowerTopology Delegate"); - return CHIP_ERROR_NO_MEMORY; - } - - gPTInstance = - std::make_unique(EndpointId(ENERGY_EVSE_ENDPOINT), *gPTDelegate, - BitMask(PowerTopology::Feature::kNodeTopology), - BitMask(0)); - - if (!gPTInstance) - { - ChipLogError(AppServer, "Failed to allocate memory for PowerTopology Instance"); - gPTDelegate.reset(); - return CHIP_ERROR_NO_MEMORY; - } - - err = gPTInstance->Init(); /* Register Attribute & Command handlers */ - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "Init failed on gPTInstance"); - gPTInstance.reset(); - gPTDelegate.reset(); - return err; - } - - return CHIP_NO_ERROR; -} - -CHIP_ERROR PowerTopologyShutdown() -{ - /* Do this in the order Instance first, then delegate - * Ensure we call the Instance->Shutdown to free attribute & command handlers first - */ - if (gPTInstance) - { - /* deregister attribute & command handlers */ - gPTInstance->Shutdown(); - gPTInstance.reset(); - } - - if (gPTDelegate) - { - gPTDelegate.reset(); - } - - return CHIP_NO_ERROR; -} - -/* - * @brief Creates a Delegate and Instance for Electrical Power/Energy Measurement clusters - * - * The Instance is a container around the Delegate, so - * create the Delegate first, then wrap it in the Instance - * Then call the Instance->Init() to register the attribute and command handlers - */ -CHIP_ERROR EnergyMeterInit() -{ - CHIP_ERROR err; - - if (gEPMDelegate || gEPMInstance) - { - ChipLogError(AppServer, "EPM Instance or Delegate already exist."); - return CHIP_ERROR_INCORRECT_STATE; - } - - gEPMDelegate = std::make_unique(); - if (!gEPMDelegate) - { - ChipLogError(AppServer, "Failed to allocate memory for EPM Delegate"); - return CHIP_ERROR_NO_MEMORY; - } - - /* Manufacturer may optionally not support all features, commands & attributes */ - /* Turning on all optional features and attributes for test certification purposes */ - gEPMInstance = std::make_unique( - EndpointId(ENERGY_EVSE_ENDPOINT), *gEPMDelegate, - BitMask( - ElectricalPowerMeasurement::Feature::kDirectCurrent, ElectricalPowerMeasurement::Feature::kAlternatingCurrent, - ElectricalPowerMeasurement::Feature::kPolyphasePower, ElectricalPowerMeasurement::Feature::kHarmonics, - ElectricalPowerMeasurement::Feature::kPowerQuality), - BitMask( - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRanges, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeVoltage, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeActiveCurrent, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactiveCurrent, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentCurrent, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactivePower, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentPower, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSVoltage, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSCurrent, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSPower, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeFrequency, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributePowerFactor, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeNeutralCurrent)); - - if (!gEPMInstance) - { - ChipLogError(AppServer, "Failed to allocate memory for EPM Instance"); - gEPMDelegate.reset(); - return CHIP_ERROR_NO_MEMORY; - } - - err = gEPMInstance->Init(); /* Register Attribute & Command handlers */ - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "Init failed on gEPMInstance"); - gEPMInstance.reset(); - gEPMDelegate.reset(); - return err; - } - - return CHIP_NO_ERROR; -} - -CHIP_ERROR EnergyMeterShutdown() -{ - /* Do this in the order Instance first, then delegate - * Ensure we call the Instance->Shutdown to free attribute & command handlers first - */ - if (gEPMInstance) - { - /* deregister attribute & command handlers */ - gEPMInstance->Shutdown(); - gEPMInstance.reset(); - } - - if (gEPMDelegate) - { - gEPMDelegate.reset(); - } - - return CHIP_NO_ERROR; -} - /* * @brief Creates a EVSEManufacturer class to hold the EVSE & DEM clusters * @@ -393,7 +156,8 @@ CHIP_ERROR EnergyMeterShutdown() * create the Delegate first, then wrap it in the Instance * Then call the Instance->Init() to register the attribute and command handlers */ -CHIP_ERROR EVSEManufacturerInit() +CHIP_ERROR EVSEManufacturerInit(ElectricalPowerMeasurementInstance & epmInstance, PowerTopologyInstance & ptInstance, + DeviceEnergyManagementManager & demInstance, DeviceEnergyManagementDelegate & demDelegate) { CHIP_ERROR err; @@ -404,15 +168,14 @@ CHIP_ERROR EVSEManufacturerInit() } /* Now create EVSEManufacturer */ - gEvseManufacturer = - std::make_unique(gEvseInstance.get(), gEPMInstance.get(), gPTInstance.get(), gDEMInstance.get()); + gEvseManufacturer = std::make_unique(gEvseInstance.get(), &epmInstance, &ptInstance, &demInstance); if (!gEvseManufacturer) { ChipLogError(AppServer, "Failed to allocate memory for EvseManufacturer"); return CHIP_ERROR_NO_MEMORY; } - gDEMDelegate.get()->SetDEMManufacturerDelegate(*gEvseManufacturer.get()); + demDelegate.SetDEMManufacturerDelegate(*gEvseManufacturer.get()); /* Call Manufacturer specific init */ err = gEvseManufacturer->Init(); @@ -437,104 +200,3 @@ CHIP_ERROR EVSEManufacturerShutdown() return CHIP_NO_ERROR; } - -void EvseApplicationInit() -{ - if (DeviceEnergyManagementInit() != CHIP_NO_ERROR) - { - return; - } - - if (EnergyEvseInit() != CHIP_NO_ERROR) - { - DeviceEnergyManagementShutdown(); - return; - } - - if (EnergyMeterInit() != CHIP_NO_ERROR) - { - DeviceEnergyManagementShutdown(); - EnergyEvseShutdown(); - return; - } - - if (PowerTopologyInit() != CHIP_NO_ERROR) - { - EVSEManufacturerShutdown(); - DeviceEnergyManagementShutdown(); - EnergyEvseShutdown(); - EnergyMeterShutdown(); - return; - } - - /* Do this last so that the instances for other clusters can be wrapped inside */ - if (EVSEManufacturerInit() != CHIP_NO_ERROR) - { - DeviceEnergyManagementShutdown(); - EnergyEvseShutdown(); - EnergyMeterShutdown(); - return; - } -} - -void EvseApplicationShutdown() -{ - ChipLogDetail(AppServer, "Energy Management App (EVSE): ApplicationShutdown()"); - - /* Shutdown in reverse order that they were created */ - EVSEManufacturerShutdown(); /* Free the EVSEManufacturer */ - PowerTopologyShutdown(); /* Free the PowerTopology */ - EnergyMeterShutdown(); /* Free the Energy Meter */ - EnergyEvseShutdown(); /* Free the EnergyEvse */ - DeviceEnergyManagementShutdown(); /* Free the DEM */ - - Clusters::DeviceEnergyManagementMode::Shutdown(); - Clusters::EnergyEvseMode::Shutdown(); -} - -void emberAfElectricalEnergyMeasurementClusterInitCallback(chip::EndpointId endpointId) -{ - VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. - VerifyOrDie(!gEEMAttrAccess); - - gEEMAttrAccess = std::make_unique( - BitMask( - ElectricalEnergyMeasurement::Feature::kImportedEnergy, ElectricalEnergyMeasurement::Feature::kExportedEnergy, - ElectricalEnergyMeasurement::Feature::kCumulativeEnergy, ElectricalEnergyMeasurement::Feature::kPeriodicEnergy), - BitMask( - ElectricalEnergyMeasurement::OptionalAttributes::kOptionalAttributeCumulativeEnergyReset)); - - // Create an accuracy entry which is between +/-0.5 and +/- 5% across the range of all possible energy readings - ElectricalEnergyMeasurement::Structs::MeasurementAccuracyRangeStruct::Type energyAccuracyRanges[] = { - { .rangeMin = 0, - .rangeMax = 1'000'000'000'000'000, // 1 million Mwh - .percentMax = MakeOptional(static_cast(500)), - .percentMin = MakeOptional(static_cast(50)) } - }; - - ElectricalEnergyMeasurement::Structs::MeasurementAccuracyStruct::Type accuracy = { - .measurementType = MeasurementTypeEnum::kElectricalEnergy, - .measured = true, - .minMeasuredValue = 0, - .maxMeasuredValue = 1'000'000'000'000'000, // 1 million Mwh - .accuracyRanges = - DataModel::List(energyAccuracyRanges) - }; - - // Example of setting CumulativeEnergyReset structure - for now set these to 0 - // but the manufacturer may want to store these in non volatile storage for timestamp (based on epoch_s) - ElectricalEnergyMeasurement::Structs::CumulativeEnergyResetStruct::Type resetStruct = { - .importedResetTimestamp = MakeOptional(MakeNullable(static_cast(0))), - .exportedResetTimestamp = MakeOptional(MakeNullable(static_cast(0))), - .importedResetSystime = MakeOptional(MakeNullable(static_cast(0))), - .exportedResetSystime = MakeOptional(MakeNullable(static_cast(0))), - }; - - if (gEEMAttrAccess) - { - gEEMAttrAccess->Init(); - - SetMeasurementAccuracy(endpointId, accuracy); - SetCumulativeReset(endpointId, MakeOptional(resetStruct)); - } -} diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index a3c2b9f58b5485..7bd9cb448e0c8b 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -2398,6 +2398,361 @@ provisional cluster DeviceEnergyManagementMode = 159 { command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } +/** An interface for configuring and controlling the functionality of a thermostat. */ +cluster Thermostat = 513 { + revision 7; + + enum ACCapacityFormatEnum : enum8 { + kBTUh = 0; + } + + enum ACCompressorTypeEnum : enum8 { + kUnknown = 0; + kT1 = 1; + kT2 = 2; + kT3 = 3; + } + + enum ACLouverPositionEnum : enum8 { + kClosed = 1; + kOpen = 2; + kQuarter = 3; + kHalf = 4; + kThreeQuarters = 5; + } + + enum ACRefrigerantTypeEnum : enum8 { + kUnknown = 0; + kR22 = 1; + kR410a = 2; + kR407c = 3; + } + + enum ACTypeEnum : enum8 { + kUnknown = 0; + kCoolingFixed = 1; + kHeatPumpFixed = 2; + kCoolingInverter = 3; + kHeatPumpInverter = 4; + } + + enum ControlSequenceOfOperationEnum : enum8 { + kCoolingOnly = 0; + kCoolingWithReheat = 1; + kHeatingOnly = 2; + kHeatingWithReheat = 3; + kCoolingAndHeating = 4; + kCoolingAndHeatingWithReheat = 5; + } + + enum PresetScenarioEnum : enum8 { + kOccupied = 1; + kUnoccupied = 2; + kSleep = 3; + kWake = 4; + kVacation = 5; + kGoingToSleep = 6; + kUserDefined = 254; + } + + enum SetpointChangeSourceEnum : enum8 { + kManual = 0; + kSchedule = 1; + kExternal = 2; + } + + enum SetpointRaiseLowerModeEnum : enum8 { + kHeat = 0; + kCool = 1; + kBoth = 2; + } + + enum StartOfWeekEnum : enum8 { + kSunday = 0; + kMonday = 1; + kTuesday = 2; + kWednesday = 3; + kThursday = 4; + kFriday = 5; + kSaturday = 6; + } + + enum SystemModeEnum : enum8 { + kOff = 0; + kAuto = 1; + kCool = 3; + kHeat = 4; + kEmergencyHeat = 5; + kPrecooling = 6; + kFanOnly = 7; + kDry = 8; + kSleep = 9; + } + + enum TemperatureSetpointHoldEnum : enum8 { + kSetpointHoldOff = 0; + kSetpointHoldOn = 1; + } + + enum ThermostatRunningModeEnum : enum8 { + kOff = 0; + kCool = 3; + kHeat = 4; + } + + bitmap ACErrorCodeBitmap : bitmap32 { + kCompressorFail = 0x1; + kRoomSensorFail = 0x2; + kOutdoorSensorFail = 0x4; + kCoilSensorFail = 0x8; + kFanFail = 0x10; + } + + bitmap Feature : bitmap32 { + kHeating = 0x1; + kCooling = 0x2; + kOccupancy = 0x4; + kScheduleConfiguration = 0x8; + kSetback = 0x10; + kAutoMode = 0x20; + kLocalTemperatureNotExposed = 0x40; + kMatterScheduleConfiguration = 0x80; + kPresets = 0x100; + } + + bitmap HVACSystemTypeBitmap : bitmap8 { + kCoolingStage = 0x3; + kHeatingStage = 0xC; + kHeatingIsHeatPump = 0x10; + kHeatingUsesFuel = 0x20; + } + + bitmap OccupancyBitmap : bitmap8 { + kOccupied = 0x1; + } + + bitmap PresetTypeFeaturesBitmap : bitmap16 { + kAutomatic = 0x1; + kSupportsNames = 0x2; + } + + bitmap ProgrammingOperationModeBitmap : bitmap8 { + kScheduleActive = 0x1; + kAutoRecovery = 0x2; + kEconomy = 0x4; + } + + bitmap RelayStateBitmap : bitmap16 { + kHeat = 0x1; + kCool = 0x2; + kFan = 0x4; + kHeatStage2 = 0x8; + kCoolStage2 = 0x10; + kFanStage2 = 0x20; + kFanStage3 = 0x40; + } + + bitmap RemoteSensingBitmap : bitmap8 { + kLocalTemperature = 0x1; + kOutdoorTemperature = 0x2; + kOccupancy = 0x4; + } + + bitmap ScheduleDayOfWeekBitmap : bitmap8 { + kSunday = 0x1; + kMonday = 0x2; + kTuesday = 0x4; + kWednesday = 0x8; + kThursday = 0x10; + kFriday = 0x20; + kSaturday = 0x40; + kAway = 0x80; + } + + bitmap ScheduleModeBitmap : bitmap8 { + kHeatSetpointPresent = 0x1; + kCoolSetpointPresent = 0x2; + } + + bitmap ScheduleTypeFeaturesBitmap : bitmap16 { + kSupportsPresets = 0x1; + kSupportsSetpoints = 0x2; + kSupportsNames = 0x4; + kSupportsOff = 0x8; + } + + struct ScheduleTransitionStruct { + ScheduleDayOfWeekBitmap dayOfWeek = 0; + int16u transitionTime = 1; + optional octet_string<16> presetHandle = 2; + optional SystemModeEnum systemMode = 3; + optional temperature coolingSetpoint = 4; + optional temperature heatingSetpoint = 5; + } + + struct ScheduleStruct { + nullable octet_string<16> scheduleHandle = 0; + SystemModeEnum systemMode = 1; + optional char_string<64> name = 2; + optional octet_string<16> presetHandle = 3; + ScheduleTransitionStruct transitions[] = 4; + nullable boolean builtIn = 5; + } + + struct PresetStruct { + nullable octet_string<16> presetHandle = 0; + PresetScenarioEnum presetScenario = 1; + optional nullable char_string<64> name = 2; + optional temperature coolingSetpoint = 3; + optional temperature heatingSetpoint = 4; + nullable boolean builtIn = 5; + } + + struct PresetTypeStruct { + PresetScenarioEnum presetScenario = 0; + int8u numberOfPresets = 1; + PresetTypeFeaturesBitmap presetTypeFeatures = 2; + } + + struct ScheduleTypeStruct { + SystemModeEnum systemMode = 0; + int8u numberOfSchedules = 1; + ScheduleTypeFeaturesBitmap scheduleTypeFeatures = 2; + } + + struct WeeklyScheduleTransitionStruct { + int16u transitionTime = 0; + nullable temperature heatSetpoint = 1; + nullable temperature coolSetpoint = 2; + } + + readonly attribute nullable temperature localTemperature = 0; + readonly attribute optional nullable temperature outdoorTemperature = 1; + readonly attribute optional OccupancyBitmap occupancy = 2; + readonly attribute optional temperature absMinHeatSetpointLimit = 3; + readonly attribute optional temperature absMaxHeatSetpointLimit = 4; + readonly attribute optional temperature absMinCoolSetpointLimit = 5; + readonly attribute optional temperature absMaxCoolSetpointLimit = 6; + readonly attribute optional int8u PICoolingDemand = 7; + readonly attribute optional int8u PIHeatingDemand = 8; + attribute access(write: manage) optional HVACSystemTypeBitmap HVACSystemTypeConfiguration = 9; + attribute access(write: manage) optional int8s localTemperatureCalibration = 16; + attribute optional temperature occupiedCoolingSetpoint = 17; + attribute optional temperature occupiedHeatingSetpoint = 18; + attribute optional temperature unoccupiedCoolingSetpoint = 19; + attribute optional temperature unoccupiedHeatingSetpoint = 20; + attribute access(write: manage) optional temperature minHeatSetpointLimit = 21; + attribute access(write: manage) optional temperature maxHeatSetpointLimit = 22; + attribute access(write: manage) optional temperature minCoolSetpointLimit = 23; + attribute access(write: manage) optional temperature maxCoolSetpointLimit = 24; + attribute access(write: manage) optional int8s minSetpointDeadBand = 25; + attribute access(write: manage) optional RemoteSensingBitmap remoteSensing = 26; + attribute access(write: manage) ControlSequenceOfOperationEnum controlSequenceOfOperation = 27; + attribute access(write: manage) SystemModeEnum systemMode = 28; + readonly attribute optional ThermostatRunningModeEnum thermostatRunningMode = 30; + readonly attribute optional StartOfWeekEnum startOfWeek = 32; + readonly attribute optional int8u numberOfWeeklyTransitions = 33; + readonly attribute optional int8u numberOfDailyTransitions = 34; + attribute access(write: manage) optional TemperatureSetpointHoldEnum temperatureSetpointHold = 35; + attribute access(write: manage) optional nullable int16u temperatureSetpointHoldDuration = 36; + attribute access(write: manage) optional ProgrammingOperationModeBitmap thermostatProgrammingOperationMode = 37; + readonly attribute optional RelayStateBitmap thermostatRunningState = 41; + readonly attribute optional SetpointChangeSourceEnum setpointChangeSource = 48; + readonly attribute optional nullable int16s setpointChangeAmount = 49; + readonly attribute optional epoch_s setpointChangeSourceTimestamp = 50; + attribute access(write: manage) optional nullable int8u occupiedSetback = 52; + readonly attribute optional nullable int8u occupiedSetbackMin = 53; + readonly attribute optional nullable int8u occupiedSetbackMax = 54; + attribute access(write: manage) optional nullable int8u unoccupiedSetback = 55; + readonly attribute optional nullable int8u unoccupiedSetbackMin = 56; + readonly attribute optional nullable int8u unoccupiedSetbackMax = 57; + attribute access(write: manage) optional int8u emergencyHeatDelta = 58; + attribute access(write: manage) optional ACTypeEnum ACType = 64; + attribute access(write: manage) optional int16u ACCapacity = 65; + attribute access(write: manage) optional ACRefrigerantTypeEnum ACRefrigerantType = 66; + attribute access(write: manage) optional ACCompressorTypeEnum ACCompressorType = 67; + attribute access(write: manage) optional ACErrorCodeBitmap ACErrorCode = 68; + attribute access(write: manage) optional ACLouverPositionEnum ACLouverPosition = 69; + readonly attribute optional nullable temperature ACCoilTemperature = 70; + attribute access(write: manage) optional ACCapacityFormatEnum ACCapacityformat = 71; + readonly attribute optional PresetTypeStruct presetTypes[] = 72; + readonly attribute optional ScheduleTypeStruct scheduleTypes[] = 73; + readonly attribute optional int8u numberOfPresets = 74; + readonly attribute optional int8u numberOfSchedules = 75; + readonly attribute optional int8u numberOfScheduleTransitions = 76; + readonly attribute optional nullable int8u numberOfScheduleTransitionPerDay = 77; + readonly attribute optional nullable octet_string<16> activePresetHandle = 78; + readonly attribute optional nullable octet_string<16> activeScheduleHandle = 79; + attribute access(write: manage) optional PresetStruct presets[] = 80; + attribute access(write: manage) optional ScheduleStruct schedules[] = 81; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 82; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SetpointRaiseLowerRequest { + SetpointRaiseLowerModeEnum mode = 0; + int8s amount = 1; + } + + response struct GetWeeklyScheduleResponse = 0 { + int8u numberOfTransitionsForSequence = 0; + ScheduleDayOfWeekBitmap dayOfWeekForSequence = 1; + ScheduleModeBitmap modeForSequence = 2; + WeeklyScheduleTransitionStruct transitions[] = 3; + } + + request struct SetWeeklyScheduleRequest { + int8u numberOfTransitionsForSequence = 0; + ScheduleDayOfWeekBitmap dayOfWeekForSequence = 1; + ScheduleModeBitmap modeForSequence = 2; + WeeklyScheduleTransitionStruct transitions[] = 3; + } + + request struct GetWeeklyScheduleRequest { + ScheduleDayOfWeekBitmap daysToReturn = 0; + ScheduleModeBitmap modeToReturn = 1; + } + + request struct SetActiveScheduleRequestRequest { + octet_string<16> scheduleHandle = 0; + } + + request struct SetActivePresetRequestRequest { + nullable octet_string<16> presetHandle = 0; + } + + response struct AtomicResponse = 253 { + status statusCode = 0; + AtomicAttributeStatusStruct attributeStatus[] = 1; + optional int16u timeout = 2; + } + + request struct AtomicRequestRequest { + AtomicRequestTypeEnum requestType = 0; + attrib_id attributeRequests[] = 1; + optional int16u timeout = 2; + } + + /** Upon receipt, the attributes for the indicated setpoint(s) SHALL have the amount specified in the Amount field added to them. */ + command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; + /** This command is used to update the thermostat weekly setpoint schedule from a management system. */ + command access(invoke: manage) SetWeeklySchedule(SetWeeklyScheduleRequest): DefaultSuccess = 1; + /** The Current Weekly Schedule Command is sent from the server in response to the Get Weekly Schedule Command. */ + command GetWeeklySchedule(GetWeeklyScheduleRequest): GetWeeklyScheduleResponse = 2; + /** This command is used to clear the weekly schedule. */ + command access(invoke: manage) ClearWeeklySchedule(): DefaultSuccess = 3; + /** Upon receipt, if the Schedules attribute contains a ScheduleStruct whose ScheduleHandle field matches the value of the ScheduleHandle field, the server SHALL set the thermostat's ActiveScheduleHandle attribute to the value of the ScheduleHandle field. */ + command SetActiveScheduleRequest(SetActiveScheduleRequestRequest): DefaultSuccess = 5; + /** ID */ + command SetActivePresetRequest(SetActivePresetRequestRequest): DefaultSuccess = 6; + /** Begins, Commits or Cancels an atomic write */ + command access(invoke: manage) AtomicRequest(AtomicRequestRequest): AtomicResponse = 254; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -2677,23 +3032,6 @@ endpoint 1 { ram attribute clusterRevision default = 1; } - server cluster WaterHeaterManagement { - callback attribute heaterTypes; - callback attribute heatDemand; - callback attribute tankVolume; - callback attribute estimatedHeatRequired; - callback attribute tankPercentage; - callback attribute boostState; - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute attributeList; - callback attribute featureMap; - callback attribute clusterRevision; - - handle command Boost; - handle command CancelBoost; - } - server cluster DeviceEnergyManagement { emits event PowerAdjustStart; emits event PowerAdjustEnd; @@ -2784,7 +3122,7 @@ endpoint 1 { handle command ChangeToModeResponse; } - server cluster WaterHeaterMode { + server cluster DeviceEnergyManagementMode { callback attribute supportedModes; callback attribute currentMode; callback attribute generatedCommandList; @@ -2796,8 +3134,119 @@ endpoint 1 { handle command ChangeToMode; handle command ChangeToModeResponse; } +} +endpoint 2 { + device type ma_electricalsensor = 1296, version 1; + device type ma_waterheater = 1295, version 1; - server cluster DeviceEnergyManagementMode { + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster ElectricalPowerMeasurement { + callback attribute powerMode; + callback attribute numberOfMeasurementTypes; + callback attribute accuracy; + callback attribute ranges; + callback attribute voltage; + callback attribute activeCurrent; + callback attribute reactiveCurrent; + callback attribute apparentCurrent; + callback attribute activePower; + callback attribute reactivePower; + callback attribute apparentPower; + callback attribute RMSVoltage; + callback attribute RMSCurrent; + callback attribute RMSPower; + callback attribute frequency; + callback attribute harmonicCurrents; + callback attribute harmonicPhases; + callback attribute powerFactor; + callback attribute neutralCurrent; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster ElectricalEnergyMeasurement { + callback attribute accuracy; + callback attribute cumulativeEnergyImported; + callback attribute cumulativeEnergyExported; + callback attribute periodicEnergyImported; + callback attribute periodicEnergyExported; + callback attribute cumulativeEnergyReset; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster WaterHeaterManagement { + callback attribute heaterTypes; + callback attribute heatDemand; + callback attribute tankVolume; + callback attribute estimatedHeatRequired; + callback attribute tankPercentage; + callback attribute boostState; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command Boost; + handle command CancelBoost; + } + + server cluster DeviceEnergyManagement { + callback attribute ESAType; + callback attribute ESACanGenerate; + callback attribute ESAState; + callback attribute absMinPower; + callback attribute absMaxPower; + callback attribute powerAdjustmentCapability; + callback attribute forecast; + callback attribute optOutState; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 4; + } + + server cluster PowerTopology { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster WaterHeaterMode { callback attribute supportedModes; callback attribute currentMode; callback attribute generatedCommandList; @@ -2809,6 +3258,29 @@ endpoint 1 { handle command ChangeToMode; handle command ChangeToModeResponse; } + + server cluster DeviceEnergyManagementMode { + callback attribute supportedModes; + callback attribute currentMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster Thermostat { + ram attribute localTemperature; + ram attribute controlSequenceOfOperation default = 4; + ram attribute systemMode default = 1; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 7; + + handle command SetpointRaiseLower; + } } diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.zap b/examples/energy-management-app/energy-management-common/energy-management-app.zap index 17a539dbf13348..56b87970e7fc9f 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.zap +++ b/examples/energy-management-app/energy-management-common/energy-management-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 103, + "featureLevel": 104, "creator": "zap", "keyValuePairs": [ { @@ -41,14 +41,16 @@ "code": 22, "profileId": 259, "label": "MA-rootdevice", - "name": "MA-rootdevice" + "name": "MA-rootdevice", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 22, "profileId": 259, "label": "MA-rootdevice", - "name": "MA-rootdevice" + "name": "MA-rootdevice", + "deviceTypeOrder": 0 } ], "deviceVersions": [ @@ -2714,20 +2716,23 @@ "code": 1292, "profileId": 259, "label": "Energy EVSE", - "name": "Energy EVSE" + "name": "Energy EVSE", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 1292, "profileId": 259, "label": "Energy EVSE", - "name": "Energy EVSE" + "name": "Energy EVSE", + "deviceTypeOrder": 0 }, { "code": 1296, "profileId": 259, "label": "MA-electricalsensor", - "name": "MA-electricalsensor" + "name": "MA-electricalsensor", + "deviceTypeOrder": 1 } ], "deviceVersions": [ @@ -3696,227 +3701,6 @@ } ] }, - { - "name": "Water Heater Management", - "code": 148, - "mfgCode": null, - "define": "WATER_HEATER_MANAGEMENT_CLUSTER", - "side": "server", - "enabled": 1, - "apiMaturity": "provisional", - "commands": [ - { - "name": "Boost", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "CancelBoost", - "code": 1, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "HeaterTypes", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "WaterHeaterHeatSourceBitmap", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "HeatDemand", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "WaterHeaterHeatSourceBitmap", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "TankVolume", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EstimatedHeatRequired", - "code": 3, - "mfgCode": null, - "side": "server", - "type": "energy_mwh", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "TankPercentage", - "code": 4, - "mfgCode": null, - "side": "server", - "type": "percent", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "BoostState", - "code": 5, - "mfgCode": null, - "side": "server", - "type": "BoostStateEnum", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - } - ] - }, { "name": "Device Energy Management", "code": 152, @@ -4999,12 +4783,13 @@ ] }, { - "name": "Water Heater Mode", - "code": 158, + "name": "Device Energy Management Mode", + "code": 159, "mfgCode": null, - "define": "WATER_HEATER_MODE_CLUSTER", + "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "provisional", "commands": [ { "name": "ChangeToMode", @@ -5153,33 +4938,1703 @@ "reportableChange": 0 } ] + } + ] + }, + { + "id": 3, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 1295, + "profileId": 259, + "label": "MA-waterheater", + "name": "MA-waterheater", + "deviceTypeOrder": 0 + }, + "deviceTypes": [ + { + "code": 1295, + "profileId": 259, + "label": "MA-waterheater", + "name": "MA-waterheater", + "deviceTypeOrder": 0 }, { - "name": "Device Energy Management Mode", - "code": 159, - "mfgCode": null, - "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", - "side": "server", - "enabled": 1, - "apiMaturity": "provisional", - "commands": [ - { - "name": "ChangeToMode", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, + "code": 1296, + "profileId": 259, + "label": "MA-electricalsensor", + "name": "MA-electricalsensor", + "deviceTypeOrder": 1 + } + ], + "deviceVersions": [ + 1, + 1 + ], + "deviceIdentifiers": [ + 1295, + 1296 + ], + "deviceTypeName": "MA-waterheater", + "deviceTypeCode": 1295, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Electrical Power Measurement", + "code": 144, + "mfgCode": null, + "define": "ELECTRICAL_POWER_MEASUREMENT_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "PowerMode", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerModeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfMeasurementTypes", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Accuracy", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Ranges", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Voltage", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "voltage_mv", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveCurrent", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ReactiveCurrent", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ApparentCurrent", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActivePower", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ReactivePower", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ApparentPower", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RMSVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "voltage_mv", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RMSCurrent", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RMSPower", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Frequency", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int64s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HarmonicCurrents", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HarmonicPhases", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PowerFactor", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int64s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NeutralCurrent", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Electrical Energy Measurement", + "code": 145, + "mfgCode": null, + "define": "ELECTRICAL_ENERGY_MEASUREMENT_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Accuracy", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "MeasurementAccuracyStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CumulativeEnergyImported", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "EnergyMeasurementStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CumulativeEnergyExported", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "EnergyMeasurementStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PeriodicEnergyImported", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "EnergyMeasurementStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PeriodicEnergyExported", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "EnergyMeasurementStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CumulativeEnergyReset", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "CumulativeEnergyResetStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Water Heater Management", + "code": 148, + "mfgCode": null, + "define": "WATER_HEATER_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "Boost", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CancelBoost", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "HeaterTypes", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "WaterHeaterHeatSourceBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HeatDemand", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "WaterHeaterHeatSourceBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TankVolume", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EstimatedHeatRequired", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "energy_mwh", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TankPercentage", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "percent", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BoostState", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "BoostStateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Device Energy Management", + "code": 152, + "mfgCode": null, + "define": "DEVICE_ENERGY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "attributes": [ + { + "name": "ESAType", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "ESATypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ESACanGenerate", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ESAState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "ESAStateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AbsMinPower", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AbsMaxPower", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PowerAdjustmentCapability", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "PowerAdjustCapabilityStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Forecast", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "ForecastStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OptOutState", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "OptOutStateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Power Topology", + "code": 156, + "mfgCode": null, + "define": "POWER_TOPOLOGY_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Water Heater Mode", + "code": 158, + "mfgCode": null, + "define": "WATER_HEATER_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SupportedModes", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentMode", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { - "name": "ChangeToModeResponse", - "code": 1, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 } - ], + ] + }, + { + "name": "Device Energy Management Mode", + "code": 159, + "mfgCode": null, + "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", "attributes": [ { "name": "SupportedModes", @@ -5310,6 +6765,170 @@ "reportableChange": 0 } ] + }, + { + "name": "Thermostat", + "code": 513, + "mfgCode": null, + "define": "THERMOSTAT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SetpointRaiseLower", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "LocalTemperature", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "temperature", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ControlSequenceOfOperation", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "ControlSequenceOfOperationEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SystemMode", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "SystemModeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "7", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] } ] } @@ -5330,6 +6949,14 @@ "endpointId": 1, "networkId": 0, "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 2, + "profileId": 259, + "endpointId": 2, + "networkId": 0, + "parentEndpointIdentifier": 0 } ] } \ No newline at end of file diff --git a/examples/energy-management-app/energy-management-common/water-heater/include/WaterHeaterMain.h b/examples/energy-management-app/energy-management-common/energy-reporting/include/ElectricalSensorInit.h similarity index 55% rename from examples/energy-management-app/energy-management-common/water-heater/include/WaterHeaterMain.h rename to examples/energy-management-app/energy-management-common/energy-reporting/include/ElectricalSensorInit.h index 819ff9e4d160ca..6e0c38bb7d85bb 100644 --- a/examples/energy-management-app/energy-management-common/water-heater/include/WaterHeaterMain.h +++ b/examples/energy-management-app/energy-management-common/energy-reporting/include/ElectricalSensorInit.h @@ -18,15 +18,16 @@ #pragma once -namespace chip { -namespace app { -namespace Clusters { -namespace WaterHeaterManagement { +#include +#include +#include +#include -void FullWhmApplicationInit(); -void FullWhmApplicationShutdown(); +chip::app::Clusters::PowerTopology::PowerTopologyInstance * GetPTInstance(); +chip::app::Clusters::ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * GetEPMInstance(); -} // namespace WaterHeaterManagement -} // namespace Clusters -} // namespace app -} // namespace chip +CHIP_ERROR PowerTopologyInit(chip::EndpointId endpointId); +CHIP_ERROR PowerTopologyShutdown(); + +CHIP_ERROR ElectricalPowerMeasurementInit(chip::EndpointId endpointId); +CHIP_ERROR ElectricalPowerMeasurementShutdown(); diff --git a/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp b/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp index bffe3c900d29af..8fab0e2a7dbe07 100644 --- a/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp +++ b/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp @@ -16,8 +16,8 @@ * limitations under the License. */ -#include #include +#include #include #include diff --git a/examples/energy-management-app/energy-management-common/water-heater/include/WhmMain.h b/examples/energy-management-app/energy-management-common/water-heater/include/WhmMain.h index 34f04d8cbb6b8f..d0fa8d97f5cc14 100644 --- a/examples/energy-management-app/energy-management-common/water-heater/include/WhmMain.h +++ b/examples/energy-management-app/energy-management-common/water-heater/include/WhmMain.h @@ -25,7 +25,7 @@ namespace app { namespace Clusters { namespace WaterHeaterManagement { -CHIP_ERROR WhmApplicationInit(); +CHIP_ERROR WhmApplicationInit(EndpointId endpointId); CHIP_ERROR WhmApplicationShutdown(); } // namespace WaterHeaterManagement diff --git a/examples/energy-management-app/energy-management-common/water-heater/src/WaterHeaterMain.cpp b/examples/energy-management-app/energy-management-common/water-heater/src/WaterHeaterMain.cpp deleted file mode 100644 index 0c8e44ac7cb248..00000000000000 --- a/examples/energy-management-app/energy-management-common/water-heater/src/WaterHeaterMain.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * 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. - */ - -#include "EnergyManagementAppCmdLineOptions.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace chip { -namespace app { -namespace Clusters { -namespace WaterHeaterManagement { - -void FullWhmApplicationInit() -{ - ReturnOnFailure(WhmApplicationInit()); - - if (DeviceEnergyManagementInit() != CHIP_NO_ERROR) - { - WhmApplicationShutdown(); - return; - } - - if (EnergyMeterInit() != CHIP_NO_ERROR) - { - DeviceEnergyManagementShutdown(); - WhmApplicationShutdown(); - return; - } - - if (PowerTopologyInit() != CHIP_NO_ERROR) - { - EnergyMeterShutdown(); - DeviceEnergyManagementShutdown(); - WhmApplicationShutdown(); - return; - } - - /* For Device Energy Management we need the ESA to be Online and ready to accept commands */ - - GetDEMDelegate()->SetESAState(ESAStateEnum::kOnline); - GetDEMDelegate()->SetESAType(ESATypeEnum::kWaterHeating); - GetDEMDelegate()->SetDEMManufacturerDelegate(*GetWhmManufacturer()); - - // Set the abs min and max power - GetDEMDelegate()->SetAbsMinPower(1200000); // 1.2KW - GetDEMDelegate()->SetAbsMaxPower(7600000); // 7.6KW -} - -void FullWhmApplicationShutdown() -{ - ChipLogDetail(AppServer, "Energy Management App (WaterHeater): ApplicationShutdown()"); - - /* Shutdown in reverse order that they were created */ - PowerTopologyShutdown(); /* Free the PowerTopology */ - EnergyMeterShutdown(); /* Free the Energy Meter */ - DeviceEnergyManagementShutdown(); /* Free the DEM */ - WhmApplicationShutdown(); - - Clusters::DeviceEnergyManagementMode::Shutdown(); - Clusters::WaterHeaterMode::Shutdown(); -} - -} // namespace WaterHeaterManagement -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/water-heater/src/WhmMain.cpp b/examples/energy-management-app/energy-management-common/water-heater/src/WhmMain.cpp index 038e332bd31aff..b53da3c7d69251 100644 --- a/examples/energy-management-app/energy-management-common/water-heater/src/WhmMain.cpp +++ b/examples/energy-management-app/energy-management-common/water-heater/src/WhmMain.cpp @@ -24,8 +24,6 @@ #include #include -static constexpr int WHM_ENDPOINT = 1; - using namespace chip; using namespace chip::app; using namespace chip::app::DataModel; @@ -53,7 +51,7 @@ WhmManufacturer * GetWhmManufacturer() * create the Delegate first, then wrap it in the Instance * Then call the Instance->Init() to register the attribute and command handlers */ -CHIP_ERROR WhmInit() +CHIP_ERROR WhmInit(EndpointId endpointId) { CHIP_ERROR err; @@ -63,7 +61,7 @@ CHIP_ERROR WhmInit() return CHIP_ERROR_INCORRECT_STATE; } - gWhmDelegate = std::make_unique(WHM_ENDPOINT); + gWhmDelegate = std::make_unique(endpointId); if (!gWhmDelegate) { ChipLogError(AppServer, "Failed to allocate memory for WaterHeaterManagementDelegate"); @@ -72,7 +70,7 @@ CHIP_ERROR WhmInit() /* Manufacturer may optionally not support all features, commands & attributes */ gWhmInstance = std::make_unique( - EndpointId(WHM_ENDPOINT), *gWhmDelegate, BitMask(Feature::kEnergyManagement, Feature::kTankPercent)); + EndpointId(endpointId), *gWhmDelegate, BitMask(Feature::kEnergyManagement, Feature::kTankPercent)); if (!gWhmInstance) { ChipLogError(AppServer, "Failed to allocate memory for WaterHeaterManagementInstance"); @@ -167,9 +165,9 @@ CHIP_ERROR WhmManufacturerShutdown() return CHIP_NO_ERROR; } -CHIP_ERROR WhmApplicationInit() +CHIP_ERROR WhmApplicationInit(EndpointId endpointId) { - ReturnErrorOnFailure(WhmInit()); + ReturnErrorOnFailure(WhmInit(endpointId)); /* Do this last so that the instances for other clusters can be wrapped inside */ ReturnErrorOnFailure(WhmManufacturerInit()); diff --git a/examples/energy-management-app/energy-management-common/water-heater/src/water-heater-mode.cpp b/examples/energy-management-app/energy-management-common/water-heater/src/water-heater-mode.cpp index 9c4121fb70d668..a22ee7254c3b8e 100755 --- a/examples/energy-management-app/energy-management-common/water-heater/src/water-heater-mode.cpp +++ b/examples/energy-management-app/energy-management-common/water-heater/src/water-heater-mode.cpp @@ -24,9 +24,12 @@ using chip::Protocols::InteractionModel::Status; template using List = chip::app::DataModel::List; using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; +namespace { -static ExampleWaterHeaterModeDelegate * gWaterHeaterModeDelegate = nullptr; -static ModeBase::Instance * gWaterHeaterModeInstance = nullptr; +ExampleWaterHeaterModeDelegate * gWaterHeaterModeDelegate = nullptr; +ModeBase::Instance * gWaterHeaterModeInstance = nullptr; + +} // namespace CHIP_ERROR ExampleWaterHeaterModeDelegate::Init() { diff --git a/examples/energy-management-app/esp32/main/CMakeLists.txt b/examples/energy-management-app/esp32/main/CMakeLists.txt index e5459616238d3d..f1b73211ccab2e 100644 --- a/examples/energy-management-app/esp32/main/CMakeLists.txt +++ b/examples/energy-management-app/esp32/main/CMakeLists.txt @@ -58,6 +58,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/identify-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/localization-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-format-localization-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thermostat-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/energy-evse-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/device-energy-management-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" diff --git a/examples/energy-management-app/esp32/main/main.cpp b/examples/energy-management-app/esp32/main/main.cpp index d235fa4291ac98..9e1dff9b43b745 100644 --- a/examples/energy-management-app/esp32/main/main.cpp +++ b/examples/energy-management-app/esp32/main/main.cpp @@ -17,15 +17,8 @@ #include "DeviceCallbacks.h" -#if CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE -#include -#endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE - -#if CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE -#include -#endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE - #include "esp_log.h" +#include #include #include #include @@ -43,8 +36,10 @@ #include "nvs_flash.h" #include "shell_extension/launch.h" #include "shell_extension/openthread_cli_register.h" +#include #include #include +#include #include #include #include @@ -80,6 +75,7 @@ using namespace ::chip::Credentials; using namespace ::chip::DeviceManager; using namespace ::chip::DeviceLayer; using namespace chip::app::Clusters::WaterHeaterManagement; +using namespace chip::app::Clusters::DeviceEnergyManagement; #if CONFIG_ENABLE_ESP_INSIGHTS_TRACE extern const char insights_auth_key_start[] asm("_binary_insights_auth_key_txt_start"); @@ -92,6 +88,10 @@ static AppDeviceCallbacks EchoCallbacks; static DeviceCallbacksDelegate sAppDeviceCallbacksDelegate; namespace { + +constexpr chip::EndpointId kEvseEndpoint = 1; +constexpr chip::EndpointId kWaterHeaterEndpoint = 2; + #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider; #endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER @@ -156,15 +156,29 @@ chip::BitMask GetFeatureMapFromCmdLine() #error Cannot define CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE and CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE #endif +EndpointId GetEnergyDeviceEndpointId() +{ +#if defined(CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE) + return kWaterHeaterEndpoint; +#else + return kEvseEndpoint; +#endif +} + void ApplicationInit() { ESP_LOGD(TAG, "Energy Management App: ApplicationInit()"); #if CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE + EvseApplicationInit(); + // Disable Water Heater Endpoint + emberAfEndpointEnableDisable(kWaterHeaterEndpoint, false); #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #if CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE - FullWhmApplicationInit(); + WaterHeaterApplicationInit(); + // Disable EVSE Endpoint + emberAfEndpointEnableDisable(kEvseEndpoint, false); #endif // CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE } @@ -177,7 +191,7 @@ void ApplicationShutdown() #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #if CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE - FullWhmApplicationShutdown(); + WaterHeaterApplicationShutdown(); #endif // CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE } diff --git a/examples/energy-management-app/linux/BUILD.gn b/examples/energy-management-app/linux/BUILD.gn index a9d41a1e76d033..e742c05d692296 100644 --- a/examples/energy-management-app/linux/BUILD.gn +++ b/examples/energy-management-app/linux/BUILD.gn @@ -34,6 +34,7 @@ config("includes") { executable("chip-energy-management-app") { sources = [ + "${chip_root}/examples/energy-management-app/energy-management-common/common/src/EnergyManagementAppCommonMain.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/common/src/EnergyTimeUtils.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMTestEventTriggers.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementDelegateImpl.cpp", @@ -51,7 +52,6 @@ executable("chip-energy-management-app") { "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/EnergyReportingEventTriggers.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/PowerTopologyDelegate.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WaterHeaterMain.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WhmDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WhmInstance.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WhmMain.cpp", diff --git a/examples/energy-management-app/linux/main.cpp b/examples/energy-management-app/linux/main.cpp index 7a6312538ada45..c6fdd2b98a2a91 100644 --- a/examples/energy-management-app/linux/main.cpp +++ b/examples/energy-management-app/linux/main.cpp @@ -18,8 +18,10 @@ #include #include -#include +#include +#include #include +#include #include using namespace chip; @@ -39,10 +41,12 @@ static bool EnergyAppOptionHandler(const char * aProgram, chip::ArgParser::Optio constexpr uint16_t kOptionApplication = 0xffd0; constexpr uint16_t kOptionFeatureMap = 0xffd1; -constexpr const char * kEvseApp = "evse"; -constexpr const char * kWhmApp = "water-heater"; - -constexpr const char * kValidApps[] = { kEvseApp, kWhmApp }; +constexpr chip::EndpointId kEvseEndpoint = 1; +constexpr chip::EndpointId kWaterHeaterEndpoint = 2; +constexpr const char * kEvseApp = "evse"; +constexpr const char * kWhmApp = "water-heater"; +constexpr const char * kValidApps[] = { kEvseApp, kWhmApp }; +constexpr EndpointId kValidEndpoints[] = { kEvseEndpoint, kWaterHeaterEndpoint }; // Define the chip::ArgParser command line structures for extending the command line to support the // energy apps @@ -69,7 +73,8 @@ static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kP Feature::kForecastAdjustment, Feature::kConstraintBasedAdjustment); // Make EVSE the default app -static const char * spApp = kEvseApp; +static const char * spApp = kEvseApp; +static EndpointId sAppEndpointId = kEvseEndpoint; chip::BitMask GetFeatureMapFromCmdLine() { @@ -81,6 +86,11 @@ chip::BitMask GetFeatureMapFromCmdLine() } // namespace app } // namespace chip +chip::EndpointId GetEnergyDeviceEndpointId() +{ + return sAppEndpointId; +} + static uint32_t ParseNumber(const char * pString) { uint32_t num = 0; @@ -101,11 +111,15 @@ void ApplicationInit() ChipLogDetail(AppServer, "Energy Management App: ApplicationInit()"); if (strcmp(spApp, kEvseApp) == 0) { + // Disable Water Heater Endpoint + emberAfEndpointEnableDisable(kWaterHeaterEndpoint, false); EvseApplicationInit(); } else if (strcmp(spApp, kWhmApp) == 0) { - FullWhmApplicationInit(); + // Disable EVSE Endpoint + emberAfEndpointEnableDisable(kEvseEndpoint, false); + WaterHeaterApplicationInit(); } else { @@ -118,7 +132,7 @@ void ApplicationShutdown() ChipLogDetail(AppServer, "Energy Management App: ApplicationShutdown()"); EvseApplicationShutdown(); - FullWhmApplicationShutdown(); + WaterHeaterApplicationShutdown(); } static bool EnergyAppOptionHandler(const char * aProgram, chip::ArgParser::OptionSet * aOptions, int aIdentifier, @@ -134,7 +148,8 @@ static bool EnergyAppOptionHandler(const char * aProgram, chip::ArgParser::Optio { if (strcmp(kValidApps[idx], aValue) == 0) { - spApp = kValidApps[idx]; + spApp = kValidApps[idx]; + sAppEndpointId = kValidEndpoints[idx]; break; } } diff --git a/examples/energy-management-app/silabs/BUILD.gn b/examples/energy-management-app/silabs/BUILD.gn index 624cfff6250a85..cdf218b5142a98 100644 --- a/examples/energy-management-app/silabs/BUILD.gn +++ b/examples/energy-management-app/silabs/BUILD.gn @@ -166,6 +166,7 @@ silabs_executable("energy-management-app") { } sources = [ + "${chip_root}/examples/energy-management-app/energy-management-common/common/src/EnergyManagementAppCommonMain.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/common/src/EnergyTimeUtils.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMTestEventTriggers.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementDelegateImpl.cpp", @@ -183,7 +184,6 @@ silabs_executable("energy-management-app") { "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/EnergyReportingEventTriggers.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/FakeReadings.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/PowerTopologyDelegate.cpp", - "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WaterHeaterMain.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WhmDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WhmInstance.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/water-heater/src/WhmMain.cpp", diff --git a/examples/energy-management-app/silabs/src/AppTask.cpp b/examples/energy-management-app/silabs/src/AppTask.cpp index 42069a85b5de84..173b14a999bb02 100644 --- a/examples/energy-management-app/silabs/src/AppTask.cpp +++ b/examples/energy-management-app/silabs/src/AppTask.cpp @@ -21,12 +21,7 @@ #include "AppConfig.h" #include "AppEvent.h" #include "LEDWidget.h" -#if SL_MATTER_CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE -#include -#endif -#if SL_CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE -#include -#endif +#include #include #include #include @@ -36,6 +31,7 @@ #include #include #include +#include #include #include @@ -46,6 +42,7 @@ #include +#include #include #ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED @@ -76,8 +73,12 @@ #define APP_EVSE_SWITCH 1 namespace { + LEDWidget sEnergyManagementLED; -} +constexpr chip::EndpointId kEvseEndpoint = 1; +constexpr chip::EndpointId kWaterHeaterEndpoint = 2; + +} // namespace using namespace chip; using namespace chip::app; @@ -130,6 +131,15 @@ chip::BitMask GetFeatureMapFromCmdLine() AppTask AppTask::sAppTask; +EndpointId GetEnergyDeviceEndpointId() +{ +#if defined(SL_CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE) + return kWaterHeaterEndpoint; +#else + return kEvseEndpoint; +#endif +} + void ApplicationInit() { chip::DeviceLayer::PlatformMgr().LockChipStack(); @@ -138,12 +148,16 @@ void ApplicationInit() SILABS_LOG("energy-management-example EVSE starting. featureMap 0x%08lx", DeviceEnergyManagement::sFeatureMap.Raw()); EvseApplicationInit(); + // Disable Water Heater Endpoint + emberAfEndpointEnableDisable(kWaterHeaterEndpoint, false); #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #if SL_CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE SILABS_LOG("energy-management-example WaterHeater starting. featureMap 0x%08lx", DeviceEnergyManagement::sFeatureMap.Raw()); - FullWhmApplicationInit(); + WaterHeaterApplicationInit(); + // Disable EVSE Endpoint + emberAfEndpointEnableDisable(kEvseEndpoint, false); #endif // CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE SILABS_LOG("==================================================");