Skip to content

Commit c341697

Browse files
committed
Added Clear Targets support and initial implementation of SetTargets
1 parent ff53867 commit c341697

File tree

3 files changed

+161
-123
lines changed

3 files changed

+161
-123
lines changed

examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp

+6-29
Original file line numberDiff line numberDiff line change
@@ -371,36 +371,9 @@ Status EnergyEvseDelegate::SaveTargets(
371371
}
372372

373373
/**
374-
* @brief Called when EVSE cluster receives GetTargets command
374+
* @brief Called when EVSE cluster receives GetTargets command to load the
375+
* targets into RAM and create an iterator for the cluster server to use
375376
*/
376-
377-
Structs::ChargingTargetStruct::Type dailyTargetArrayDay1[3] = {
378-
{ .targetTimeMinutesPastMidnight = static_cast<uint16_t>(120), .addedEnergy = MakeOptional(10000) },
379-
{ .targetTimeMinutesPastMidnight = static_cast<uint16_t>(800), .addedEnergy = MakeOptional(5000) },
380-
{ .targetTimeMinutesPastMidnight = static_cast<uint16_t>(1200), .addedEnergy = MakeOptional(2000) },
381-
};
382-
Structs::ChargingTargetStruct::Type dailyTargetArrayDay2[1] = {
383-
{ .targetTimeMinutesPastMidnight = static_cast<uint16_t>(800), .addedEnergy = MakeOptional(5000) },
384-
};
385-
Structs::ChargingTargetStruct::Type dailyTargetArrayDay3[1] = {
386-
{ .targetTimeMinutesPastMidnight = static_cast<uint16_t>(1200), .addedEnergy = MakeOptional(2000) },
387-
};
388-
389-
Structs::ChargingTargetScheduleStruct::Type array[3] = {
390-
{
391-
.dayOfWeekForSequence = 0x40,
392-
.chargingTargets = DataModel::List<const Structs::ChargingTargetStruct::Type>(dailyTargetArrayDay1),
393-
},
394-
{
395-
.dayOfWeekForSequence = 0x10,
396-
.chargingTargets = DataModel::List<const Structs::ChargingTargetStruct::Type>(dailyTargetArrayDay2),
397-
},
398-
{
399-
.dayOfWeekForSequence = 0x01,
400-
.chargingTargets = DataModel::List<const Structs::ChargingTargetStruct::Type>(dailyTargetArrayDay3),
401-
402-
},
403-
};
404377
CHIP_ERROR EnergyEvseDelegate::PrepareGetTargets(EvseTargetIterator ** iterator)
405378
{
406379
CHIP_ERROR err;
@@ -420,6 +393,10 @@ CHIP_ERROR EnergyEvseDelegate::PrepareGetTargets(EvseTargetIterator ** iterator)
420393
return err;
421394
}
422395

396+
/**
397+
* @brief Called when EVSE cluster has finished copying the data into the
398+
* GetTargetsResponse to free up memory
399+
*/
423400
CHIP_ERROR EnergyEvseDelegate::GetTargetsFinished()
424401
{
425402
CHIP_ERROR err;

examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp

+154-94
Original file line numberDiff line numberDiff line change
@@ -79,86 +79,6 @@ CHIP_ERROR EvseTargetIteratorImpl::Load()
7979
return CHIP_NO_ERROR;
8080
}
8181

