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

[K32W0][THREADIP-3658] Fix lighting app #11192

Merged
merged 2 commits into from
Oct 29, 2021
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
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