From a9799ee2c7d4e55fde2a15de4657c86191805d35 Mon Sep 17 00:00:00 2001 From: James Harrow Date: Mon, 26 Feb 2024 22:37:54 +0000 Subject: [PATCH 1/7] Turned on PowerSource on EP0 with WIRED mandated attributes, and PowerTopology on EP1 --- .../energy-management-app.matter | 306 ++++++++++++++++ .../energy-management-app.zap | 335 +++++++++++++++++- 2 files changed, 640 insertions(+), 1 deletion(-) 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 1cedefb6c1e43c..398910a77514fb 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 @@ -343,6 +343,265 @@ cluster UnitLocalization = 45 { readonly attribute int16u clusterRevision = 65533; } +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + 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; +} + /** This cluster is used to manage global aspects of the Commissioning flow. */ cluster GeneralCommissioning = 48 { revision 1; // NOTE: Default/not specifically set @@ -1557,6 +1816,27 @@ provisional cluster EnergyEvse = 153 { timed command ClearTargets(): DefaultSuccess = 7; } +/** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ +provisional cluster PowerTopology = 156 { + revision 1; + + bitmap Feature : bitmap32 { + kNodeTopology = 0x1; + kTreeTopology = 0x2; + kSetTopology = 0x4; + kDynamicPowerFlow = 0x8; + } + + readonly attribute optional endpoint_no availableEndpoints[] = 0; + readonly attribute optional endpoint_no activeEndpoints[] = 1; + 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; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster EnergyEvseMode = 157 { revision 1; @@ -1742,6 +2022,22 @@ endpoint 0 { ram attribute clusterRevision default = 1; } + server cluster PowerSource { + ram attribute status; + ram attribute order; + ram attribute description; + ram attribute wiredCurrentType; + ram attribute wiredNominalVoltage; + ram attribute wiredMaximumCurrent; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster GeneralCommissioning { ram attribute breadcrumb default = 0x0000000000000000; callback attribute basicCommissioningInfo; @@ -1860,6 +2156,7 @@ endpoint 0 { } } endpoint 1 { + device type ma_electricalsensor = 1296, version 1; device type energy_evse = 1292, version 1; @@ -2006,6 +2303,15 @@ endpoint 1 { handle command ClearTargets; } + server cluster PowerTopology { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + } + server cluster EnergyEvseMode { callback attribute supportedModes; callback attribute currentMode; 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 88514f105c37f1..694b6bfa83b8b6 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 @@ -1112,6 +1112,224 @@ } ] }, + { + "name": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "WiredCurrentType", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "WiredCurrentTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "WiredNominalVoltage", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "WiredMaximumCurrent", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "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": "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": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "General Commissioning", "code": 48, @@ -2471,13 +2689,21 @@ "profileId": 259, "label": "Energy EVSE", "name": "Energy EVSE" + }, + { + "code": 1296, + "profileId": 259, + "label": "MA-electricalsensor", + "name": "MA-electricalsensor" } ], "deviceVersions": [ + 1, 1 ], "deviceIdentifiers": [ - 1292 + 1292, + 1296 ], "deviceTypeName": "Energy EVSE", "deviceTypeCode": 1292, @@ -4259,6 +4485,113 @@ } ] }, + { + "name": "Power Topology", + "code": 156, + "mfgCode": null, + "define": "POWER_TOPOLOGY_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "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": "Energy EVSE Mode", "code": 157, From 6f47f064e39f2570e779aa690d5c9fc93902aa79 Mon Sep 17 00:00:00 2001 From: James Harrow Date: Mon, 26 Feb 2024 23:28:51 +0000 Subject: [PATCH 2/7] Added code into EvseMain to initialise the PowerTopology cluster on EP1 --- .../src/EnergyEvseMain.cpp | 84 +++++++++++++++++++ examples/energy-management-app/linux/BUILD.gn | 1 + 2 files changed, 85 insertions(+) diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp index 9beff80e8dc22a..b9bec3f1c8e167 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +44,7 @@ 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::PowerTopology; static std::unique_ptr gEvseDelegate; static std::unique_ptr gEvseInstance; @@ -53,6 +56,9 @@ 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(); @@ -197,6 +203,74 @@ 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 * @@ -359,6 +433,15 @@ void EvseApplicationInit() EnergyMeterShutdown(); return; } + + if (PowerTopologyInit() != CHIP_NO_ERROR) + { + EVSEManufacturerShutdown(); + DeviceEnergyManagementShutdown(); + EnergyEvseShutdown(); + EnergyMeterShutdown(); + return; + } } void EvseApplicationShutdown() @@ -366,6 +449,7 @@ void EvseApplicationShutdown() ChipLogDetail(AppServer, "Energy Management App: ApplicationShutdown()"); /* Shutdown in reverse order that they were created */ + PowerTopologyShutdown(); /* Free the PowerTopology */ EVSEManufacturerShutdown(); /* Free the EVSEManufacturer */ EnergyMeterShutdown(); /* Free the Energy Meter */ EnergyEvseShutdown(); /* Free the EnergyEvse */ diff --git a/examples/energy-management-app/linux/BUILD.gn b/examples/energy-management-app/linux/BUILD.gn index 99acf81baad1c9..4730c2c8ea82f3 100644 --- a/examples/energy-management-app/linux/BUILD.gn +++ b/examples/energy-management-app/linux/BUILD.gn @@ -43,6 +43,7 @@ executable("chip-energy-management-app") { "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/device-energy-management-mode.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/energy-evse-mode.cpp", "include/CHIPProjectAppConfig.h", From 074ae840e87fa4d389de4cce61abbe3b91d112d8 Mon Sep 17 00:00:00 2001 From: James Harrow Date: Tue, 27 Feb 2024 01:48:52 +0000 Subject: [PATCH 3/7] Changed ClusterRevision of PowerTopology to 2, enabled SerialNumber in BasicInfo. Added Initialization of PowerSource attributes. --- .../energy-management-app.matter | 3 +- .../energy-management-app.zap | 18 ++++++++- .../include/EVSEManufacturerImpl.h | 5 +++ .../src/EVSEManufacturerImpl.cpp | 37 +++++++++++++++++++ .../linux/include/CHIPProjectAppConfig.h | 8 ++++ 5 files changed, 69 insertions(+), 2 deletions(-) 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 398910a77514fb..ea4e5db21a0b18 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 @@ -1981,6 +1981,7 @@ endpoint 0 { callback attribute hardwareVersionString; callback attribute softwareVersion; callback attribute softwareVersionString; + callback attribute serialNumber; callback attribute capabilityMinima; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; @@ -2035,7 +2036,7 @@ endpoint 0 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster GeneralCommissioning { 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 694b6bfa83b8b6..2f3745ed979e98 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 @@ -600,6 +600,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "CapabilityMinima", "code": 19, @@ -1322,7 +1338,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h index fcae38dcafd2b5..92875a3b781e33 100644 --- a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h +++ b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h @@ -82,6 +82,11 @@ class EVSEManufacturer */ CHIP_ERROR InitializePowerMeasurementCluster(); + /** + * @brief Allows a client application to initialise the PowerSource cluster + */ + CHIP_ERROR InitializePowerSourceCluster(); + /** * @brief Allows a client application to send in power readings into the system * diff --git a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp index cb7a7a44991e16..83abac767844d1 100644 --- a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp @@ -18,11 +18,16 @@ #include #include + #include #include #include +#include #include +#include +#include + using namespace chip; using namespace chip::app; using namespace chip::app::DataModel; @@ -31,6 +36,10 @@ using namespace chip::app::Clusters::EnergyEvse; using namespace chip::app::Clusters::ElectricalPowerMeasurement; using namespace chip::app::Clusters::ElectricalEnergyMeasurement; using namespace chip::app::Clusters::ElectricalEnergyMeasurement::Structs; +using namespace chip::app::Clusters::PowerSource; +using namespace chip::app::Clusters::PowerSource::Attributes; + +using Protocols::InteractionModel::Status; CHIP_ERROR EVSEManufacturer::Init() { @@ -48,6 +57,7 @@ CHIP_ERROR EVSEManufacturer::Init() ReturnErrorOnFailure(InitializePowerMeasurementCluster()); + ReturnErrorOnFailure(InitializePowerSourceCluster()); /* * This is an example implementation for manufacturers to consider * @@ -110,6 +120,33 @@ CHIP_ERROR EVSEManufacturer::InitializePowerMeasurementCluster() return CHIP_NO_ERROR; } +/** + * @brief Allows a client application to initialise the PowerSource cluster + */ +CHIP_ERROR EVSEManufacturer::InitializePowerSourceCluster() +{ + Protocols::InteractionModel::Status status; + + status = PowerSource::Attributes::Status::Set(EndpointId(0) /*RootNode*/, PowerSourceStatusEnum::kActive); + VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); + status = + PowerSource::Attributes::FeatureMap::Set(EndpointId(0 /*RootNode*/), static_cast(PowerSource::Feature::kWired)); + VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); + status = PowerSource::Attributes::WiredNominalVoltage::Set(EndpointId(0 /*RootNode*/), 230'000); // 230V in mv + VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); + status = PowerSource::Attributes::WiredMaximumCurrent::Set(EndpointId(0 /*RootNode*/), 32'000); // 32A in mA + VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); + + status = PowerSource::Attributes::WiredCurrentType::Set(EndpointId(0 /*RootNode*/), PowerSource::WiredCurrentTypeEnum::kAc); + VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); + status = PowerSource::Attributes::Description::Set(EndpointId(0 /*RootNode*/), CharSpan::fromCharString("Primary Mains Power")); + VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); + + // TODO set the EndpointList - GetPowerTopologyDelegate()->SetEndpointList(Span(EndpointId(1))); + + return CHIP_NO_ERROR; +} + /** * @brief Allows a client application to send in power readings into the system * diff --git a/examples/energy-management-app/linux/include/CHIPProjectAppConfig.h b/examples/energy-management-app/linux/include/CHIPProjectAppConfig.h index e091fa9cf7c91c..4a42f0a9c04c97 100644 --- a/examples/energy-management-app/linux/include/CHIPProjectAppConfig.h +++ b/examples/energy-management-app/linux/include/CHIPProjectAppConfig.h @@ -45,3 +45,11 @@ #define CHIP_DEVICE_ENABLE_PORT_PARAMS 1 #define CHIP_DEVICE_CONFIG_DEVICE_NAME "Test Energy Management" + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 1 +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.0" +#endif From 98b24695eaa6b1168d1c8e836fdf05e579164b38 Mon Sep 17 00:00:00 2001 From: James Harrow Date: Tue, 27 Feb 2024 07:39:01 +0000 Subject: [PATCH 4/7] Added missing PowerTopologyDelegate.h & .cpp --- .../include/PowerTopologyDelegate.h | 42 +++++++++++++++++++ .../src/PowerTopologyDelegate.cpp | 33 +++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h create mode 100644 examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp diff --git a/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h b/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h new file mode 100644 index 00000000000000..365201a6951c75 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.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 + +namespace chip { +namespace app { +namespace Clusters { +namespace PowerTopology { + +class PowerTopologyDelegate : public Delegate +{ +public: + ~PowerTopologyDelegate() = default; + + CHIP_ERROR GetAvailableEndpointAtIndex(size_t index, EndpointId & endpointId) override; + CHIP_ERROR GetActiveEndpointAtIndex(size_t index, EndpointId & endpointId) override; +}; + +} // namespace PowerTopology +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp b/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp new file mode 100644 index 00000000000000..71d698b39e22f0 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp @@ -0,0 +1,33 @@ +/* + * + * 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 + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::PowerTopology; + +CHIP_ERROR PowerTopologyDelegate::GetAvailableEndpointAtIndex(size_t index, EndpointId & endpointId) +{ + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +CHIP_ERROR PowerTopologyDelegate::GetActiveEndpointAtIndex(size_t index, EndpointId & endpointId) +{ + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} From a93e184392797066521be228e27f23b69829ab75 Mon Sep 17 00:00:00 2001 From: James Harrow Date: Tue, 27 Feb 2024 22:19:05 +0000 Subject: [PATCH 5/7] Added power-source and power-topology to ESP32 CMakeList.txt --- examples/energy-management-app/esp32/main/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/energy-management-app/esp32/main/CMakeLists.txt b/examples/energy-management-app/esp32/main/CMakeLists.txt index ddaff6b83e02f0..0c038632b4feab 100644 --- a/examples/energy-management-app/esp32/main/CMakeLists.txt +++ b/examples/energy-management-app/esp32/main/CMakeLists.txt @@ -55,7 +55,9 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-topology-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/software-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/switch-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/thread-network-diagnostics-server" From 5e0fb1b6f6597479019d9eb4ea0eedd4dbdc5e64 Mon Sep 17 00:00:00 2001 From: James Harrow Date: Tue, 27 Feb 2024 23:38:20 +0000 Subject: [PATCH 6/7] Updated PowerTopology to include an Instance, and also added to EvseManufacturer class. Called PowerSource->SetEndpointList() --- .../include/EVSEManufacturerImpl.h | 16 ++++++++++++- .../include/PowerTopologyDelegate.h | 24 +++++++++++++++++++ .../src/EVSEManufacturerImpl.cpp | 7 +++++- .../src/EnergyEvseMain.cpp | 21 ++++++++-------- .../src/PowerTopologyDelegate.cpp | 10 ++++++++ 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h index 92875a3b781e33..23994e7f5d9454 100644 --- a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h +++ b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h @@ -21,6 +21,7 @@ #include #include #include +#include using chip::Protocols::InteractionModel::Status; namespace chip { @@ -36,13 +37,16 @@ class EVSEManufacturer { public: EVSEManufacturer(EnergyEvseManager * aEvseInstance, - ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * aEPMInstance) + ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * aEPMInstance, + PowerTopology::PowerTopologyInstance * aPTInstance) { mEvseInstance = aEvseInstance; mEPMInstance = aEPMInstance; + mPTInstance = aPTInstance; } EnergyEvseManager * GetEvseInstance() { return mEvseInstance; } ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * GetEPMInstance() { return mEPMInstance; } + PowerTopology::PowerTopologyInstance * GetPTInstance() { return mPTInstance; } EnergyEvseDelegate * GetEvseDelegate() { @@ -62,6 +66,15 @@ class EVSEManufacturer return nullptr; } + PowerTopology::PowerTopologyDelegate * GetPTDelegate() + { + if (mPTInstance) + { + return mPTInstance->GetDelegate(); + } + return nullptr; + } + /** * @brief Called at start up to apply hardware settings */ @@ -158,6 +171,7 @@ class EVSEManufacturer private: EnergyEvseManager * mEvseInstance; ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * mEPMInstance; + PowerTopology::PowerTopologyInstance * mPTInstance; int64_t mLastChargingEnergyMeter = 0; int64_t mLastDischargingEnergyMeter = 0; diff --git a/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h b/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h index 365201a6951c75..7e3336e772f940 100644 --- a/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h +++ b/examples/energy-management-app/energy-management-common/include/PowerTopologyDelegate.h @@ -36,6 +36,30 @@ class PowerTopologyDelegate : public Delegate CHIP_ERROR GetActiveEndpointAtIndex(size_t index, EndpointId & endpointId) override; }; +class PowerTopologyInstance : public Instance +{ +public: + PowerTopologyInstance(EndpointId aEndpointId, PowerTopologyDelegate & aDelegate, Feature aFeature, + OptionalAttributes aOptionalAttributes) : + PowerTopology::Instance(aEndpointId, aDelegate, aFeature, aOptionalAttributes) + { + mDelegate = &aDelegate; + } + + // Delete copy constructor and assignment operator. + PowerTopologyInstance(const PowerTopologyInstance &) = delete; + PowerTopologyInstance(const PowerTopologyInstance &&) = delete; + PowerTopologyInstance & operator=(const PowerTopologyInstance &) = delete; + + CHIP_ERROR Init(); + void Shutdown(); + + PowerTopologyDelegate * GetDelegate() { return mDelegate; }; + +private: + PowerTopologyDelegate * mDelegate; +}; + } // namespace PowerTopology } // namespace Clusters } // namespace app diff --git a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp index 83abac767844d1..d9848bcbc53515 100644 --- a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp @@ -142,7 +142,12 @@ CHIP_ERROR EVSEManufacturer::InitializePowerSourceCluster() status = PowerSource::Attributes::Description::Set(EndpointId(0 /*RootNode*/), CharSpan::fromCharString("Primary Mains Power")); VerifyOrReturnError(status == Protocols::InteractionModel::Status::Success, CHIP_ERROR_INTERNAL); - // TODO set the EndpointList - GetPowerTopologyDelegate()->SetEndpointList(Span(EndpointId(1))); + chip::EndpointId endpointArray[] = { 1 /* EVSE Endpoint */ }; + Span endpointList = Span(endpointArray); + + // Note per API - we do not need to maintain the span after the SetEndpointList has been called + // since it takes a copy (see power-source-server.cpp) + PowerSourceServer::Instance().SetEndpointList(0 /* Root Node */, endpointList); return CHIP_NO_ERROR; } diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp index b9bec3f1c8e167..6eeaaf8369c38c 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp @@ -56,8 +56,8 @@ 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 gPTDelegate; +static std::unique_ptr gPTInstance; EVSEManufacturer * EnergyEvse::GetEvseManufacturer() { @@ -228,9 +228,9 @@ CHIP_ERROR PowerTopologyInit() } gPTInstance = - std::make_unique(EndpointId(ENERGY_EVSE_ENDPOINT), *gPTDelegate, - BitMask(PowerTopology::Feature::kNodeTopology), - BitMask(0)); + std::make_unique(EndpointId(ENERGY_EVSE_ENDPOINT), *gPTDelegate, + BitMask(PowerTopology::Feature::kNodeTopology), + BitMask(0)); if (!gPTInstance) { @@ -375,7 +375,7 @@ CHIP_ERROR EVSEManufacturerInit() } /* Now create EVSEManufacturer */ - gEvseManufacturer = std::make_unique(gEvseInstance.get(), gEPMInstance.get()); + gEvseManufacturer = std::make_unique(gEvseInstance.get(), gEPMInstance.get(), gPTInstance.get()); if (!gEvseManufacturer) { ChipLogError(AppServer, "Failed to allocate memory for EvseManufacturer"); @@ -426,17 +426,18 @@ void EvseApplicationInit() return; } - if (EVSEManufacturerInit() != CHIP_NO_ERROR) + if (PowerTopologyInit() != CHIP_NO_ERROR) { + EVSEManufacturerShutdown(); DeviceEnergyManagementShutdown(); EnergyEvseShutdown(); EnergyMeterShutdown(); return; } - if (PowerTopologyInit() != CHIP_NO_ERROR) + /* Do this last so that the instances for other clusters can be wrapped inside */ + if (EVSEManufacturerInit() != CHIP_NO_ERROR) { - EVSEManufacturerShutdown(); DeviceEnergyManagementShutdown(); EnergyEvseShutdown(); EnergyMeterShutdown(); @@ -449,8 +450,8 @@ void EvseApplicationShutdown() ChipLogDetail(AppServer, "Energy Management App: ApplicationShutdown()"); /* Shutdown in reverse order that they were created */ - PowerTopologyShutdown(); /* Free the PowerTopology */ EVSEManufacturerShutdown(); /* Free the EVSEManufacturer */ + PowerTopologyShutdown(); /* Free the PowerTopology */ EnergyMeterShutdown(); /* Free the Energy Meter */ EnergyEvseShutdown(); /* Free the EnergyEvse */ DeviceEnergyManagementShutdown(); /* Free the DEM */ diff --git a/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp b/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp index 71d698b39e22f0..68ce4ff2358450 100644 --- a/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp +++ b/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp @@ -31,3 +31,13 @@ CHIP_ERROR PowerTopologyDelegate::GetActiveEndpointAtIndex(size_t index, Endpoin { return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; } + +CHIP_ERROR PowerTopologyInstance::Init() +{ + return Instance::Init(); +} + +void PowerTopologyInstance::Shutdown() +{ + Instance::Shutdown(); +} \ No newline at end of file From 13f9c59ad15b967281190dd1ab342de4daa9ac51 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 27 Feb 2024 23:39:14 +0000 Subject: [PATCH 7/7] Restyled by whitespace --- .../energy-management-common/src/PowerTopologyDelegate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp b/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp index 68ce4ff2358450..9f72d58cbc4983 100644 --- a/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp +++ b/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp @@ -40,4 +40,4 @@ CHIP_ERROR PowerTopologyInstance::Init() void PowerTopologyInstance::Shutdown() { Instance::Shutdown(); -} \ No newline at end of file +}