25
25
#include < PowerTopologyDelegate.h>
26
26
#include < device-energy-management-modes.h>
27
27
#include < energy-evse-modes.h>
28
+ #include < EnergyReportingMain.h>
29
+ #include < DEMDelegate.h>
28
30
29
31
#include < app-common/zap-generated/ids/Attributes.h>
30
32
#include < app-common/zap-generated/ids/Clusters.h>
36
38
#include < lib/support/logging/CHIPLogging.h>
37
39
#include < platform/Linux/NetworkCommissioningDriver.h>
38
40
39
- # define ENERGY_EVSE_ENDPOINT 1
41
+ static constexpr int ENERGY_EVSE_ENDPOINT = 1 ;
40
42
41
43
using namespace chip ;
42
44
using namespace chip ::app;
@@ -51,94 +53,16 @@ using namespace chip::app::Clusters::PowerTopology;
51
53
static std::unique_ptr<EnergyEvseDelegate> gEvseDelegate ;
52
54
static std::unique_ptr<EvseTargetsDelegate> gEvseTargetsDelegate ;
53
55
static std::unique_ptr<EnergyEvseManager> gEvseInstance ;
54
- static std::unique_ptr<DeviceEnergyManagementDelegate> gDEMDelegate ;
55
- static std::unique_ptr<DeviceEnergyManagementManager> gDEMInstance ;
56
+
56
57
static std::unique_ptr<EVSEManufacturer> gEvseManufacturer ;
57
- static std::unique_ptr<ElectricalPowerMeasurementDelegate> gEPMDelegate ;
58
- static std::unique_ptr<ElectricalPowerMeasurementInstance> gEPMInstance ;
59
- // Electrical Energy Measurement cluster uses ember to initialise
60
- static std::unique_ptr<ElectricalEnergyMeasurementAttrAccess> gEEMAttrAccess ;
61
58
62
- static std::unique_ptr<PowerTopologyDelegate> gPTDelegate ;
63
- static std::unique_ptr<PowerTopologyInstance> gPTInstance ;
64
59
65
60
EVSEManufacturer * EnergyEvse::GetEvseManufacturer ()
66
61
{
67
62
return gEvseManufacturer .get ();
68
63
}
69
64
70
- DeviceEnergyManagement::DeviceEnergyManagementDelegate * GetDEMDelegate ()
71
- {
72
- VerifyOrDieWithMsg (gDEMDelegate .get () != nullptr , AppServer, " DEM Delegate is null" );
73
-
74
- return gDEMDelegate .get ();
75
- }
76
-
77
- /*
78
- * @brief Creates a Delegate and Instance for DEM
79
- *
80
- * The Instance is a container around the Delegate, so
81
- * create the Delegate first, then wrap it in the Instance
82
- * Then call the Instance->Init() to register the attribute and command handlers
83
- */
84
- CHIP_ERROR DeviceEnergyManagementInit ()
85
- {
86
- if (gDEMDelegate || gDEMInstance )
87
- {
88
- ChipLogError (AppServer, " DEM Instance or Delegate already exist." );
89
- return CHIP_ERROR_INCORRECT_STATE;
90
- }
91
-
92
- gDEMDelegate = std::make_unique<DeviceEnergyManagementDelegate>();
93
- if (!gDEMDelegate )
94
- {
95
- ChipLogError (AppServer, " Failed to allocate memory for DeviceEnergyManagementDelegate" );
96
- return CHIP_ERROR_NO_MEMORY;
97
- }
98
-
99
- BitMask<DeviceEnergyManagement::Feature> featureMap = GetFeatureMapFromCmdLine ();
100
-
101
- /* Manufacturer may optionally not support all features, commands & attributes */
102
- gDEMInstance = std::make_unique<DeviceEnergyManagementManager>(EndpointId (ENERGY_EVSE_ENDPOINT), *gDEMDelegate , featureMap);
103
-
104
- if (!gDEMInstance )
105
- {
106
- ChipLogError (AppServer, " Failed to allocate memory for DeviceEnergyManagementManager" );
107
- gDEMDelegate .reset ();
108
- return CHIP_ERROR_NO_MEMORY;
109
- }
110
-
111
- gDEMDelegate ->SetDeviceEnergyManagementInstance (*gDEMInstance );
112
-
113
- CHIP_ERROR err = gDEMInstance ->Init (); /* Register Attribute & Command handlers */
114
- if (err != CHIP_NO_ERROR)
115
- {
116
- ChipLogError (AppServer, " Init failed on gDEMInstance" );
117
- gDEMInstance .reset ();
118
- gDEMDelegate .reset ();
119
- return err;
120
- }
121
-
122
- return CHIP_NO_ERROR;
123
- }
124
65
125
- CHIP_ERROR DeviceEnergyManagementShutdown ()
126
- {
127
- /* Do this in the order Instance first, then delegate
128
- * Ensure we call the Instance->Shutdown to free attribute & command handlers first
129
- */
130
- if (gDEMInstance )
131
- {
132
- /* deregister attribute & command handlers */
133
- gDEMInstance ->Shutdown ();
134
- gDEMInstance .reset ();
135
- }
136
- if (gDEMDelegate )
137
- {
138
- gDEMDelegate .reset ();
139
- }
140
- return CHIP_NO_ERROR;
141
- }
142
66
143
67
/*
144
68
* @brief Creates a Delegate and Instance for EVSE cluster
@@ -232,160 +156,6 @@ CHIP_ERROR EnergyEvseShutdown()
232
156
return CHIP_NO_ERROR;
233
157
}
234
158
235
- /*
236
- * @brief Creates a Delegate and Instance for PowerTopology clusters
237
- *
238
- * The Instance is a container around the Delegate, so
239
- * create the Delegate first, then wrap it in the Instance
240
- * Then call the Instance->Init() to register the attribute and command handlers
241
- */
242
- CHIP_ERROR PowerTopologyInit ()
243
- {
244
- CHIP_ERROR err;
245
-
246
- if (gPTDelegate || gPTInstance )
247
- {
248
- ChipLogError (AppServer, " PowerTopology Instance or Delegate already exist." );
249
- return CHIP_ERROR_INCORRECT_STATE;
250
- }
251
-
252
- gPTDelegate = std::make_unique<PowerTopologyDelegate>();
253
- if (!gPTDelegate )
254
- {
255
- ChipLogError (AppServer, " Failed to allocate memory for PowerTopology Delegate" );
256
- return CHIP_ERROR_NO_MEMORY;
257
- }
258
-
259
- gPTInstance =
260
- std::make_unique<PowerTopologyInstance>(EndpointId (ENERGY_EVSE_ENDPOINT), *gPTDelegate ,
261
- BitMask<PowerTopology::Feature, uint32_t >(PowerTopology::Feature::kNodeTopology ),
262
- BitMask<PowerTopology::OptionalAttributes, uint32_t >(0 ));
263
-
264
- if (!gPTInstance )
265
- {
266
- ChipLogError (AppServer, " Failed to allocate memory for PowerTopology Instance" );
267
- gPTDelegate .reset ();
268
- return CHIP_ERROR_NO_MEMORY;
269
- }
270
-
271
- err = gPTInstance ->Init (); /* Register Attribute & Command handlers */
272
- if (err != CHIP_NO_ERROR)
273
- {
274
- ChipLogError (AppServer, " Init failed on gPTInstance" );
275
- gPTInstance .reset ();
276
- gPTDelegate .reset ();
277
- return err;
278
- }
279
-
280
- return CHIP_NO_ERROR;
281
- }
282
-
283
- CHIP_ERROR PowerTopologyShutdown ()
284
- {
285
- /* Do this in the order Instance first, then delegate
286
- * Ensure we call the Instance->Shutdown to free attribute & command handlers first
287
- */
288
- if (gPTInstance )
289
- {
290
- /* deregister attribute & command handlers */
291
- gPTInstance ->Shutdown ();
292
- gPTInstance .reset ();
293
- }
294
-
295
- if (gPTDelegate )
296
- {
297
- gPTDelegate .reset ();
298
- }
299
-
300
- return CHIP_NO_ERROR;
301
- }
302
-
303
- /*
304
- * @brief Creates a Delegate and Instance for Electrical Power/Energy Measurement clusters
305
- *
306
- * The Instance is a container around the Delegate, so
307
- * create the Delegate first, then wrap it in the Instance
308
- * Then call the Instance->Init() to register the attribute and command handlers
309
- */
310
- CHIP_ERROR EnergyMeterInit ()
311
- {
312
- CHIP_ERROR err;
313
-
314
- if (gEPMDelegate || gEPMInstance )
315
- {
316
- ChipLogError (AppServer, " EPM Instance or Delegate already exist." );
317
- return CHIP_ERROR_INCORRECT_STATE;
318
- }
319
-
320
- gEPMDelegate = std::make_unique<ElectricalPowerMeasurementDelegate>();
321
- if (!gEPMDelegate )
322
- {
323
- ChipLogError (AppServer, " Failed to allocate memory for EPM Delegate" );
324
- return CHIP_ERROR_NO_MEMORY;
325
- }
326
-
327
- /* Manufacturer may optionally not support all features, commands & attributes */
328
- /* Turning on all optional features and attributes for test certification purposes */
329
- gEPMInstance = std::make_unique<ElectricalPowerMeasurementInstance>(
330
- EndpointId (ENERGY_EVSE_ENDPOINT), *gEPMDelegate ,
331
- BitMask<ElectricalPowerMeasurement::Feature, uint32_t >(
332
- ElectricalPowerMeasurement::Feature::kDirectCurrent , ElectricalPowerMeasurement::Feature::kAlternatingCurrent ,
333
- ElectricalPowerMeasurement::Feature::kPolyphasePower , ElectricalPowerMeasurement::Feature::kHarmonics ,
334
- ElectricalPowerMeasurement::Feature::kPowerQuality ),
335
- BitMask<ElectricalPowerMeasurement::OptionalAttributes, uint32_t >(
336
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRanges ,
337
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeVoltage ,
338
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeActiveCurrent ,
339
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactiveCurrent ,
340
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentCurrent ,
341
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactivePower ,
342
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentPower ,
343
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSVoltage ,
344
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSCurrent ,
345
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSPower ,
346
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeFrequency ,
347
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributePowerFactor ,
348
- ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeNeutralCurrent ));
349
-
350
- if (!gEPMInstance )
351
- {
352
- ChipLogError (AppServer, " Failed to allocate memory for EPM Instance" );
353
- gEPMDelegate .reset ();
354
- return CHIP_ERROR_NO_MEMORY;
355
- }
356
-
357
- err = gEPMInstance ->Init (); /* Register Attribute & Command handlers */
358
- if (err != CHIP_NO_ERROR)
359
- {
360
- ChipLogError (AppServer, " Init failed on gEPMInstance" );
361
- gEPMInstance .reset ();
362
- gEPMDelegate .reset ();
363
- return err;
364
- }
365
-
366
- return CHIP_NO_ERROR;
367
- }
368
-
369
- CHIP_ERROR EnergyMeterShutdown ()
370
- {
371
- /* Do this in the order Instance first, then delegate
372
- * Ensure we call the Instance->Shutdown to free attribute & command handlers first
373
- */
374
- if (gEPMInstance )
375
- {
376
- /* deregister attribute & command handlers */
377
- gEPMInstance ->Shutdown ();
378
- gEPMInstance .reset ();
379
- }
380
-
381
- if (gEPMDelegate )
382
- {
383
- gEPMDelegate .reset ();
384
- }
385
-
386
- return CHIP_NO_ERROR;
387
- }
388
-
389
159
/*
390
160
* @brief Creates a EVSEManufacturer class to hold the EVSE & DEM clusters
391
161
*
@@ -460,7 +230,6 @@ void EvseApplicationInit()
460
230
461
231
if (PowerTopologyInit () != CHIP_NO_ERROR)
462
232
{
463
- EVSEManufacturerShutdown ();
464
233
DeviceEnergyManagementShutdown ();
465
234
EnergyEvseShutdown ();
466
235
EnergyMeterShutdown ();
@@ -473,6 +242,7 @@ void EvseApplicationInit()
473
242
DeviceEnergyManagementShutdown ();
474
243
EnergyEvseShutdown ();
475
244
EnergyMeterShutdown ();
245
+ PowerTopologyShutdown ();
476
246
return ;
477
247
}
478
248
}
@@ -491,50 +261,3 @@ void EvseApplicationShutdown()
491
261
Clusters::DeviceEnergyManagementMode::Shutdown ();
492
262
Clusters::EnergyEvseMode::Shutdown ();
493
263
}
494
-
495
- void emberAfElectricalEnergyMeasurementClusterInitCallback (chip::EndpointId endpointId)
496
- {
497
- VerifyOrDie (endpointId == 1 ); // this cluster is only enabled for endpoint 1.
498
- VerifyOrDie (!gEEMAttrAccess );
499
-
500
- gEEMAttrAccess = std::make_unique<ElectricalEnergyMeasurementAttrAccess>(
501
- BitMask<ElectricalEnergyMeasurement::Feature, uint32_t >(
502
- ElectricalEnergyMeasurement::Feature::kImportedEnergy , ElectricalEnergyMeasurement::Feature::kExportedEnergy ,
503
- ElectricalEnergyMeasurement::Feature::kCumulativeEnergy , ElectricalEnergyMeasurement::Feature::kPeriodicEnergy ),
504
- BitMask<ElectricalEnergyMeasurement::OptionalAttributes, uint32_t >(
505
- ElectricalEnergyMeasurement::OptionalAttributes::kOptionalAttributeCumulativeEnergyReset ));
506
-
507
- // Create an accuracy entry which is between +/-0.5 and +/- 5% across the range of all possible energy readings
508
- ElectricalEnergyMeasurement::Structs::MeasurementAccuracyRangeStruct::Type energyAccuracyRanges[] = {
509
- { .rangeMin = 0 ,
510
- .rangeMax = 1'000'000'000'000'000 , // 1 million Mwh
511
- .percentMax = MakeOptional (static_cast <chip::Percent100ths>(500 )),
512
- .percentMin = MakeOptional (static_cast <chip::Percent100ths>(50 )) }
513
- };
514
-
515
- ElectricalEnergyMeasurement::Structs::MeasurementAccuracyStruct::Type accuracy = {
516
- .measurementType = MeasurementTypeEnum::kElectricalEnergy ,
517
- .measured = true ,
518
- .minMeasuredValue = 0 ,
519
- .maxMeasuredValue = 1'000'000'000'000'000 , // 1 million Mwh
520
- .accuracyRanges =
521
- DataModel::List<const ElectricalEnergyMeasurement::Structs::MeasurementAccuracyRangeStruct::Type>(energyAccuracyRanges)
522
- };
523
-
524
- // Example of setting CumulativeEnergyReset structure - for now set these to 0
525
- // but the manufacturer may want to store these in non volatile storage for timestamp (based on epoch_s)
526
- ElectricalEnergyMeasurement::Structs::CumulativeEnergyResetStruct::Type resetStruct = {
527
- .importedResetTimestamp = MakeOptional (MakeNullable (static_cast <uint32_t >(0 ))),
528
- .exportedResetTimestamp = MakeOptional (MakeNullable (static_cast <uint32_t >(0 ))),
529
- .importedResetSystime = MakeOptional (MakeNullable (static_cast <uint64_t >(0 ))),
530
- .exportedResetSystime = MakeOptional (MakeNullable (static_cast <uint64_t >(0 ))),
531
- };
532
-
533
- if (gEEMAttrAccess )
534
- {
535
- gEEMAttrAccess ->Init ();
536
-
537
- SetMeasurementAccuracy (endpointId, accuracy);
538
- SetCumulativeReset (endpointId, MakeOptional (resetStruct));
539
- }
540
- }
0 commit comments