82-
/**
83-
* This function tries to compress a list of entries which has:
84-
* dayOfWeek bitmask
85-
* chargingTargetsList
86-
*
87-
* It takes a new entry and scans the existing list to see if the
88-
* dayOfWeek bitmask is already included somewhere
89-
*
90-
* compute bitmask values:
91-
*
92-
* bitmaskA: (entry.bitmask & bitmask)
93-
* work out which bits in the existing entry are the same (overlapping)
94-
*
95-
* Create and append a new entry for the bits that are the same
96-
* newEntry.bitmask = bitmaskA;
97-
* newEntry.chargingTargetsList = chargingTargetsList
98-
*
99-
* if entry.bitmask == bitmaskA
100-
* this entry is being deleted and can share the newEntry
101-
* delete it
102-
*
103-
* bitmaskB = (entry.bitmask & ~bitmask);
104-
* work out which bits in the existing entry are different
105-
* Remove these bits from the existing entry, (effectively deleting them)
106-
* entry.bitmask = bitmaskB;
107-
*
108-
* NOTE: if `all` bits are removed then the existing entry can be deleted,
109-
* but that's not possible because we check for a full match first
110-
*
111-
* We continue walking our list to see if other entries have overlapping bits
112-
* If they do, then the newEntry.bitmask |= bitmaskA
113-
*
114-
*/
115-
CHIP_ERROR EvseTargetsDelegate::CopyTarget(const Structs::ChargingTargetScheduleStruct::DecodableType & newEntry)
116-
{
117-
// Structs::ChargingTargetScheduleStruct::DecodableType createdEntry;
118-
// uint8_t newEntryBitmask = 0;
119-
// uint8_t bitmaskA;
120-
// uint8_t bitmaskB;
121-
122-
// DataModel::List<Structs::ChargingTargetScheduleStruct::DecodableType> updatedList;
123-
124-
// uint8_t bitmask = newEntry.dayOfWeekForSequence.GetField(static_cast<TargetDayOfWeekBitmap>(0x7F));
125-
// ChipLogProgress(AppServer, "DayOfWeekForSequence = 0x%02x", bitmask);
126-
127-
// auto iter = mTargets.begin();
128-
// while (iter->Next())
129-
// {
130-
// auto & entry = iter->GetValue();
131-
// uint8_t entryBitmask = entry.dayOfWeekForSequence.GetField(static_cast<TargetDayOfWeekBitmap>(0x7F));
132-
133-
// bitmaskA = entryBitmask & bitmask;
134-
// bitmaskB = entryBitmask & ~bitmask;
135-
// newEntryBitmask |= bitmaskA;
136-
// if (entryBitmask == bitmaskA)
137-
// {
138-
// /* This entry has the all the same bits as the newEntry
139-
// * Delete this entry - we don't copy it
140-
// */
141-
// }
142-
// else
143-
// {
144-
// /* this entry stays - but it has lost some days from the bitmask */
145-
// entry.dayOfWeekForSequence = BitMask<TargetDayOfWeekBitmap>(bitmaskB);
146-
// updatedList.Put(entry);
147-
// }
148-
// }
149-
150-
// /* Append new entry */
151-
// ChipLogDetail(AppServer, "Adding new entry with bitmask 0x%02x", newEntryBitmask);
152-
// createdEntry.dayOfWeekForSequence = static_cast<TargetDayOfWeekBitmap>(newEntryBitmask);
153-
// createdEntry.chargingTargets = newEntry.chargingTargets;
154-
// updatedList.Put(createdEntry);
155-
156-
// /* delete our original mTargets */
157-
// mTargets = updatedList; // TODO check this doesn't cause a memory leak?
158-
159-
return CHIP_NO_ERROR;
160-
}
161-
16282
CHIP_ERROR EvseTargetsDelegate::Init(PersistentStorageDelegate * targetStore)
16383
{
16484
ChipLogProgress(AppServer, "EVSE: Initializing EvseTargetsDelegate");
@@ -369,6 +289,157 @@ CHIP_ERROR EvseTargetsDelegate::SerializeToTlv(TLV::TLVWriter & writer, const st
369289
return writer.EndContainer(arrayType);
370290
}
371291

292+
/**
293+
* This function tries to compress a list of entries which has:
294+
* dayOfWeek bitmask
295+
* chargingTargetsList
296+
*
297+
* It takes a new entry and scans the existing list to see if the
298+
* dayOfWeek bitmask is already included somewhere
299+
*
300+
* compute bitmask values:
301+
*
302+
* bitmaskA: (entry.bitmask & bitmask)
303+
* work out which bits in the existing entry are the same (overlapping)
304+
*
305+
* Create and append a new entry for the bits that are the same
306+
* newEntry.bitmask = bitmaskA;
307+
* newEntry.chargingTargetsList = chargingTargetsList
308+
*
309+
* if entry.bitmask == bitmaskA
310+
* this entry is being deleted and can share the newEntry
311+
* delete it
312+
*
313+
* bitmaskB = (entry.bitmask & ~bitmask);
314+
* work out which bits in the existing entry are different
315+
* Remove these bits from the existing entry, (effectively deleting them)
316+
* entry.bitmask = bitmaskB;
317+
*
318+
* NOTE: if `all` bits are removed then the existing entry can be deleted,
319+
* but that's not possible because we check for a full match first
320+
*
321+
* We continue walking our list to see if other entries have overlapping bits
322+
* If they do, then the newEntry.bitmask |= bitmaskA
323+
*
324+
*/
325+
#if 0
326+
CHIP_ERROR EvseTargetsDelegate::CopyTarget(const Structs::ChargingTargetScheduleStruct::DecodableType & newEntry)
327+
{
328+
Structs::ChargingTargetScheduleStruct::DecodableType createdEntry;
329+
uint8_t newEntryBitmask = 0;
330+
uint8_t bitmaskA;
331+
uint8_t bitmaskB;
332+
333+
DataModel::List<Structs::ChargingTargetScheduleStruct::DecodableType> updatedList;
334+
335+
uint8_t bitmask = newEntry.dayOfWeekForSequence.GetField(static_cast<TargetDayOfWeekBitmap>(0x7F));
336+
ChipLogProgress(AppServer, "DayOfWeekForSequence = 0x%02x", bitmask);
337+
338+
auto iter = mTargets.begin();
339+
while (iter->Next())
340+
{
341+
auto & entry = iter->GetValue();
342+
uint8_t entryBitmask = entry.dayOfWeekForSequence.GetField(static_cast<TargetDayOfWeekBitmap>(0x7F));
343+
344+
bitmaskA = entryBitmask & bitmask;
345+
bitmaskB = entryBitmask & ~bitmask;
346+
newEntryBitmask |= bitmaskA;
347+
if (entryBitmask == bitmaskA)
348+
{
349+
/* This entry has the all the same bits as the newEntry
350+
* Delete this entry - we don't copy it
351+
*/
352+
}
353+
else
354+
{
355+
/* this entry stays - but it has lost some days from the bitmask */
356+
entry.dayOfWeekForSequence = BitMask<TargetDayOfWeekBitmap>(bitmaskB);
357+
updatedList.Put(entry);
358+
}
359+
}
360+
361+
/* Append new entry */
362+
ChipLogDetail(AppServer, "Adding new entry with bitmask 0x%02x", newEntryBitmask);
363+
createdEntry.dayOfWeekForSequence = static_cast<TargetDayOfWeekBitmap>(newEntryBitmask);
364+
createdEntry.chargingTargets = newEntry.chargingTargets;
365+
updatedList.Put(createdEntry);
366+
367+
/* delete our original mTargets */
368+
mTargets = updatedList; // TODO check this doesn't cause a memory leak?
369+
370+
return CHIP_NO_ERROR;
371+
}
372+
#endif
373+
CHIP_ERROR EvseTargetsDelegate::CopyTarget(const Structs::ChargingTargetScheduleStruct::DecodableType & newDataModelEntry)
374+
{
375+
uint8_t newEntryBitmask = 0;
376+
uint8_t bitmaskA;
377+
uint8_t bitmaskB;
378+
379+
std::vector<EvseTargetEntry> targetEntryVector;
380+
size_t targetEntrySize = MaxTargetEntrySize();
381+
ReturnErrorOnFailure(Load(targetEntryVector, targetEntrySize));
382+
383+
uint8_t bitmask = newDataModelEntry.dayOfWeekForSequence.GetField(static_cast<TargetDayOfWeekBitmap>(0x7F));
384+
ChipLogProgress(AppServer, "DayOfWeekForSequence = 0x%02x", bitmask);
385+
386+
for (auto entry = targetEntryVector.begin(); entry != targetEntryVector.end(); entry++)
387+
{
388+
uint8_t entryBitmask = entry->dayOfWeekMap.GetField(static_cast<TargetDayOfWeekBitmap>(0x7F));
389+
390+
bitmaskA = entryBitmask & bitmask;
391+
bitmaskB = entryBitmask & ~bitmask;
392+
newEntryBitmask |= bitmaskA;
393+
if (entryBitmask == bitmaskA)
394+
{
395+
/* This entry has the all the same bits as the newEntry
396+
* Delete this entry - we don't copy it
397+
*/
398+
targetEntryVector.erase(entry);
399+
ReturnErrorOnFailure(DecreaseEntryCount());
400+
}
401+
else
402+
{
403+
/* this entry stays - but it has lost some days from the bitmask */
404+
entry->dayOfWeekMap = BitMask<TargetDayOfWeekBitmap>(bitmaskB);
405+
}
406+
}
407+
408+
// Add the new Entry - we have to convert it from DatatModel format to storage format
409+
EvseTargetEntry newStorageEntry;
410+
newStorageEntry.dayOfWeekMap = newDataModelEntry.dayOfWeekForSequence;
411+
412+
auto it = newDataModelEntry.chargingTargets.begin();
413+
while (it.Next())
414+
{
415+
auto & chargingTargetStruct = it.GetValue();
416+
EvseChargingTarget temp;
417+
418+
temp.targetTimeMinutesPastMidnight = chargingTargetStruct.targetTimeMinutesPastMidnight;
419+
temp.targetSoC = chargingTargetStruct.targetSoC;
420+
temp.addedEnergy = chargingTargetStruct.addedEnergy;
421+
newStorageEntry.dailyChargingTargets.push_back(temp);
422+
}
423+
424+
targetEntryVector.push_back(newStorageEntry);
425+
426+
size_t total = targetEntrySize * targetEntryVector.size() + kArrayOverHead;
427+
Platform::ScopedMemoryBuffer<uint8_t> backingBuffer;
428+
ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY);
429+
TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total);
430+
431+
ReturnErrorOnFailure(SerializeToTlv(writer, targetEntryVector));
432+
433+
const auto len = writer.GetLengthWritten();
434+
VerifyOrReturnError(CanCastTo<uint16_t>(len), CHIP_ERROR_BUFFER_TOO_SMALL);
435+
436+
writer.Finalize(backingBuffer);
437+
ReturnErrorOnFailure(mpTargetStore->SyncSetKeyValue(DefaultStorageKeyAllocator::EVSETargets().KeyName(), backingBuffer.Get(),
438+
static_cast<uint16_t>(len)));
439+
440+
return IncreaseEntryCount();
441+
}
442+
372443
CHIP_ERROR EvseTargetsDelegate::StoreEntry(const EvseTargetEntry & entry)
373444
{
374445
std::vector<EvseTargetEntry> targetEntryVector;
@@ -404,20 +475,9 @@ CHIP_ERROR EvseTargetsDelegate::StoreEntry(const EvseTargetEntry & entry)
404475

405476
CHIP_ERROR EvseTargetsDelegate::ClearTargets()
406477
{
407-
EvseTargetIteratorImpl * iterator = GetEvseTargetsIterator();
408-
EvseTargetEntry entry;
409-
CHIP_ERROR err;
410-
411-
while (iterator->Next(entry))
412-
{
413-
err = DeleteEntry(entry);
414-
if (CHIP_NO_ERROR == err)
415-
{
416-
iterator->Release();
417-
return CHIP_NO_ERROR;
418-
}
419-
}
420-
iterator->Release();
478+
/* We simply delete the data from the persistent store */
479+
mpTargetStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::EVSETargets().KeyName());
480+
mpTargetStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::EvseTargetEntryCounter().KeyName());
421481
return CHIP_NO_ERROR;
422482
}
423483

src/app/clusters/energy-evse-server/energy-evse-server.h

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <app/util/attribute-storage.h>
2929
#include <lib/core/CHIPError.h>
3030
#include <protocols/interaction_model/StatusCode.h>
31+
#include <vector>
3132

3233
namespace chip {
3334
namespace app {

0 commit comments

Comments
 (0)