Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[samples/nrfconnect] Added updating ZCL cluster state to fit actual light/lock state. #3132

Merged
merged 2 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions examples/lighting-app/efr32/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,16 @@ extern "C" void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClus
LightMgr().InitiateAction(AppEvent::kEventType_Light, LightingManager::OFF_ACTION);
}
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
extern "C" void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
// TODO: implement any additional On/off Cluster Server post init actions
}
10 changes: 0 additions & 10 deletions examples/lighting-app/lighting-common/gen/callback-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,6 @@
//#include "hal/hal.h"
//#include EMBER_AF_API_NETWORK_STEERING

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint) {}

/** @brief Add To Current App Tasks
*
* This function is only useful to sleepy end devices. This function will note
Expand Down
13 changes: 13 additions & 0 deletions examples/lighting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clust
LightingMgr().InitiateAction(LightingManager::OFF_ACTION);
}
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
// TODO: implement any additional On/off Cluster Server post init actions
}
}

int main()
Expand Down
13 changes: 13 additions & 0 deletions examples/lighting-app/nrf5/main/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,17 @@ void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clust
LightingMgr().InitiateAction(LightingManager::OFF_ACTION);
}
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
// TODO: implement any additional On/off Cluster Server post init actions
}
}
30 changes: 27 additions & 3 deletions examples/lighting-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include "Service.h"
#include "ThreadUtil.h"

#include "attribute-storage.h"
#include "gen/cluster-id.h"

#include <platform/CHIPDeviceLayer.h>

#include <setup_payload/QRCodeSetupPayloadGenerator.h>
Expand Down Expand Up @@ -197,17 +200,20 @@ int AppTask::StartApp()
void AppTask::LightingActionEventHandler(AppEvent * aEvent)
{
LightingManager::Action_t action = LightingManager::INVALID_ACTION;
int32_t actor = 0;

if (aEvent->Type == AppEvent::kEventType_Lighting)
{
action = static_cast<LightingManager::Action_t>(aEvent->LightingEvent.Action);
actor = aEvent->LightingEvent.Actor;
}
else if (aEvent->Type == AppEvent::kEventType_Button)
{
action = LightingMgr().IsTurnedOn() ? LightingManager::OFF_ACTION : LightingManager::ON_ACTION;
actor = AppEvent::kEventType_Button;
}

if (action != LightingManager::INVALID_ACTION && !LightingMgr().InitiateAction(action))
if (action != LightingManager::INVALID_ACTION && !LightingMgr().InitiateAction(action, actor))
LOG_INF("Action is already in progress or active.");
}

Expand Down Expand Up @@ -350,7 +356,7 @@ void AppTask::StartTimer(uint32_t aTimeoutInMs)
mFunctionTimerActive = true;
}

void AppTask::ActionInitiated(LightingManager::Action_t aAction)
void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor)
{
if (aAction == LightingManager::ON_ACTION)
{
Expand All @@ -362,7 +368,7 @@ void AppTask::ActionInitiated(LightingManager::Action_t aAction)
}
}

void AppTask::ActionCompleted(LightingManager::Action_t aAction)
void AppTask::ActionCompleted(LightingManager::Action_t aAction, int32_t aActor)
{
if (aAction == LightingManager::ON_ACTION)
{
Expand All @@ -372,6 +378,11 @@ void AppTask::ActionCompleted(LightingManager::Action_t aAction)
{
LOG_INF("Turn Off Action has been completed");
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will be reached even if the action is coming from the data model itself, right? Do we really want to re-enter the data model at that point with the attribute write?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I forgot about checking if action was triggered by pushing button manually. I fixed it.

if (aActor == AppEvent::kEventType_Button)
{
sAppTask.UpdateClusterState();
}
}

void AppTask::PostLightingActionRequest(LightingManager::Action_t aAction)
Expand Down Expand Up @@ -402,3 +413,16 @@ void AppTask::DispatchEvent(AppEvent * aEvent)
LOG_INF("Event received with no handler. Dropping event.");
}
}

void AppTask::UpdateClusterState()
{
uint8_t newValue = LightingMgr().IsTurnedOn();

// write the new on/off value
EmberAfStatus status = emberAfWriteAttribute(1, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, &newValue,
ZCL_BOOLEAN_ATTRIBUTE_TYPE);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
LOG_ERR("Updating on/off %x", status);
}
}
6 changes: 3 additions & 3 deletions examples/lighting-app/nrfconnect/main/LightingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void LightingManager::SetCallbacks(LightingCallback_fn aActionInitiated_CB, Ligh
mActionCompleted_CB = aActionCompleted_CB;
}

bool LightingManager::InitiateAction(Action_t aAction)
bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor)
{
// TODO: this function is called InitiateAction because we want to implement some features such as ramping up here.
bool action_initiated = false;
Expand All @@ -81,14 +81,14 @@ bool LightingManager::InitiateAction(Action_t aAction)
{
if (mActionInitiated_CB)
{
mActionInitiated_CB(aAction);
mActionInitiated_CB(aAction, aActor);
}

Set(new_state == kState_On);

if (mActionCompleted_CB)
{
mActionCompleted_CB(aAction);
mActionCompleted_CB(aAction, aActor);
}
}

Expand Down
16 changes: 15 additions & 1 deletion examples/lighting-app/nrfconnect/main/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "gen/znet-bookkeeping.h"
#include <app/util/af-types.h>

#include "AppTask.h"
#include "LightingManager.h"

extern "C" {
Expand All @@ -41,6 +42,19 @@ void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clust
return;
}

LightingMgr().InitiateAction(*value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION);
LightingMgr().InitiateAction(*value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, AppEvent::kEventType_Lighting);
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
GetAppTask().UpdateClusterState();
}
}
1 change: 1 addition & 0 deletions examples/lighting-app/nrfconnect/main/include/AppEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct AppEvent
struct
{
uint8_t Action;
int32_t Actor;
} LightingEvent;
};

Expand Down
6 changes: 3 additions & 3 deletions examples/lighting-app/nrfconnect/main/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ class AppTask

void PostLightingActionRequest(LightingManager::Action_t aAction);
void PostEvent(AppEvent * event);
void UpdateClusterState();

private:
friend AppTask & GetAppTask(void);

int Init();

static void ActionInitiated(LightingManager::Action_t aAction);
static void ActionCompleted(LightingManager::Action_t aAction);
static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor);
static void ActionCompleted(LightingManager::Action_t aAction, int32_t aActor);

void CancelTimer(void);

Expand All @@ -66,7 +67,6 @@ class AppTask

Function_t mFunction;
bool mFunctionTimerActive;

static AppTask sAppTask;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class LightingManager
kState_Off,
};

using LightingCallback_fn = void (*)(Action_t);
using LightingCallback_fn = void (*)(Action_t, int32_t);

int Init(const char * gpioDeviceName, gpio_pin_t gpioPin);
bool IsTurnedOn() const { return mState == kState_On; }
bool InitiateAction(Action_t aAction);
bool InitiateAction(Action_t aAction, int32_t aActor);
void SetCallbacks(LightingCallback_fn aActionInitiated_CB, LightingCallback_fn aActionCompleted_CB);

private:
Expand Down
13 changes: 13 additions & 0 deletions examples/lock-app/efr32/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,16 @@ extern "C" void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClus
BoltLockMgr().InitiateAction(AppEvent::kEventType_Lock, BoltLockManager::UNLOCK_ACTION);
}
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
extern "C" void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
// TODO: implement any additional On/off Cluster Server post init actions
}
13 changes: 13 additions & 0 deletions examples/lock-app/k32w/main/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,17 @@ void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clust

BoltLockMgr().InitiateAction(0, *value ? BoltLockManager::LOCK_ACTION : BoltLockManager::UNLOCK_ACTION);
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
// TODO: implement any additional On/off Cluster Server post init actions
}
}
10 changes: 0 additions & 10 deletions examples/lock-app/lock-common/gen/callback-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,6 @@
//#include "hal/hal.h"
//#include EMBER_AF_API_NETWORK_STEERING

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint) {}

/** @brief Add To Current App Tasks
*
* This function is only useful to sleepy end devices. This function will note
Expand Down
13 changes: 13 additions & 0 deletions examples/lock-app/nrf5/main/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,17 @@ void emberAfPostAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clust
BoltLockMgr().InitiateAction(0, BoltLockManager::UNLOCK_ACTION);
}
}

/** @brief On/off Cluster Server Post Init
*
* Following resolution of the On/Off state at startup for this endpoint,
* perform any additional initialization needed; e.g., synchronize hardware
* state.
*
* @param endpoint Endpoint that is being initialized Ver.: always
*/
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
// TODO: implement any additional On/off Cluster Server post init actions
}
}
24 changes: 23 additions & 1 deletion examples/lock-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "Service.h"
#include "ThreadUtil.h"

