Skip to content

Commit ce32d11

Browse files
jamesharrowrestyled-commitsbzbarsky-apple
authored
EVSE Delegate callbacks to user application (#30999)
* Fix #30665 (EVSE) - Changed to use amperage_mA, energy_mWh - removed max on epoch_s - removed access for operate - removed side for events * Fix #30665 updates to try to get further with ZAP and autogen, but still fails with some parts of regen_all * Added ember-compatibility-functions.cpp which was missing. * Made all types all lowercase to resolve regen_all issues. * Fixed lint issue (trailing whitespace). * Fixes #30727 - Added initial EVSE cluster and Example Energy Managament app. * Tidied up old comments. * Restyled by whitespace * Restyled by gn * Restyled by prettier-markdown * Added copy of files to all-clusters-app linux BUILD.gn and did basic test with chip-tool * Fixed lint error (Remove PRId64) * Fix for Documentation Build and publish checker. * Updated all-clusters-app.zap after merge and regen_all * Added Cluster to ESP32 CMakeLists.txt * Fixed ESP32 compile error caused by %d * Added missing source files to each build variant * Restyled by gn * Fixed incorrect uint64_t in EnableCharging/EnableDischarging command * Fixed more issues seen on different platforms * Removed unused mEndpointId * Add source files to shell standalone BUILD.gn, More %d fixes for different platforms * Restyled by gn * Removed unused mMinimumChargingCurrentLimitFromCommand * Removed yet more unused variables * Fixed missing semi-colon. How did the other compilers not pick this up? * Capitalise function names * PR comment - Moved PluginServerInitCallback to sdk. Capitalised more function names in energy-management-app. * Restyled by whitespace * Fixes #30805 Updated energy-evse-cluster.xml * Fixes #30805 zap_regen_all commit. * Made Fault Event allow a nullable SessionID * Updates based on review (use kMaximumChargeCurrent instead of duplicate #define). Add HwSetVehicleID implementation * Added RFID Event support. Removed more unnecessary chip:: * Added Feature flags, optional commands and optional attributes. * Made command handling conditional based on features * Added Feature support to all-clusters-app * Restyled by clang-format * Fix to Darwin compile error - not checking strcmp return * Attempt to fix Darwin errors (return after else) * Updated based on latest upstream master * Removed unnecessary mInstance and used 'this' instead. * Regen_all after merge to master. * Fix review comment. * Ensure Init() returns a failure if there is one. Aligned to mode-base-server.cpp * Backed out Read attr check based on features. * Fixed EnumerateAcceptedCommands to handle Loop::Break condition. * Had missed StartDiagnostic as an optional command in InvokeCommand * Removed extra chip:: in attr types. * Updated HwSetVehicleID to copy the value from callee * Fixed potential buffer overrun in HwSetVehicleID. * Fixed simple to address comments raised by Andrei in PR 30857 * Fixed simple to address comments raised by Andrei in PR 30857 * Check Delegate is initialized before calling functions. * Check Delegate is initialized before calling functions. * Added callbacks into Application code * Restyled by whitespace * Ensured that mVehicleID free's any malloc'd CharSpan in destructor * Sync EnergyEvseDelegateImpl.cpp from Example Energy Management * Ensured that mVehicleID free's any malloc'd CharSpan in destructor * Sync EnergyEvseDelegateImpl.cpp from Example Energy Management * Sync'd changes from example energy management app, and commits from #30857 & #30727 * Added namespace to avoid global namespace error in header file. * Re-write of ApplicationInit to handle potential errors * Re-write of ApplicationInit to handle potential errors * Removed unnecessary void in function decl. * Open and saved in ZAP, then regen_all * Updated Energy-management-app.zap / .matter after change to general-diagnostics.xml change to MS. * Updated Energy-management-app.zap / .matter after change to general-diagnostics.xml change to MS. * Restyled by whitespace * Fixed types to be signed=true * Fixed 31032 - revert removal of side="server". Also turned on Events. * PR comment fix - remove Localization Config and Time Format Localization cluster * Removed EVSE commands from ZAP to avoid emberAf linker errors since these are handled in the IM Commands handler * Regen_all to update energy-management.matter file to remove commands that cause linker errors. * Minor changes to align all-clusters and energy-management common. * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Addressed comment and replicated into example energy management copies. * Added documentation to EVSE Callbacks as to which struct in the union is used. * Added Energy EVSE and Device Energy Management to config-data.yml under CommandHandlerInterfaceOnlyClusters. Then turned on EVSE commands in ZAP. --------- Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent 13fd61d commit ce32d11

File tree

12 files changed

+448
-130
lines changed

12 files changed

+448
-130
lines changed

examples/all-clusters-app/all-clusters-common/all-clusters-app.matter

+9
Original file line numberDiff line numberDiff line change
@@ -7354,6 +7354,15 @@ endpoint 1 {
73547354
callback attribute attributeList;
73557355
ram attribute featureMap default = 0;
73567356
ram attribute clusterRevision default = 2;
7357+
7358+
handle command GetTargetsResponse;
7359+
handle command Disable;
7360+
handle command EnableCharging;
7361+
handle command EnableDischarging;
7362+
handle command StartDiagnostics;
7363+
handle command SetTargets;
7364+
handle command GetTargets;
7365+
handle command ClearTargets;
73577366
}
73587367

73597368
server cluster WindowCovering {

examples/all-clusters-app/all-clusters-common/all-clusters-app.zap

+66
Original file line numberDiff line numberDiff line change
@@ -11737,6 +11737,72 @@
1173711737
"side": "server",
1173811738
"enabled": 1,
1173911739
"apiMaturity": "provisional",
11740+
"commands": [
11741+
{
11742+
"name": "GetTargetsResponse",
11743+
"code": 0,
11744+
"mfgCode": null,
11745+
"source": "server",
11746+
"isIncoming": 0,
11747+
"isEnabled": 1
11748+
},
11749+
{
11750+
"name": "Disable",
11751+
"code": 1,
11752+
"mfgCode": null,
11753+
"source": "client",
11754+
"isIncoming": 1,
11755+
"isEnabled": 1
11756+
},
11757+
{
11758+
"name": "EnableCharging",
11759+
"code": 2,
11760+
"mfgCode": null,
11761+
"source": "client",
11762+
"isIncoming": 1,
11763+
"isEnabled": 1
11764+
},
11765+
{
11766+
"name": "EnableDischarging",
11767+
"code": 3,
11768+
"mfgCode": null,
11769+
"source": "client",
11770+
"isIncoming": 1,
11771+
"isEnabled": 1
11772+
},
11773+
{
11774+
"name": "StartDiagnostics",
11775+
"code": 4,
11776+
"mfgCode": null,
11777+
"source": "client",
11778+
"isIncoming": 1,
11779+
"isEnabled": 1
11780+
},
11781+
{
11782+
"name": "SetTargets",
11783+
"code": 5,
11784+
"mfgCode": null,
11785+
"source": "client",
11786+
"isIncoming": 1,
11787+
"isEnabled": 1
11788+
},
11789+
{
11790+
"name": "GetTargets",
11791+
"code": 6,
11792+
"mfgCode": null,
11793+
"source": "client",
11794+
"isIncoming": 1,
11795+
"isEnabled": 1
11796+
},
11797+
{
11798+
"name": "ClearTargets",
11799+
"code": 7,
11800+
"mfgCode": null,
11801+
"source": "client",
11802+
"isIncoming": 1,
11803+
"isEnabled": 1
11804+
}
11805+
],
1174011806
"attributes": [
1174111807
{
1174211808
"name": "State",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
*
3+
* Copyright (c) 2023 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
namespace chip {
22+
namespace app {
23+
namespace Clusters {
24+
25+
using namespace chip::app::Clusters::EnergyEvse;
26+
27+
/* This callbacks mechanism is intended to allow different delegates to
28+
* dispatch notifications that something has changed.
29+
*
30+
* This is not specific to the EnergyEVSE cluster, but includes DeviceEnergyManagement
31+
* and potential future clusters.
32+
*/
33+
enum EVSECallbackType
34+
{
35+
/*
36+
* The State has changed (e.g. from Disabled to Charging, or vice-versa)
37+
*/
38+
StateChanged,
39+
/*
40+
* ChargeCurrent has changed
41+
*/
42+
ChargeCurrentChanged,
43+
/*
44+
* Charging Preferences have changed
45+
*/
46+
ChargingPreferencesChanged,
47+
/*
48+
* DeviceEnergyManagement has changed
49+
*/
50+
DeviceEnergyManagementChanged,
51+
};
52+
53+
struct EVSECbInfo
54+
{
55+
EVSECallbackType type;
56+
57+
union
58+
{
59+
/* for type = StateChanged */
60+
struct
61+
{
62+
StateEnum state;
63+
SupplyStateEnum supplyState;
64+
} StateChange;
65+
66+
/* for type = ChargeCurrentChanged */
67+
struct
68+
{
69+
int64_t maximumChargeCurrent;
70+
} ChargingCurrent;
71+
};
72+
};
73+
74+
typedef void (*EVSECallbackFunc)(const EVSECbInfo * cb, intptr_t arg);
75+
76+
struct EVSECallbackWrapper
77+
{
78+
EVSECallbackFunc handler;
79+
intptr_t arg;
80+
};
81+
82+
} // namespace Clusters
83+
} // namespace app
84+
} // namespace chip

examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#pragma once
2020

2121
#include "app/clusters/energy-evse-server/energy-evse-server.h"
22+
#include <EVSECallbacks.h>
2223

2324
#include <app/util/af.h>
2425
#include <app/util/config.h>
@@ -68,9 +69,13 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate
6869
*/
6970
Status StartDiagnostics() override;
7071

72+
/**
73+
* @brief Called by EVSE Hardware to register a single callback handler
74+
*/
75+
Status HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg);
76+
7177
// -----------------------------------------------------------------
7278
// Internal API to allow an EVSE to change its internal state etc
73-
// TODO Status HwRegisterEvseHardwareCallback(Callback);
7479
Status HwSetMaxHardwareCurrentLimit(int64_t currentmA);
7580
Status HwSetCircuitCapacity(int64_t currentmA);
7681
Status HwSetCableAssemblyLimit(int64_t currentmA);
@@ -150,6 +155,11 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate
150155
int64_t mActualChargingCurrentLimit = 0;
151156
StateEnum mHwState = StateEnum::kNotPluggedIn; /* Hardware state */
152157

158+
/* Callback related */
159+
EVSECallbackWrapper mCallbacks = { .handler = nullptr, .arg = 0 }; /* Wrapper to allow callbacks to be registered */
160+
Status NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent);
161+
Status NotifyApplicationStateChange();
162+
153163
/**
154164
* @brief Helper function to work out the charge limit based on conditions and settings
155165
*/

examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp

+75-21
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Status EnergyEvseDelegate::Disable()
8383
/* update MaximumDischargeCurrent to 0 */
8484
SetMaximumDischargeCurrent(0);
8585

86+
NotifyApplicationStateChange();
8687
// TODO: Generate events
8788

8889
return Status::Success;
@@ -102,31 +103,31 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable<uint32_t> &
102103

103104
if (maximumChargeCurrent < kMinimumChargeCurrent || maximumChargeCurrent > kMaximumChargeCurrent)
104105
{
105-
ChipLogError(NotSpecified, "Maximum Current outside limits");
106+
ChipLogError(AppServer, "Maximum Current outside limits");
106107
return Status::ConstraintError;
107108
}
108109

109110
if (minimumChargeCurrent < kMinimumChargeCurrent || minimumChargeCurrent > kMaximumChargeCurrent)
110111
{
111-
ChipLogError(NotSpecified, "Maximum Current outside limits");
112+
ChipLogError(AppServer, "Maximum Current outside limits");
112113
return Status::ConstraintError;
113114
}
114115

115116
if (minimumChargeCurrent > maximumChargeCurrent)
116117
{
117-
ChipLogError(NotSpecified, "Minium Current > Maximum Current!");
118+
ChipLogError(AppServer, "Minium Current > Maximum Current!");
118119
return Status::ConstraintError;
119120
}
120121

121122
if (chargingEnabledUntil.IsNull())
122123
{
123124
/* Charging enabled indefinitely */
124-
ChipLogError(NotSpecified, "Charging enabled indefinitely");
125+
ChipLogError(AppServer, "Charging enabled indefinitely");
125126
}
126127
else
127128
{
128129
/* check chargingEnabledUntil is in the future */
129-
ChipLogError(NotSpecified, "Charging enabled until: %lu", static_cast<long unsigned int>(chargingEnabledUntil.Value()));
130+
ChipLogError(AppServer, "Charging enabled until: %lu", static_cast<long unsigned int>(chargingEnabledUntil.Value()));
130131
// TODO
131132
// if (checkChargingEnabled)
132133
}
@@ -169,6 +170,8 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable<uint32_t> &
169170

170171
// TODO: Generate events
171172

173+
NotifyApplicationStateChange();
174+
172175
return this->ComputeMaxChargeCurrentLimit();
173176
}
174177

@@ -188,6 +191,8 @@ Status EnergyEvseDelegate::EnableDischarging(const DataModel::Nullable<uint32_t>
188191

189192
// TODO: Generate events
190193

194+
NotifyApplicationStateChange();
195+
191196
return Status::Success;
192197
}
193198

@@ -199,25 +204,42 @@ Status EnergyEvseDelegate::StartDiagnostics()
199204
/* For EVSE manufacturers to customize */
200205
ChipLogProgress(AppServer, "EnergyEvseDelegate::StartDiagnostics()");
201206

202-
/* update SupplyState */
207+
/* update SupplyState to indicate we are now in Diagnostics mode */
203208
SetSupplyState(SupplyStateEnum::kDisabledDiagnostics);
204209

205210
// TODO: Generate events
206211

212+
// TODO: Notify Application to implement Diagnostics
213+
214+
NotifyApplicationStateChange();
215+
207216
return Status::Success;
208217
}
209218

