Skip to content

Commit

Permalink
[QPG] lighting-app: Persist level and color (#31601)
Browse files Browse the repository at this point in the history
Use DeferredAttributePersistenceProvider to save CurrentX, CurrentY and
CurrentLevel attributes. Restore them on startup.
  • Loading branch information
q-thla authored and pull[bot] committed Feb 14, 2024
1 parent b52b3ab commit 4301976
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
23 changes: 23 additions & 0 deletions examples/lighting-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <app/util/attribute-storage.h>
#include <lib/support/TypeTraits.h>

#include <app/DeferredAttributePersistenceProvider.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>

Expand Down Expand Up @@ -72,6 +73,7 @@ using namespace ::chip::DeviceLayer;
static uint8_t countdown = 0;

namespace {
constexpr EndpointId kLightEndpointId = 1;
TaskHandle_t sAppTaskHandle;
QueueHandle_t sAppEventQueue;

Expand All @@ -93,6 +95,25 @@ StaticTask_t appTaskStruct;
Clusters::Identify::EffectIdentifierEnum sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect;
chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;

// Define a custom attribute persister which makes actual write of the attribute value
// to the non-volatile storage only when it has remained constant for 5 seconds. This is to reduce
// the flash wearout when the attribute changes frequently as a result of commands.
// DeferredAttribute object describes a deferred attribute, but also holds a buffer with a value to
// be written, so it must live so long as the DeferredAttributePersistenceProvider object.
//
DeferredAttribute gPersisters[] = { DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id,
Clusters::ColorControl::Attributes::CurrentX::Id)),
DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id,
Clusters::ColorControl::Attributes::CurrentY::Id)),
DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::LevelControl::Id,
Clusters::LevelControl::Attributes::CurrentLevel::Id))

};

DeferredAttributePersistenceProvider gDeferredAttributePersister(Server::GetInstance().GetDefaultAttributePersister(),
Span<DeferredAttribute>(gPersisters, 3),
System::Clock::Milliseconds32(5000));

/**********************************************************
* Identify Callbacks
*********************************************************/
Expand Down Expand Up @@ -250,6 +271,8 @@ void AppTask::InitServer(intptr_t arg)

chip::Server::GetInstance().Init(initParams);

app::SetAttributePersistenceProvider(&gDeferredAttributePersister);

#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
chip::app::DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(extDiscTimeoutSecs);
#endif
Expand Down
30 changes: 29 additions & 1 deletion examples/lighting-app/qpg/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,41 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &
*/
void emberAfOnOffClusterInitCallback(EndpointId endpoint)
{
uint8_t levelValue;
XyColor_t xy;
bool onOffValue = false;
app::DataModel::Nullable<uint8_t> currentLevel;
EmberAfStatus status;

EmberAfStatus status = OnOff::Attributes::OnOff::Get(1, &onOffValue);
status = OnOff::Attributes::OnOff::Get(1, &onOffValue);

if (status == EMBER_ZCL_STATUS_SUCCESS)
{
LightingMgr().InitiateAction(onOffValue ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, 0, 1,
(uint8_t *) onOffValue);
}

/* restore values saved by DeferredAttributePersistenceProvider */
status = LevelControl::Attributes::CurrentLevel::Get(endpoint, currentLevel);
if (status != EMBER_ZCL_STATUS_SUCCESS || currentLevel.IsNull())
{
return;
}

levelValue = currentLevel.Value();

status = ColorControl::Attributes::CurrentY::Get(endpoint, &xy.y);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
return;
}
status = ColorControl::Attributes::CurrentX::Get(endpoint, &xy.x);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
return;
}
ChipLogProgress(Zcl, "restore level: %u", levelValue);
LightingMgr().InitiateAction(LightingManager::LEVEL_ACTION, 0, 1, &levelValue);
ChipLogProgress(Zcl, "restore XY color: %u|%u", xy.x, xy.y);
LightingMgr().InitiateAction(LightingManager::COLOR_ACTION_XY, 0, sizeof(xy), (uint8_t *) &xy);
}
4 changes: 2 additions & 2 deletions examples/lighting-app/qpg/zap/light.matter
Original file line number Diff line number Diff line change
Expand Up @@ -2330,8 +2330,8 @@ endpoint 1 {
ram attribute currentHue default = 0x00;
ram attribute currentSaturation default = 0x00;
ram attribute remainingTime default = 0x0000;
ram attribute currentX default = 0x616B;
ram attribute currentY default = 0x607D;
persist attribute currentX default = 0x616B;
persist attribute currentY default = 0x607D;
ram attribute colorTemperatureMireds default = 0x00FA;
ram attribute colorMode default = 0x01;
ram attribute options default = 0x00;
Expand Down
6 changes: 3 additions & 3 deletions examples/lighting-app/qpg/zap/light.zap
Original file line number Diff line number Diff line change
Expand Up @@ -5310,7 +5310,7 @@
"side": "server",
"type": "int16u",
"included": 1,
"storageOption": "RAM",
"storageOption": "NVM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x616B",
Expand All @@ -5326,7 +5326,7 @@
"side": "server",
"type": "int16u",
"included": 1,
"storageOption": "RAM",
"storageOption": "NVM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x607D",
Expand Down Expand Up @@ -5980,4 +5980,4 @@
"networkId": 0
}
]
}
}

0 comments on commit 4301976

Please sign in to comment.