diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 0e16c64c41de13..390b21fc52cdc7 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -35,11 +35,8 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/boolcfg-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/device-energy-management-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-alarm-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/electrical-energy-measurement-stub.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/electrical-power-measurement-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-preference-delegate.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp", @@ -51,7 +48,6 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/power-topology-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-delegates.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp", @@ -61,6 +57,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp", "${chip_root}/examples/all-clusters-app/linux/diagnostic-logs-provider-delegate-impl.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/DEMDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementManager.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/device-energy-management-mode.cpp", @@ -71,6 +68,8 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseTargetsStore.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/energy-evse-mode.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/ElectricalPowerMeasurementDelegate.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/EnergyReportingMain.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/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/energy-management-common/common/include/EnergyManagementAppCmdLineOptions.h b/examples/energy-management-app/energy-management-common/common/include/EnergyManagementAppCmdLineOptions.h deleted file mode 100644 index a44140b94c762b..00000000000000 --- a/examples/energy-management-app/energy-management-common/common/include/EnergyManagementAppCmdLineOptions.h +++ /dev/null @@ -1,34 +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. - */ - -#pragma once - -#include -#include - -namespace chip { -namespace app { -namespace Clusters { -namespace DeviceEnergyManagement { - -chip::BitMask GetFeatureMapFromCmdLine(); - -} // namespace DeviceEnergyManagement -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h b/examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h index ac5cc5000e71b9..c404e4aa5d9b15 100644 --- a/examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h +++ b/examples/energy-management-app/energy-management-common/device-energy-management/include/DEMDelegate.h @@ -19,5 +19,15 @@ #pragma once #include +#include chip::app::Clusters::DeviceEnergyManagement::DeviceEnergyManagementDelegate * GetDEMDelegate(); +// TODO investigate this why isn't in in DEM? +extern std::unique_ptr gDEMInstance; +extern std::unique_ptr gDEMDelegate; + +CHIP_ERROR DeviceEnergyManagementInit(); +CHIP_ERROR DeviceEnergyManagementShutdown(); + +chip::BitMask GetDEMFeatureMap(); +void SetDEMFeatureMap(uint32_t); diff --git a/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMDelegate.cpp b/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMDelegate.cpp new file mode 100644 index 00000000000000..df57413e5df783 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/device-energy-management/src/DEMDelegate.cpp @@ -0,0 +1,146 @@ +/* + * + * 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 +#include + +#include +#include +#include +#include +#include + +static constexpr int DEM_ENDPOINT = 1; + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DeviceEnergyManagement; + +namespace chip { +namespace app { +namespace Clusters { +namespace DeviceEnergyManagement { + +// Keep track of the parsed featureMap option +#if defined(CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING) && defined(CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING) +#error Cannot define CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING and CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING +#endif + +#if defined(CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING) +static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kPowerForecastReporting, + Feature::kStartTimeAdjustment, Feature::kPausable, Feature::kForecastAdjustment, + Feature::kConstraintBasedAdjustment); +#elif defined(CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING) +static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kStateForecastReporting, + Feature::kStartTimeAdjustment, Feature::kPausable, Feature::kForecastAdjustment, + Feature::kConstraintBasedAdjustment); +#else +static chip::BitMask sFeatureMap(Feature::kPowerAdjustment); +#endif + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip + +chip::BitMask GetDEMFeatureMap() +{ + return sFeatureMap; +} + +void SetDEMFeatureMap(uint32_t featureMap) +{ + sFeatureMap = BitMask(featureMap); +} + +std::unique_ptr gDEMDelegate; +std::unique_ptr gDEMInstance; + +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 = GetDEMFeatureMap(); + + /* Manufacturer may optionally not support all features, commands & attributes */ + gDEMInstance = std::make_unique(EndpointId(DEM_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; +} 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..2e7e29537ef3b4 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,5 @@ #pragma once -#include - void EvseApplicationInit(); void EvseApplicationShutdown(); - -CHIP_ERROR DeviceEnergyManagementInit(); -CHIP_ERROR DeviceEnergyManagementShutdown(); - -CHIP_ERROR EnergyMeterInit(); -CHIP_ERROR EnergyMeterShutdown(); - -CHIP_ERROR PowerTopologyInit(); -CHIP_ERROR PowerTopologyShutdown(); 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..d0515a6305c36b 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 @@ -16,12 +16,12 @@ * limitations under the License. */ -#include "EnergyManagementAppCmdLineOptions.h" - +#include #include #include #include #include +#include #include #include #include @@ -36,7 +36,7 @@ #include #include -#define ENERGY_EVSE_ENDPOINT 1 +static constexpr int ENERGY_EVSE_ENDPOINT = 1; using namespace chip; using namespace chip::app; @@ -51,95 +51,14 @@ 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; +static std::unique_ptr gEvseManufacturer; 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 * @@ -232,160 +151,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 * @@ -460,7 +225,6 @@ void EvseApplicationInit() if (PowerTopologyInit() != CHIP_NO_ERROR) { - EVSEManufacturerShutdown(); DeviceEnergyManagementShutdown(); EnergyEvseShutdown(); EnergyMeterShutdown(); @@ -473,6 +237,7 @@ void EvseApplicationInit() DeviceEnergyManagementShutdown(); EnergyEvseShutdown(); EnergyMeterShutdown(); + PowerTopologyShutdown(); return; } } @@ -491,50 +256,3 @@ void EvseApplicationShutdown() 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-reporting/include/EnergyReportingMain.h b/examples/energy-management-app/energy-management-common/energy-reporting/include/EnergyReportingMain.h new file mode 100644 index 00000000000000..04bb84121f52c7 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/energy-reporting/include/EnergyReportingMain.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include + +#include +#include + +extern std::unique_ptr gPTDelegate; +extern std::unique_ptr gPTInstance; + +extern std::unique_ptr gEPMDelegate; +extern std::unique_ptr gEPMInstance; + +// Electrical Energy Measurement cluster uses ember to initialise +extern std::unique_ptr gEEMAttrAccess; + +CHIP_ERROR PowerTopologyInit(); +CHIP_ERROR PowerTopologyShutdown(); + +CHIP_ERROR EnergyMeterInit(); +CHIP_ERROR EnergyMeterShutdown(); diff --git a/examples/energy-management-app/energy-management-common/energy-reporting/src/EnergyReportingMain.cpp b/examples/energy-management-app/energy-management-common/energy-reporting/src/EnergyReportingMain.cpp new file mode 100644 index 00000000000000..75ab3035194175 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/energy-reporting/src/EnergyReportingMain.cpp @@ -0,0 +1,255 @@ +/* + * + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static constexpr int POWER_TOPOLOGY_ENDPOINT = 1; +static constexpr int ENERGY_METER_ENDPOINT = 1; + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ElectricalPowerMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement; +using namespace chip::app::Clusters::PowerTopology; + +std::unique_ptr gEPMDelegate; +std::unique_ptr gEPMInstance; +// Electrical Energy Measurement cluster uses ember to initialise +std::unique_ptr gEEMAttrAccess; + +std::unique_ptr gPTDelegate; +std::unique_ptr gPTInstance; + +/* + * @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(POWER_TOPOLOGY_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_METER_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; +} + +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/water-heater/include/WaterHeaterMain.h b/examples/energy-management-app/energy-management-common/water-heater/include/WaterHeaterMain.h deleted file mode 100644 index 819ff9e4d160ca..00000000000000 --- a/examples/energy-management-app/energy-management-common/water-heater/include/WaterHeaterMain.h +++ /dev/null @@ -1,32 +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. - */ - -#pragma once - -namespace chip { -namespace app { -namespace Clusters { -namespace WaterHeaterManagement { - -void FullWhmApplicationInit(); -void FullWhmApplicationShutdown(); - -} // namespace WaterHeaterManagement -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/water-heater/include/WhmManufacturer.h b/examples/energy-management-app/energy-management-common/water-heater/include/WhmManufacturer.h index 3a48b467ee22c5..8d2c2206d6e9a8 100644 --- a/examples/energy-management-app/energy-management-common/water-heater/include/WhmManufacturer.h +++ b/examples/energy-management-app/energy-management-common/water-heater/include/WhmManufacturer.h @@ -19,6 +19,10 @@ #pragma once #include +#include +#include +#include + #include #include @@ -36,7 +40,15 @@ namespace WaterHeaterManagement { class WhmManufacturer : public DeviceEnergyManagement::DEMManufacturerDelegate { public: - WhmManufacturer(WaterHeaterManagementInstance * whmInstance) { mWhmInstance = whmInstance; } + WhmManufacturer(WaterHeaterManagementInstance * whmInstance, + ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * aEPMInstance, + PowerTopology::PowerTopologyInstance * aPTInstance, DeviceEnergyManagementManager * aDEMInstance) + { + mWhmInstance = whmInstance; + mEPMInstance = aEPMInstance; + mPTInstance = aPTInstance; + mDEMInstance = aDEMInstance; + } WaterHeaterManagementInstance * GetWhmInstance() { return mWhmInstance; } @@ -50,6 +62,33 @@ class WhmManufacturer : public DeviceEnergyManagement::DEMManufacturerDelegate return nullptr; } + ElectricalPowerMeasurement::ElectricalPowerMeasurementDelegate * GetEPMDelegate() + { + if (mEPMInstance) + { + return mEPMInstance->GetDelegate(); + } + return nullptr; + } + + PowerTopology::PowerTopologyDelegate * GetPTDelegate() + { + if (mPTInstance) + { + return mPTInstance->GetDelegate(); + } + return nullptr; + } + + DeviceEnergyManagementDelegate * GetDEMDelegate() + { + if (mDEMInstance) + { + return mDEMInstance->GetDelegate(); + } + return nullptr; + } + /** * @brief Called at start up to apply hardware settings */ @@ -140,6 +179,9 @@ class WhmManufacturer : public DeviceEnergyManagement::DEMManufacturerDelegate */ void BoostCommandFinished(); + CHIP_ERROR SendPowerReading(EndpointId aEndpointId, Power_mW aActivePower_mW, Voltage_mV aVoltage_mV, + Amperage_mA aActiveCurrent_mA); + /* Implement the DEMManufacturerDelegate interface */ /** @@ -149,6 +191,9 @@ class WhmManufacturer : public DeviceEnergyManagement::DEMManufacturerDelegate private: WaterHeaterManagementInstance * mWhmInstance; + ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * mEPMInstance; + PowerTopology::PowerTopologyInstance * mPTInstance; + DeviceEnergyManagementManager * mDEMInstance; }; /** @brief Helper function to return the singleton WhmManufacturer instance 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..99d39a483bd0ae 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 @@ -16,8 +16,12 @@ * limitations under the License. */ +#include +#include #include #include +#include +#include #include #include @@ -30,6 +34,10 @@ using namespace chip; using namespace chip::app; using namespace chip::app::DataModel; using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ElectricalPowerMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement; +using namespace chip::app::Clusters::PowerTopology; +using namespace chip::app::Clusters::DeviceEnergyManagement; namespace chip { namespace app { @@ -133,7 +141,8 @@ CHIP_ERROR WhmManufacturerInit() } /* Now create WhmManufacturer */ - gWhmManufacturer = std::make_unique(gWhmInstance.get()); + gWhmManufacturer = + std::make_unique(gWhmInstance.get(), gEPMInstance.get(), gPTInstance.get(), gDEMInstance.get()); if (!gWhmManufacturer) { ChipLogError(AppServer, "Failed to allocate memory for WhmManufacturer"); @@ -169,20 +178,61 @@ CHIP_ERROR WhmManufacturerShutdown() CHIP_ERROR WhmApplicationInit() { - ReturnErrorOnFailure(WhmInit()); + ReturnErrorOnFailure(DeviceEnergyManagementInit()); + + CHIP_ERROR err = WhmInit(); + if (err != CHIP_NO_ERROR) + { + DeviceEnergyManagementShutdown(); + return err; + } + + err = EnergyMeterInit(); + if (err != CHIP_NO_ERROR) + { + DeviceEnergyManagementShutdown(); + WhmShutdown(); + return err; + } + + err = PowerTopologyInit(); + if (err != CHIP_NO_ERROR) + { + DeviceEnergyManagementShutdown(); + WhmShutdown(); + EnergyMeterShutdown(); + return err; + } /* Do this last so that the instances for other clusters can be wrapped inside */ - ReturnErrorOnFailure(WhmManufacturerInit()); + err = WhmManufacturerInit(); + if (err != CHIP_NO_ERROR) + { + DeviceEnergyManagementShutdown(); + WhmShutdown(); + EnergyMeterShutdown(); + PowerTopologyShutdown(); + return err; + } return CHIP_NO_ERROR; } CHIP_ERROR WhmApplicationShutdown() { + ChipLogDetail(AppServer, "Energy Management App (WaterHeater): ApplicationShutdown()"); + /* Shutdown in reverse order that they were created */ WhmManufacturerShutdown(); + PowerTopologyShutdown(); + EnergyMeterShutdown(); + WhmShutdown(); + DeviceEnergyManagementShutdown(); - return WhmShutdown(); + Clusters::DeviceEnergyManagementMode::Shutdown(); + Clusters::WaterHeaterMode::Shutdown(); + + return CHIP_NO_ERROR; } } // namespace WaterHeaterManagement diff --git a/examples/energy-management-app/energy-management-common/water-heater/src/WhmManufacturer.cpp b/examples/energy-management-app/energy-management-common/water-heater/src/WhmManufacturer.cpp index 446d684e41be64..58b5d5c9e1c334 100644 --- a/examples/energy-management-app/energy-management-common/water-heater/src/WhmManufacturer.cpp +++ b/examples/energy-management-app/energy-management-common/water-heater/src/WhmManufacturer.cpp @@ -25,7 +25,10 @@ #include using namespace chip; +using namespace chip::app::DataModel; using namespace chip::app::Clusters::WaterHeaterManagement; +using namespace chip::app::Clusters::ElectricalPowerMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement; using Protocols::InteractionModel::Status; @@ -46,6 +49,14 @@ CHIP_ERROR WhmManufacturer::Init() dg->SetHeaterTypes(BitMask(WaterHeaterHeatSourceBitmap::kImmersionElement1)); dg->SetColdWaterTemperature(2000); + /* For Device Energy Management we need the ESA to be Online and ready to accept commands */ + GetDEMDelegate()->SetESAState(ESAStateEnum::kOnline); + GetDEMDelegate()->SetDEMManufacturerDelegate(*GetWhmManufacturer()); + + // Set the abs min and max power + GetDEMDelegate()->SetAbsMinPower(1000000); // 1.0KW + GetDEMDelegate()->SetAbsMaxPower(5400000); // 5.4KW + return CHIP_NO_ERROR; } @@ -151,6 +162,29 @@ WaterHeaterManagementDelegate * GetWhmDelegate() return wg; } +/** + * @brief Allows a client application to send in power readings into the system + * + * @param[in] aEndpointId - Endpoint to send to EPM Cluster + * @param[in] aActivePower_mW - ActivePower measured in milli-watts + * @param[in] aVoltage_mV - Voltage measured in milli-volts + * @param[in] aActiveCurrent_mA - ActiveCurrent measured in milli-amps + */ +CHIP_ERROR WhmManufacturer::SendPowerReading(EndpointId aEndpointId, Power_mW aActivePower_mW, Voltage_mV aVoltage_mV, + Amperage_mA aActiveCurrent_mA) +{ + WhmManufacturer * mn = GetWhmManufacturer(); + VerifyOrReturnError(mn != nullptr, CHIP_ERROR_UNINITIALIZED); + + ElectricalPowerMeasurementDelegate * dg = mn->GetEPMDelegate(); + VerifyOrReturnError(dg != nullptr, CHIP_ERROR_UNINITIALIZED); + + dg->SetActivePower(MakeNullable(aActivePower_mW)); + dg->SetVoltage(MakeNullable(aVoltage_mV)); + dg->SetActiveCurrent(MakeNullable(aActiveCurrent_mA)); + + return CHIP_NO_ERROR; +} // The PowerAdjustEnd event needs to report the approximate energy used by the ESA during the session. int64_t WhmManufacturer::GetApproxEnergyDuringSession() { diff --git a/examples/energy-management-app/esp32/main/main.cpp b/examples/energy-management-app/esp32/main/main.cpp index d235fa4291ac98..abac211c47367b 100644 --- a/examples/energy-management-app/esp32/main/main.cpp +++ b/examples/energy-management-app/esp32/main/main.cpp @@ -17,12 +17,13 @@ #include "DeviceCallbacks.h" +#include #if CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #include #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #if CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE -#include +#include #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #include "esp_log.h" @@ -119,38 +120,6 @@ chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void) } // namespace -namespace chip { -namespace app { -namespace Clusters { -namespace DeviceEnergyManagement { - -// Keep track of the parsed featureMap option -#if defined(CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING) && defined(CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING) -#error Cannot define CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING and CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING -#endif - -#ifdef CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kPowerForecastReporting, - Feature::kStartTimeAdjustment, Feature::kPausable, Feature::kForecastAdjustment, - Feature::kConstraintBasedAdjustment); -#elif CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kStateForecastReporting, - Feature::kStartTimeAdjustment, Feature::kPausable, Feature::kForecastAdjustment, - Feature::kConstraintBasedAdjustment); -#else -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment); -#endif - -chip::BitMask GetFeatureMapFromCmdLine() -{ - return sFeatureMap; -} - -} // namespace DeviceEnergyManagement -} // namespace Clusters -} // namespace app -} // namespace chip - // Check we are not trying to build in both app types simultaneously #if defined(CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE) && defined(CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE) #error Cannot define CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE and CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE @@ -164,7 +133,7 @@ void ApplicationInit() #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #if CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE - FullWhmApplicationInit(); + WhmApplicationInit(); #endif // CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE } @@ -177,7 +146,7 @@ void ApplicationShutdown() #endif // CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #if CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE - FullWhmApplicationShutdown(); + WhmApplicationShutdown(); #endif // CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE } @@ -238,13 +207,11 @@ extern "C" void app_main() ESP_LOGI(TAG, "=================================================="); #if defined(CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE) - ESP_LOGI(TAG, "chip-esp32-energy-management-example evse starting. featureMap 0x%08lx", - DeviceEnergyManagement::sFeatureMap.Raw()); + ESP_LOGI(TAG, "chip-esp32-energy-management-example evse starting. featureMap 0x%08lx", GetDEMFeatureMap().Raw()); #elif defined(CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE) - ESP_LOGI(TAG, "chip-esp32-energy-management-example water-heater starting. featureMap 0x%08lx", - DeviceEnergyManagement::sFeatureMap.Raw()); + ESP_LOGI(TAG, "chip-esp32-energy-management-example water-heater starting. featureMap 0x%08lx", GetDEMFeatureMap().Raw()); #else - ESP_LOGI(TAG, "chip-esp32-energy-management-example starting. featureMap 0x%08lx", DeviceEnergyManagement::sFeatureMap.Raw()); + ESP_LOGI(TAG, "chip-esp32-energy-management-example starting. featureMap 0x%08lx", GetDEMFeatureMap().Raw()); #endif ESP_LOGI(TAG, "=================================================="); diff --git a/examples/energy-management-app/linux/BUILD.gn b/examples/energy-management-app/linux/BUILD.gn index a9d41a1e76d033..fc5324ce47cf24 100644 --- a/examples/energy-management-app/linux/BUILD.gn +++ b/examples/energy-management-app/linux/BUILD.gn @@ -35,6 +35,7 @@ config("includes") { executable("chip-energy-management-app") { sources = [ "${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/DEMDelegate.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", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementManager.cpp", @@ -49,9 +50,9 @@ executable("chip-energy-management-app") { "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/energy-evse-mode.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/ElectricalPowerMeasurementDelegate.cpp", "${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/EnergyReportingMain.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..3b08f9dc43f09b 100644 --- a/examples/energy-management-app/linux/main.cpp +++ b/examples/energy-management-app/linux/main.cpp @@ -17,8 +17,10 @@ */ #include +#include #include -#include +#include + #include #include @@ -58,29 +60,9 @@ static chip::ArgParser::OptionSet sCmdLineOptions = { EnergyAppOptionHandler, // "-a, --application \n" "-f, --featureSet \n" }; -namespace chip { -namespace app { -namespace Clusters { -namespace DeviceEnergyManagement { - -// Keep track of the parsed featureMap option -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kPowerForecastReporting, - Feature::kStateForecastReporting, Feature::kStartTimeAdjustment, Feature::kPausable, - Feature::kForecastAdjustment, Feature::kConstraintBasedAdjustment); - // Make EVSE the default app static const char * spApp = kEvseApp; -chip::BitMask GetFeatureMapFromCmdLine() -{ - return sFeatureMap; -} - -} // namespace DeviceEnergyManagement -} // namespace Clusters -} // namespace app -} // namespace chip - static uint32_t ParseNumber(const char * pString) { uint32_t num = 0; @@ -105,7 +87,7 @@ void ApplicationInit() } else if (strcmp(spApp, kWhmApp) == 0) { - FullWhmApplicationInit(); + WhmApplicationInit(); } else { @@ -118,7 +100,7 @@ void ApplicationShutdown() ChipLogDetail(AppServer, "Energy Management App: ApplicationShutdown()"); EvseApplicationShutdown(); - FullWhmApplicationShutdown(); + WhmApplicationShutdown(); } static bool EnergyAppOptionHandler(const char * aProgram, chip::ArgParser::OptionSet * aOptions, int aIdentifier, @@ -149,8 +131,8 @@ static bool EnergyAppOptionHandler(const char * aProgram, chip::ArgParser::Optio } break; case kOptionFeatureMap: - sFeatureMap = BitMask(ParseNumber(aValue)); - ChipLogDetail(Support, "Using FeatureMap 0x%04x", sFeatureMap.Raw()); + SetDEMFeatureMap(ParseNumber(aValue)); + ChipLogDetail(Support, "Using FeatureMap 0x%04x", GetDEMFeatureMap().Raw()); break; default: ChipLogError(Support, "%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); diff --git a/examples/energy-management-app/silabs/BUILD.gn b/examples/energy-management-app/silabs/BUILD.gn index 624cfff6250a85..e297af48735dd0 100644 --- a/examples/energy-management-app/silabs/BUILD.gn +++ b/examples/energy-management-app/silabs/BUILD.gn @@ -167,6 +167,7 @@ silabs_executable("energy-management-app") { sources = [ "${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/DEMDelegate.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", "${chip_root}/examples/energy-management-app/energy-management-common/device-energy-management/src/DeviceEnergyManagementManager.cpp", @@ -181,9 +182,9 @@ silabs_executable("energy-management-app") { "${chip_root}/examples/energy-management-app/energy-management-common/energy-evse/src/energy-evse-mode.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/energy-reporting/src/ElectricalPowerMeasurementDelegate.cpp", "${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/EnergyReportingMain.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..cc0c86a071f419 100644 --- a/examples/energy-management-app/silabs/src/AppTask.cpp +++ b/examples/energy-management-app/silabs/src/AppTask.cpp @@ -21,6 +21,8 @@ #include "AppConfig.h" #include "AppEvent.h" #include "LEDWidget.h" + +#include #if SL_MATTER_CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE #include #endif @@ -96,38 +98,6 @@ static EnergyReportingTestEventTriggerHandler sEnergyReportingTestEventTriggerHa static DeviceEnergyManagementTestEventTriggerHandler sDeviceEnergyManagementTestEventTriggerHandler; #endif -namespace chip { -namespace app { -namespace Clusters { -namespace DeviceEnergyManagement { - -// Keep track of the parsed featureMap option -#if (SL_MATTER_CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING) && (SL_MATTER_CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING) -#error Cannot define SL_MATTER_CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING and SL_MATTER_CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING -#endif - -#if SL_MATTER_CONFIG_DEM_SUPPORT_POWER_FORECAST_REPORTING -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kPowerForecastReporting, - Feature::kStartTimeAdjustment, Feature::kPausable, Feature::kForecastAdjustment, - Feature::kConstraintBasedAdjustment); -#elif SL_MATTER_CONFIG_DEM_SUPPORT_STATE_FORECAST_REPORTING -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kStateForecastReporting, - Feature::kStartTimeAdjustment, Feature::kPausable, Feature::kForecastAdjustment, - Feature::kConstraintBasedAdjustment); -#else -static chip::BitMask sFeatureMap(Feature::kPowerAdjustment); -#endif - -chip::BitMask GetFeatureMapFromCmdLine() -{ - return sFeatureMap; -} - -} // namespace DeviceEnergyManagement -} // namespace Clusters -} // namespace app -} // namespace chip - AppTask AppTask::sAppTask; void ApplicationInit() @@ -135,15 +105,15 @@ void ApplicationInit() chip::DeviceLayer::PlatformMgr().LockChipStack(); SILABS_LOG("=================================================="); #if SL_MATTER_CONFIG_ENABLE_EXAMPLE_EVSE_DEVICE - SILABS_LOG("energy-management-example EVSE starting. featureMap 0x%08lx", DeviceEnergyManagement::sFeatureMap.Raw()); + SILABS_LOG("energy-management-example EVSE starting. featureMap 0x%08lx", GetDEMFeatureMap().Raw()); EvseApplicationInit(); #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()); + SILABS_LOG("energy-management-example WaterHeater starting. featureMap 0x%08lx", GetDEMFeatureMap().Raw()); - FullWhmApplicationInit(); + WhmApplicationInit(); #endif // CONFIG_ENABLE_EXAMPLE_WATER_HEATER_DEVICE SILABS_LOG("=================================================="); @@ -224,7 +194,7 @@ CHIP_ERROR AppTask::Init() // Update the LCD with the Stored value. Show QR Code if not provisioned #ifdef DISPLAY_ENABLED - GetLCD().WriteDemoUI(LightMgr().IsLightOn()); + // GetLCD().WriteDemoUI(LightMgr().IsLightOn()); #ifdef QR_CODE_ENABLED #ifdef SL_WIFI if (!chip::DeviceLayer::ConnectivityMgr().IsWiFiStationProvisioned())