210219
/* ---------------------------------------------------------------------------
211-
* FUNCTIONS BELOW:
212-
* - EVSE Hardware interface
220+
* EVSE Hardware interface below
221+
*/
222+
223+
/**
224+
* @brief Called by EVSE Hardware to register a callback handler mechanism
213225
*
214-
* SetMaxHardwareCurrentLimit( currentmA )
215-
* SetCircuitCapacity( currentmA )
216-
* SetCableAssemblyLimit( currentmA )
217-
* SetState( EVSEStateEnum )
218-
* SetFault
226+
* This is normally called at start-up.
219227
*
228+
* @param EVSECallbackFunct - function pointer to call
229+
* @param intptr_t - optional context to provide back to callback handler
220230
*/
231+
Status EnergyEvseDelegate::HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg)
232+
{
233+
if (mCallbacks.handler != nullptr)
234+
{
235+
ChipLogError(AppServer, "Callback handler already initialized");
236+
return Status::Failure;
237+
}
238+
mCallbacks.handler = handler;
239+
mCallbacks.arg = arg;
240+
241+
return Status::Success;
242+
}
221243

222244
/**
223245
* @brief Called by EVSE Hardware to notify the delegate of the maximum
@@ -420,17 +442,18 @@ Status EnergyEvseDelegate::HwSetVehicleID(const CharSpan & newValue)
420442

421443
/**
422444
* @brief Called to compute the safe charging current limit
445+
*
446+
* mActualChargingCurrentLimit is the minimum of:
447+
* - MaxHardwareCurrentLimit (of the hardware)
448+
* - CircuitCapacity (set by the electrician - less than the hardware)
449+
* - CableAssemblyLimit (detected when the cable is inserted)
450+
* - MaximumChargeCurrent (from charging command)
451+
* - UserMaximumChargeCurrent (could dynamically change)
452+
*
423453
*/
424454
Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit()
425455
{
426456
int64_t oldValue;
427-
/* mActualChargingCurrentLimit is the minimum of:
428-
* - MaxHardwareCurrentLimit (of the hardware)
429-
* - CircuitCapacity (set by the electrician - less than the hardware)
430-
* - CableAssemblyLimit (detected when the cable is inserted)
431-
* - MaximumChargeCurrent (from charging command)
432-
* - UserMaximumChargeCurrent (could dynamically change)
433-
*/
434457

435458
oldValue = mActualChargingCurrentLimit;
436459
mActualChargingCurrentLimit = mMaxHardwareCurrentLimit;
@@ -448,11 +471,42 @@ Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit()
448471
MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id);
449472

