Skip to content

Commit

Permalink
[K32W0][THREADIP-3658] Fix lighting app (#11192)
Browse files Browse the repository at this point in the history
* [K32W0][THREADIP-3658] Fix lighting app

* remove dead code
* fix bug where the cluster state was not in sync with the physical button state
* add stubs for ColorControl/LevelControl clusters.

Signed-off-by: Doru Gucea <[email protected]>

* Restyled by clang-format

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Aug 29, 2023
1 parent 911d15d commit 41bf5ad
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 201 deletions.
20 changes: 10 additions & 10 deletions examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,19 @@ CHIP_ERROR AppTask::Init()
/* HW init leds */
LED_Init();

if (LightingMgr().Init() != 0)
{
K32W_LOG("LightingMgr().Init() failed");
assert(0);
}

LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted);

/* start with all LEDS turnedd off */
sStatusLED.Init(SYSTEM_STATE_LED);

sLightLED.Init(LIGHT_STATE_LED);
sLightLED.Set(LightingMgr().IsTurnedOff());
sLightLED.Set(!LightingMgr().IsTurnedOff());
UpdateClusterState();

/* intialize the Keyboard and button press calback */
Expand All @@ -117,22 +125,14 @@ CHIP_ERROR AppTask::Init()
(void *) this, // init timer id = app task obj context
TimerEventHandler // timer callback handler
);

if (sFunctionTimer == NULL)
{
err = APP_ERROR_CREATE_TIMER_FAILED;
K32W_LOG("app_timer_create() failed");
assert(err == CHIP_NO_ERROR);
}

int status = LightingMgr().Init();
if (status != 0)
{
K32W_LOG("LightingMgr().Init() failed");
assert(status == 0);
}

LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted);

// Print the current software version
char currentFirmwareRev[ConfigurationManager::kMaxFirmwareRevisionLength + 1] = { 0 };
err = ConfigurationMgr().GetFirmwareRevisionString(currentFirmwareRev, sizeof(currentFirmwareRev));
Expand Down
176 changes: 10 additions & 166 deletions examples/lighting-app/nxp/k32w/k32w0/main/LightingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,9 @@

LightingManager LightingManager::sLight;

TimerHandle_t sLightTimer; // FreeRTOS app sw timer.

int LightingManager::Init()
{
// Create FreeRTOS sw timer for light timer.

sLightTimer = xTimerCreate("LightTmr", // Just a text name, not used by the RTOS kernel
1, // == default timer period (mS)
false, // no timer reload (==one-shot)
(void *) this, // init timer id = light obj context
TimerEventHandler // timer callback handler
);

if (sLightTimer == NULL)
{
K32W_LOG("light timer create failed");
assert(0);
}

mState = kState_TurnOffCompleted;
mAutoTurnOnTimerArmed = false;
mAutoTurnOn = false;
mAutoTurnOnDuration = 0;
mState = kState_Off;

return 0;
}
Expand All @@ -59,173 +39,37 @@ void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Ca
mActionCompleted_CB = aActionCompleted_CB;
}

bool LightingManager::IsActionInProgress()
{
return (mState == kState_TurnOnInitiated || mState == kState_TurnOffInitiated) ? true : false;
}

bool LightingManager::IsTurnedOff()
{
return (mState == kState_TurnOffCompleted) ? true : false;
}

void LightingManager::EnableAutoTurnOn(bool aOn)
{
mAutoTurnOn = aOn;
}

void LightingManager::SetAutoTurnOnDuration(uint32_t aDurationInSecs)
{
mAutoTurnOnDuration = aDurationInSecs;
return (mState == kState_Off) ? true : false;
}

bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction)
{
bool action_initiated = false;
State_t new_state;

// Initiate ON/OFF Action only when the previous one is complete.
if (mState == kState_TurnOnCompleted && aAction == TURNOFF_ACTION)
if (mState == kState_On && aAction == TURNOFF_ACTION)
{
action_initiated = true;

new_state = kState_TurnOffInitiated;
mState = kState_Off;
}
else if (mState == kState_TurnOffCompleted && aAction == TURNON_ACTION)
else if (mState == kState_Off && aAction == TURNON_ACTION)
{
action_initiated = true;

new_state = kState_TurnOnInitiated;
mState = kState_On;
}

if (action_initiated)
{
if (mAutoTurnOnTimerArmed && new_state == kState_TurnOnInitiated)
{
// If auto turnon timer has been armed and someone initiates turn on the ligth,
// cancel the timer and continue as normal.
mAutoTurnOnTimerArmed = false;

CancelTimer();
}

StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS);

// Since the timer started successfully, update the state and trigger callback
mState = new_state;

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

return action_initiated;
}

void LightingManager::StartTimer(uint32_t aTimeoutMs)
{
if (xTimerIsTimerActive(sLightTimer))
{
K32W_LOG("light timer already started!");
// appError(err);
CancelTimer();
}

// timer is not active, change its period to required value.
// This also causes the timer to start. FreeRTOS- Block for a maximum of
// 100 ticks if the change period command cannot immediately be sent to the
// timer command queue.
if (xTimerChangePeriod(sLightTimer, aTimeoutMs / portTICK_PERIOD_MS, 100) != pdPASS)
{
K32W_LOG("light timer start() failed");
// appError(err);
}
}

void LightingManager::CancelTimer(void)
{
if (xTimerStop(sLightTimer, 0) == pdFAIL)
{
K32W_LOG("light timer stop() failed");
// appError(err);
}
}

