16
16
*/
17
17
18
18
#include " DeviceCallbacks.h"
19
+ #include < DeviceEnergyManagementManager.h>
19
20
#include < EVSEManufacturerImpl.h>
20
21
#include < EnergyEvseManager.h>
21
22
#include < EnergyManagementManager.h>
23
+ #include < device-energy-management-modes.h>
24
+ #include < energy-evse-modes.h>
22
25
23
26
#include " esp_log.h"
24
27
#include < common/CHIPDeviceManager.h>
@@ -74,9 +77,11 @@ using namespace ::chip::Credentials;
74
77
using namespace ::chip::DeviceManager;
75
78
using namespace ::chip::DeviceLayer;
76
79
77
- static EnergyEvseDelegate * gDelegate = nullptr ;
78
- static EnergyEvseManager * gInstance = nullptr ;
79
- static EVSEManufacturer * gEvseManufacturer = nullptr ;
80
+ static std::unique_ptr<EnergyEvseDelegate> gEvseDelegate ;
81
+ static std::unique_ptr<EnergyEvseManager> gEvseInstance ;
82
+ static std::unique_ptr<DeviceEnergyManagementDelegate> gDEMDelegate ;
83
+ static std::unique_ptr<DeviceEnergyManagementManager> gDEMInstance ;
84
+ static std::unique_ptr<EVSEManufacturer> gEvseManufacturer ;
80
85
81
86
#if CONFIG_ENABLE_ESP_INSIGHTS_TRACE
82
87
extern const char insights_auth_key_start[] asm (" _binary_insights_auth_key_txt_start" );
@@ -116,44 +121,238 @@ chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void)
116
121
117
122
} // namespace
118
123
119
- void ApplicationInit ()
124
+ EVSEManufacturer * EnergyEvse::GetEvseManufacturer ()
125
+ {
126
+ return gEvseManufacturer .get ();
127
+ }
128
+
129
+ /*
130
+ * @brief Creates a Delegate and Instance for DEM
131
+ *
132
+ * The Instance is a container around the Delegate, so
133
+ * create the Delegate first, then wrap it in the Instance
134
+ * Then call the Instance->Init() to register the attribute and command handlers
135
+ */
136
+ CHIP_ERROR DeviceEnergyManagementInit ()
137
+ {
138
+ if (gDEMDelegate || gDEMInstance )
139
+ {
140
+ ESP_LOGE (TAG, " DEM Instance or Delegate already exist." );
141
+ return CHIP_ERROR_INCORRECT_STATE;
142
+ }
143
+
144
+ gDEMDelegate = std::make_unique<DeviceEnergyManagementDelegate>();
145
+ if (!gDEMDelegate )
146
+ {
147
+ ESP_LOGE (TAG, " Failed to allocate memory for DeviceEnergyManagementDelegate" );
148
+ return CHIP_ERROR_NO_MEMORY;
149
+ }
150
+
151
+ /* Manufacturer may optionally not support all features, commands & attributes */
152
+ gDEMInstance = std::make_unique<DeviceEnergyManagementManager>(
153
+ EndpointId (ENERGY_EVSE_ENDPOINT), *gDEMDelegate ,
154
+ BitMask<DeviceEnergyManagement::Feature, uint32_t >(
155
+ DeviceEnergyManagement::Feature::kPowerAdjustment , DeviceEnergyManagement::Feature::kPowerForecastReporting ,
156
+ DeviceEnergyManagement::Feature::kStateForecastReporting , DeviceEnergyManagement::Feature::kStartTimeAdjustment ,
157
+ DeviceEnergyManagement::Feature::kPausable , DeviceEnergyManagement::Feature::kForecastAdjustment ,
158
+ DeviceEnergyManagement::Feature::kConstraintBasedAdjustment ));
159
+
160
+ if (!gDEMInstance )
161
+ {
162
+ ESP_LOGE (TAG, " Failed to allocate memory for DeviceEnergyManagementManager" );
163
+ gDEMDelegate .reset ();
164
+ return CHIP_ERROR_NO_MEMORY;
165
+ }
166
+
167
+ CHIP_ERROR err = gDEMInstance ->Init (); /* Register Attribute & Command handlers */
168
+ if (err != CHIP_NO_ERROR)
169
+ {
170
+ ESP_LOGE (TAG, " Init failed on gDEMInstance, err:%" CHIP_ERROR_FORMAT, err.Format ());
171
+ gDEMInstance .reset ();
172
+ gDEMDelegate .reset ();
173
+ return err;
174
+ }
175
+
176
+ return CHIP_NO_ERROR;
177
+ }
178
+
179
+ CHIP_ERROR DeviceEnergyManagementShutdown ()
120
180
{
121
- if ((gDelegate == nullptr ) && (gInstance == nullptr ) && (gEvseManufacturer == nullptr ))
181
+ /* Do this in the order Instance first, then delegate
182
+ * Ensure we call the Instance->Shutdown to free attribute & command handlers first
183
+ */
184
+ if (gDEMInstance )
122
185
{
123
- gDelegate = new EnergyEvseDelegate ();
124
- if (gDelegate != nullptr )
125
- {
126
- gInstance = new EnergyEvseManager (
127
- EndpointId (ENERGY_EVSE_ENDPOINT), *gDelegate ,
128
- BitMask<EnergyEvse::Feature, uint32_t >(EnergyEvse::Feature::kChargingPreferences ,
129
- EnergyEvse::Feature::kPlugAndCharge , EnergyEvse::Feature::kRfid ,
130
- EnergyEvse::Feature::kSoCReporting , EnergyEvse::Feature::kV2x ),
131
- BitMask<OptionalAttributes, uint32_t >(OptionalAttributes::kSupportsUserMaximumChargingCurrent ,
132
- OptionalAttributes::kSupportsRandomizationWindow ,
133
- OptionalAttributes::kSupportsApproximateEvEfficiency ),
134
- BitMask<OptionalCommands, uint32_t >(OptionalCommands::kSupportsStartDiagnostics ));
135
- gInstance ->Init (); /* Register Attribute & Command handlers */
136
- }
186
+ /* deregister attribute & command handlers */
187
+ gDEMInstance ->Shutdown ();
188
+ gDEMInstance .reset ();
137
189
}
138
- else
190
+ if ( gDEMDelegate )
139
191
{
140
- ChipLogError (AppServer, " EVSE Instance or Delegate already exist. " )
192
+ gDEMDelegate . reset ();
141
193
}
194
+ return CHIP_NO_ERROR;
195
+ }
196
+
197
+ /*
198
+ * @brief Creates a Delegate and Instance for EVSE cluster
199
+ *
200
+ * The Instance is a container around the Delegate, so
201
+ * create the Delegate first, then wrap it in the Instance
202
+ * Then call the Instance->Init() to register the attribute and command handlers
203
+ */
204
+ CHIP_ERROR EnergyEvseInit ()
205
+ {
206
+ CHIP_ERROR err;
142
207
143
- if (gEvseManufacturer == nullptr )
208
+ if (gEvseDelegate || gEvseInstance )
144
209
{
145
- gEvseManufacturer = new EVSEManufacturer ( );
146
- gEvseManufacturer -> Init ( gInstance ) ;
210
+ ESP_LOGE (TAG, " EVSE Instance or Delegate already exist. " );
211
+ return CHIP_ERROR_INCORRECT_STATE ;
147
212
}
148
- else
213
+
214
+ gEvseDelegate = std::make_unique<EnergyEvseDelegate>();
215
+ if (!gEvseDelegate )
216
+ {
217
+ ESP_LOGE (TAG, " Failed to allocate memory for EnergyEvseDelegate" );
218
+ return CHIP_ERROR_NO_MEMORY;
219
+ }
220
+
221
+ /* Manufacturer may optionally not support all features, commands & attributes */
222
+ gEvseInstance = std::make_unique<EnergyEvseManager>(
223
+ EndpointId (ENERGY_EVSE_ENDPOINT), *gEvseDelegate ,
224
+ BitMask<EnergyEvse::Feature, uint32_t >(EnergyEvse::Feature::kChargingPreferences , EnergyEvse::Feature::kPlugAndCharge ,
225
+ EnergyEvse::Feature::kRfid , EnergyEvse::Feature::kSoCReporting ,
226
+ EnergyEvse::Feature::kV2x ),
227
+ BitMask<EnergyEvse::OptionalAttributes, uint32_t >(EnergyEvse::OptionalAttributes::kSupportsUserMaximumChargingCurrent ,
228
+ EnergyEvse::OptionalAttributes::kSupportsRandomizationWindow ,
229
+ EnergyEvse::OptionalAttributes::kSupportsApproximateEvEfficiency ),
230
+ BitMask<EnergyEvse::OptionalCommands, uint32_t >(EnergyEvse::OptionalCommands::kSupportsStartDiagnostics ));
231
+
232
+ if (!gEvseInstance )
149
233
{
150
- ChipLogError (AppServer, " EVSEManufacturer already exists." )
234
+ ESP_LOGE (TAG, " Failed to allocate memory for EnergyEvseManager" );
235
+ gEvseDelegate .reset ();
236
+ return CHIP_ERROR_NO_MEMORY;
151
237
}
238
+
239
+ err = gEvseInstance ->Init (); /* Register Attribute & Command handlers */
240
+ if (err != CHIP_NO_ERROR)
241
+ {
242
+ ESP_LOGE (TAG, " Init failed on gEvseInstance, err:%" CHIP_ERROR_FORMAT, err.Format ());
243
+ gEvseInstance .reset ();
244
+ gEvseDelegate .reset ();
245
+ return err;
246
+ }
247
+
248
+ return CHIP_NO_ERROR;
249
+ }
250
+
251
+ CHIP_ERROR EnergyEvseShutdown ()
252
+ {
253
+ /* Do this in the order Instance first, then delegate
254
+ * Ensure we call the Instance->Shutdown to free attribute & command handlers first
255
+ */
256
+ if (gEvseInstance )
257
+ {
258
+ /* deregister attribute & command handlers */
259
+ gEvseInstance ->Shutdown ();
260
+ gEvseInstance .reset ();
261
+ }
262
+
263
+ if (gEvseDelegate )
264
+ {
265
+ gEvseDelegate .reset ();
266
+ }
267
+
268
+ return CHIP_NO_ERROR;
269
+ }
270
+
271
+ /*
272
+ * @brief Creates a EVSEManufacturer class to hold the EVSE & DEM clusters
273
+ *
274
+ * The Instance is a container around the Delegate, so
275
+ * create the Delegate first, then wrap it in the Instance
276
+ * Then call the Instance->Init() to register the attribute and command handlers
277
+ */
278
+ CHIP_ERROR EVSEManufacturerInit ()
279
+ {
280
+ CHIP_ERROR err;
281
+
282
+ if (gEvseManufacturer )
283
+ {
284
+ ESP_LOGE (TAG, " EvseManufacturer already exist." );
285
+ return CHIP_ERROR_INCORRECT_STATE;
286
+ }
287
+
288
+ /* Now create EVSEManufacturer */
289
+ gEvseManufacturer = std::make_unique<EVSEManufacturer>(gEvseInstance .get ());
290
+ if (!gEvseManufacturer )
291
+ {
292
+ ESP_LOGE (TAG, " Failed to allocate memory for EvseManufacturer" );
293
+ return CHIP_ERROR_NO_MEMORY;
294
+ }
295
+
296
+ /* Call Manufacturer specific init */
297
+ err = gEvseManufacturer ->Init ();
298
+ if (err != CHIP_NO_ERROR)
299
+ {
300
+ ESP_LOGE (TAG, " Init failed on gEvseManufacturer, err:%" CHIP_ERROR_FORMAT, err.Format ());
301
+ gEvseManufacturer .reset ();
302
+ return err;
303
+ }
304
+
305
+ return CHIP_NO_ERROR;
306
+ }
307
+
308
+ CHIP_ERROR EVSEManufacturerShutdown ()
309
+ {
310
+ if (gEvseManufacturer )
311
+ {
312
+ /* Shutdown the EVSEManufacturer */
313
+ gEvseManufacturer ->Shutdown ();
314
+ gEvseManufacturer .reset ();
315
+ }
316
+
317
+ return CHIP_NO_ERROR;
318
+ }
319
+
320
+ void ApplicationInit ()
321
+ {
322
+ if (DeviceEnergyManagementInit () != CHIP_NO_ERROR)
323
+ {
324
+ return ;
325
+ }
326
+
327
+ if (EnergyEvseInit () != CHIP_NO_ERROR)
328
+ {
329
+ DeviceEnergyManagementShutdown ();
330
+ return ;
331
+ }
332
+
333
+ if (EVSEManufacturerInit () != CHIP_NO_ERROR)
334
+ {
335
+ DeviceEnergyManagementShutdown ();
336
+ EnergyEvseShutdown ();
337
+ return ;
338
+ }
339
+ }
340
+
341
+ void ApplicationShutdown ()
342
+ {
343
+ ESP_LOGD (TAG, " Energy Management App: ApplicationShutdown()" );
344
+
345
+ /* Shutdown in reverse order that they were created */
346
+ EVSEManufacturerShutdown (); /* Free the EVSEManufacturer */
347
+ EnergyEvseShutdown (); /* Free the EnergyEvse */
348
+ DeviceEnergyManagementShutdown (); /* Free the DEM */
349
+
350
+ Clusters::DeviceEnergyManagementMode::Shutdown ();
351
+ Clusters::EnergyEvseMode::Shutdown ();
152
352
}
153
353
154
354
static void InitServer (intptr_t context)
155
355
{
156
- ApplicationInit ();
157
356
// Print QR Code URL
158
357
PrintOnboardingCodes (chip::RendezvousInformationFlags (CONFIG_RENDEZVOUS_MODE));
159
358
@@ -175,6 +374,9 @@ static void InitServer(intptr_t context)
175
374
static Tracing::Insights::ESP32Backend backend;
176
375
Tracing::Register (backend);
177
376
#endif
377
+
378
+ // Application code should always be initialised after the initialisation of server.
379
+ ApplicationInit ();
178
380
}
179
381
180
382
extern " C" void app_main ()
0 commit comments