450473
/* Call the EV Charger hardware current limit callback */
451-
// TODO
474+
NotifyApplicationCurrentLimitChange(mMaximumChargeCurrent);
452475
}
453476
return Status::Success;
454477
}
455478

479+
Status EnergyEvseDelegate::NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent)
480+
{
481+
EVSECbInfo cbInfo;
482+
483+
cbInfo.type = EVSECallbackType::ChargeCurrentChanged;
484+
cbInfo.ChargingCurrent.maximumChargeCurrent = maximumChargeCurrent;
485+
486+
if (mCallbacks.handler != nullptr)
487+
{
488+
mCallbacks.handler(&cbInfo, mCallbacks.arg);
489+
}
490+
491+
return Status::Success;
492+
}
493+
494+
Status EnergyEvseDelegate::NotifyApplicationStateChange()
495+
{
496+
EVSECbInfo cbInfo;
497+
498+
cbInfo.type = EVSECallbackType::StateChanged;
499+
cbInfo.StateChange.state = mState;
500+
cbInfo.StateChange.supplyState = mSupplyState;
501+
502+
if (mCallbacks.handler != nullptr)
503+
{
504+
mCallbacks.handler(&cbInfo, mCallbacks.arg);
505+
}
506+
507+
return Status::Success;
508+
}
509+
456510
/**
457511
* Attribute methods
458512
*/

0 commit comments

Comments
 (0)