-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathdevice-energy-management-server.h
257 lines (229 loc) · 12.3 KB
/
device-energy-management-server.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/*
*
* Copyright (c) 2023 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 <app-common/zap-generated/cluster-objects.h>
#include <app/AttributeAccessInterface.h>
#include <app/CommandHandlerInterface.h>
#include <app/ConcreteAttributePath.h>
#include <app/InteractionModelEngine.h>
#include <app/MessageDef/StatusIB.h>
#include <app/reporting/reporting.h>
#include <app/util/attribute-storage.h>
#include <lib/core/CHIPError.h>
#include <protocols/interaction_model/StatusCode.h>
namespace chip {
namespace app {
namespace Clusters {
namespace DeviceEnergyManagement {
class Delegate
{
public:
virtual ~Delegate() = default;
void SetEndpointId(EndpointId aEndpoint) { mEndpointId = aEndpoint; }
/**
* @brief Delegate should implement a handler to begin to adjust client power
* consumption/generation to the level requested.
*
* Note callers must call GetPowerAdjustmentCapability and ensure the return value is not null
* before calling PowerAdjustRequest.
*
* @param power Milli-Watts the ESA SHALL use during the adjustment period.
* @param duration The duration that the ESA SHALL maintain the requested power for.
* @return Success if the adjustment is accepted; otherwise the command SHALL be rejected with appropriate error.
*/
virtual Protocols::InteractionModel::Status PowerAdjustRequest(const int64_t power, const uint32_t duration,
AdjustmentCauseEnum cause) = 0;
/**
* @brief Delegate SHALL make the ESA end the active power adjustment session & return to normal (or idle) power levels.
* The ESA SHALL also generate an PowerAdjustEnd Event and the ESAState SHALL be restored to Online.
*
* @return It should report SUCCESS if successful and FAILURE otherwise.
*/
virtual Protocols::InteractionModel::Status CancelPowerAdjustRequest() = 0;
/**
* @brief Delegate for the ESA SHALL update its Forecast attribute with the RequestedStartTime including a new ForecastID.
*
* If the ESA supports ForecastAdjustment, and the ESAState is not UserOptOut and the RequestedStartTime is after
* the EarliestStartTime and the resulting EndTime is before the LatestEndTime, then ESA SHALL accept the request
* to modify the Start Time.
* A client can estimate the entire Forecast sequence duration by computing the EndTime - StartTime fields from the
* Forecast attribute, and therefore avoid scheduling the start time too late.
*
* @param requestedStartTime The requested start time in UTC that the client would like the appliance to shift its power
* forecast to.
* @param cause Who (Grid/local) is triggering this change.
*
* @return Success if the StartTime in the Forecast is updated, otherwise the command SHALL be rejected with appropriate
* IM_Status.
*/
virtual Protocols::InteractionModel::Status StartTimeAdjustRequest(const uint32_t requestedStartTime,
AdjustmentCauseEnum cause) = 0;
/**
* @brief Delegate handler for PauseRequest command
*
* If the ESA supports FA and the SlotIsPauseable field is true in the ActiveSlotNumber
* index in the Slots list, and the ESAState is not UserOptOut then the ESA SHALL allow its current
* operation to be Paused.
*
* During this state the ESA SHALL not consume or produce significant power (other than required to keep its
* basic control system operational).
*
* @param duration Duration that the ESA SHALL be paused for.
* @return Success if the ESA is paused, otherwise returns other IM_Status.
*/
virtual Protocols::InteractionModel::Status PauseRequest(const uint32_t duration, AdjustmentCauseEnum cause) = 0;
/**
* @brief Delegate handler for ResumeRequest command
*
* If the ESA supports FA and it is currently Paused then the ESA SHALL resume its operation.
* The ESA SHALL also generate a Resumed Event and the ESAState SHALL be updated accordingly to
* reflect its current state.
*
* @return Success if the ESA is resumed, otherwise returns other IM_Status.
*/
virtual Protocols::InteractionModel::Status ResumeRequest() = 0;
/**
* @brief Delegate handler for ModifyForecastRequest
*
* If the ESA supports FA, and the ESAState is not UserOptOut it SHALL attempt to adjust its power forecast.
* This allows a one or more modifications in a single command by sending a list of modifications (one for each 'slot').
* Attempts to modify slots which have already past, SHALL result in the entire command being rejected.
* If the ESA accepts the requested Forecast then it SHALL update its Forecast attribute (incrementing its ForecastID)
* and run the revised Forecast as its new intended operation.
*
* @param forecastID Indicates the ESA ForecastID that is to be modified.
* @param slotAdjustments List of adjustments to be applied to the ESA, corresponding to the expected ESA forecastID.
* @return Success if the entire list of SlotAdjustmentStruct are accepted, otherwise the command
* SHALL be rejected returning other IM_Status.
*/
virtual Protocols::InteractionModel::Status
ModifyForecastRequest(const uint32_t forecastID,
const DataModel::DecodableList<Structs::SlotAdjustmentStruct::Type> & slotAdjustments,
AdjustmentCauseEnum cause) = 0;
/**
* @brief Delegate handler for RequestConstraintBasedForecast
*
* The ESA SHALL inspect the requested power limits to ensure that there are no overlapping elements. The ESA
* manufacturer may also reject the request if it could cause the user’s preferences to be breached (e.g. may
* cause the home to be too hot or too cold, or a battery to be insufficiently charged).
* If the ESA can meet the requested power limits, it SHALL regenerate a new Power Forecast with a new ForecastID.
*
* @param constraints Sequence of turn up/down power requests that the ESA is being asked to constrain its operation within.
* @return Success if successful, otherwise the command SHALL be rejected returning other IM_Status.
*/
virtual Protocols::InteractionModel::Status
RequestConstraintBasedForecast(const DataModel::DecodableList<Structs::ConstraintsStruct::Type> & constraints,
AdjustmentCauseEnum cause) = 0;
/**
* @brief Delegate handler for CancelRequest
*
* The ESA SHALL attempt to cancel the effects of any previous adjustment request commands, and re-evaluate its
* forecast for intended operation ignoring those previous requests.
*
* If the ESA ForecastStruct ForecastUpdateReason was already `Internal Optimization`, then the command SHALL
* be rejected with FAILURE.
*
* If the command is accepted, the ESA SHALL update its ESAState if required, and the command status returned
* SHALL be SUCCESS.
*
* The ESA SHALL update its Forecast attribute to match its new intended operation, and update the
* ForecastStruct.ForecastUpdateReason to `Internal Optimization`
*
* @return Success if successful, otherwise the command SHALL be rejected returning other IM_Status.
*/
virtual Protocols::InteractionModel::Status CancelRequest() = 0;
// ------------------------------------------------------------------
// Get attribute methods
virtual ESATypeEnum GetESAType() = 0;
virtual bool GetESACanGenerate() = 0;
virtual ESAStateEnum GetESAState() = 0;
virtual int64_t GetAbsMinPower() = 0;
virtual int64_t GetAbsMaxPower() = 0;
virtual OptOutStateEnum GetOptOutState() = 0;
/**
* @brief Returns the current PowerAdjustCapability object
*
* The reference returned from GetPowerAdjustmentCapability() is only valid until the next Matter event
* is processed. Callers must not hold on to that reference for any asynchronous processing.
*
* Once another Matter event has had a chance to run, the memory associated with the
* PowerAdjustCapabilityStruct is likely to change or be re-allocated, so would become invalid.
*
* @return The current PowerAdjustCapability object
*/
virtual const DataModel::Nullable<Structs::PowerAdjustCapabilityStruct::Type> & GetPowerAdjustmentCapability() = 0;
/**
* @brief Returns the current Forecast object
*
* The reference returned from GetForecast() is only valid until the next Matter event
* is processed. Callers must not hold on to that reference for any asynchronous processing.
*
* Once another Matter event has had a chance to run, the memory associated with the
* ForecastStruct is likely to change or be re-allocated, so would become invalid.
*
* @return The current Forecast object
*/
virtual const DataModel::Nullable<Structs::ForecastStruct::Type> & GetForecast() = 0;
// ------------------------------------------------------------------
// Set attribute methods
virtual CHIP_ERROR SetESAState(ESAStateEnum) = 0;
protected:
EndpointId mEndpointId = 0;
};
class Instance : public AttributeAccessInterface, public CommandHandlerInterface
{
public:
Instance(EndpointId aEndpointId, Delegate & aDelegate, Feature aFeature) :
AttributeAccessInterface(MakeOptional(aEndpointId), Id), CommandHandlerInterface(MakeOptional(aEndpointId), Id),
mDelegate(aDelegate), mFeature(aFeature)
{
/* set the base class delegates endpointId */
mDelegate.SetEndpointId(aEndpointId);
}
~Instance() { Shutdown(); }
CHIP_ERROR Init();
void Shutdown();
bool HasFeature(Feature aFeature) const;
private:
Protocols::InteractionModel::Status GetMatterEpochTimeFromUnixTime(uint32_t & currentUtcTime) const;
private:
Delegate & mDelegate;
BitMask<Feature> mFeature;
// AttributeAccessInterface
CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
// NOTE there are no writable attributes
// CommandHandlerInterface
void InvokeCommand(HandlerContext & handlerContext) override;
CHIP_ERROR EnumerateAcceptedCommands(const ConcreteClusterPath & cluster,
DataModel::ListBuilder<DataModel::AcceptedCommandEntry> & builder) override;
Protocols::InteractionModel::Status CheckOptOutAllowsRequest(AdjustmentCauseEnum adjustmentCause);
void HandlePowerAdjustRequest(HandlerContext & ctx, const Commands::PowerAdjustRequest::DecodableType & commandData);
void HandleCancelPowerAdjustRequest(HandlerContext & ctx,
const Commands::CancelPowerAdjustRequest::DecodableType & commandData);
void HandleStartTimeAdjustRequest(HandlerContext & ctx, const Commands::StartTimeAdjustRequest::DecodableType & commandData);
void HandlePauseRequest(HandlerContext & ctx, const Commands::PauseRequest::DecodableType & commandData);
void HandleResumeRequest(HandlerContext & ctx, const Commands::ResumeRequest::DecodableType & commandData);
void HandleModifyForecastRequest(HandlerContext & ctx, const Commands::ModifyForecastRequest::DecodableType & commandData);
void HandleRequestConstraintBasedForecast(HandlerContext & ctx,
const Commands::RequestConstraintBasedForecast::DecodableType & commandData);
void HandleCancelRequest(HandlerContext & ctx, const Commands::CancelRequest::DecodableType & commandData);
};
} // namespace DeviceEnergyManagement
} // namespace Clusters
} // namespace app
} // namespace chip