#include "attribute-storage.h"
#include "gen/cluster-id.h"

#include <platform/CHIPDeviceLayer.h>

#include <dk_buttons_and_leds.h>
Expand Down Expand Up @@ -200,6 +203,7 @@ void AppTask::LockActionEventHandler(AppEvent * aEvent)
else if (aEvent->Type == AppEvent::kEventType_Button)
{
action = BoltLockMgr().IsUnlocked() ? BoltLockManager::LOCK_ACTION : BoltLockManager::UNLOCK_ACTION;
actor = AppEvent::kEventType_Button;
}

if (action != BoltLockManager::INVALID_ACTION && !BoltLockMgr().InitiateAction(actor, action))
Expand Down Expand Up @@ -370,7 +374,7 @@ void AppTask::ActionInitiated(BoltLockManager::Action_t aAction, int32_t aActor)
sLockLED.Blink(50, 50);
}

void AppTask::ActionCompleted(BoltLockManager::Action_t aAction)
void AppTask::ActionCompleted(BoltLockManager::Action_t aAction, int32_t aActor)
{
// if the action has been completed by the lock, update the bolt lock trait.
// Turn on the lock LED if in a LOCKED state OR
Expand All @@ -385,6 +389,11 @@ void AppTask::ActionCompleted(BoltLockManager::Action_t aAction)
LOG_INF("Unlock Action has been completed");
sLockLED.Set(false);
}

if (aActor == AppEvent::kEventType_Button)
{
sAppTask.UpdateClusterState();
}
}

void AppTask::PostLockActionRequest(int32_t aActor, BoltLockManager::Action_t aAction)
Expand Down Expand Up @@ -416,3 +425,16 @@ void AppTask::DispatchEvent(AppEvent * aEvent)
LOG_INF("Event received with no handler. Dropping event.");
}
}

void AppTask::UpdateClusterState()
{
uint8_t newValue = !BoltLockMgr().IsUnlocked();

// write the new on/off value
EmberAfStatus status = emberAfWriteAttribute(1, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, &newValue,
ZCL_BOOLEAN_ATTRIBUTE_TYPE);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
LOG_ERR("Updating on/off %x", status);
}
}
Loading