void LightingManager::TimerEventHandler(TimerHandle_t xTimer)
{
// Get light obj context from timer id.
LightingManager * light = static_cast<LightingManager *>(pvTimerGetTimerID(xTimer));

// The timer event handler will be called in the context of the timer task
// once sLightTimer expires. Post an event to apptask queue with the actual handler
// so that the event can be handled in the context of the apptask.
AppEvent event;
event.Type = AppEvent::kEventType_Timer;
event.TimerEvent.Context = light;

if (light->mAutoTurnOnTimerArmed)
{
event.Handler = AutoReTurnOnTimerEventHandler;
GetAppTask().PostEvent(&event);
}
else
{
event.Handler = ActuatorMovementTimerEventHandler;
GetAppTask().PostEvent(&event);
}
}

void LightingManager::AutoReTurnOnTimerEventHandler(AppEvent * aEvent)
{
LightingManager * light = static_cast<LightingManager *>(aEvent->TimerEvent.Context);
int32_t actor = 0;

// Make sure auto light timer is still armed.
if (!light->mAutoTurnOnTimerArmed)
{
return;
}

light->mAutoTurnOnTimerArmed = false;

K32W_LOG("Auto Turn On has been triggered!");

light->InitiateAction(actor, TURNON_ACTION);
}

void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
{
Action_t actionCompleted = INVALID_ACTION;

LightingManager * light = static_cast<LightingManager *>(aEvent->TimerEvent.Context);

if (light->mState == kState_TurnOnInitiated)
{
light->mState = kState_TurnOnCompleted;
actionCompleted = TURNON_ACTION;
}
else if (light->mState == kState_TurnOffInitiated)
{
light->mState = kState_TurnOffCompleted;
actionCompleted = TURNOFF_ACTION;
}

if (actionCompleted != INVALID_ACTION)
{
if (light->mActionCompleted_CB)
if (mActionCompleted_CB)
{
light->mActionCompleted_CB(actionCompleted);
}

if (light->mAutoTurnOn && actionCompleted == TURNOFF_ACTION)
{
// Start the timer for auto turn on
light->StartTimer(light->mAutoTurnOnDuration * 1000);

light->mAutoTurnOnTimerArmed = true;

K32W_LOG("Auto Turn On enabled. Will be triggered in %u seconds", light->mAutoTurnOnDuration);
mActionCompleted_CB(aAction);
}
}

return action_initiated;
}
40 changes: 33 additions & 7 deletions examples/lighting-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,45 @@ using namespace ::chip::app::Clusters;
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t mask, uint8_t type, uint16_t size,
uint8_t * value)
{
if (path.mClusterId != OnOff::Id)
if (path.mClusterId == OnOff::Id)
{
ChipLogProgress(Zcl, "Unknown cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mClusterId));
return;
if (path.mAttributeId != OnOff::Attributes::OnOff::Id)
{
ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId));
return;
}

LightingMgr().InitiateAction(0, *value ? LightingManager::TURNON_ACTION : LightingManager::TURNOFF_ACTION);
}
else if (path.mClusterId == LevelControl::Id)
{
ChipLogProgress(Zcl,
"Level Control attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16 ", length %" PRIu16,
ChipLogValueMEI(path.mAttributeId), type, *value, size);

if (path.mAttributeId != OnOff::Attributes::OnOff::Id)
// WIP Apply attribute change to Light
}
else if (path.mClusterId == ColorControl::Id)
{
ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId));
return;
ChipLogProgress(Zcl,
"Color Control attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16 ", length %" PRIu16,
ChipLogValueMEI(path.mAttributeId), type, *value, size);

// WIP Apply attribute change to Light
}
else if (path.mClusterId == OnOffSwitchConfiguration::Id)
{
ChipLogProgress(Zcl,
"OnOff Switch Configuration attribute ID: " ChipLogFormatMEI " Type: %" PRIu8 " Value: %" PRIu16
", length %" PRIu16,
ChipLogValueMEI(path.mAttributeId), type, *value, size);

LightingMgr().InitiateAction(0, *value ? LightingManager::TURNON_ACTION : LightingManager::TURNOFF_ACTION);
// WIP Apply attribute change to Light
}
else
{
ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId));
}
}

/** @brief OnOff Cluster Init
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,12 @@ class LightingManager

enum State_t
{
kState_TurnOnInitiated = 0,
kState_TurnOnCompleted,
kState_TurnOffInitiated,
kState_TurnOffCompleted,
kState_On = 0,
kState_Off,
} State;

int Init();
bool IsTurnedOff();
void EnableAutoTurnOn(bool aOn);
void SetAutoTurnOnDuration(uint32_t aDurationInSecs);
bool IsActionInProgress();
bool InitiateAction(int32_t aActor, Action_t aAction);

typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor);
Expand All @@ -63,17 +58,6 @@ class LightingManager
Callback_fn_initiated mActionInitiated_CB;
Callback_fn_completed mActionCompleted_CB;

bool mAutoTurnOn;
uint32_t mAutoTurnOnDuration;
bool mAutoTurnOnTimerArmed;

void CancelTimer(void);
void StartTimer(uint32_t aTimeoutMs);

static void TimerEventHandler(TimerHandle_t xTimer);
static void AutoReTurnOnTimerEventHandler(AppEvent * aEvent);
static void ActuatorMovementTimerEventHandler(AppEvent * aEvent);

static LightingManager sLight;
};

Expand Down

0 comments on commit 41bf5ad

Please sign in to comment.