From 140e6ecb5de51f253058d2582599496550ebb966 Mon Sep 17 00:00:00 2001 From: Andrei Menzopol Date: Wed, 17 Aug 2022 05:49:02 -0700 Subject: [PATCH] Fix overlapping behaviour for TriggerEffect and Identify commands * [K32W0] Add TriggerEffect support, update readme * Fix behaviour when TriggerEffect called during Identify and vice versa * Update wordlist Signed-off-by: Andrei Menzopol --- .github/.wordlist.txt | 11 +- .../lighting-app/nxp/k32w/k32w0/README.md | 16 ++ .../nxp/k32w/k32w0/main/AppTask.cpp | 146 ++++++++++++++++-- .../nxp/k32w/k32w0/main/include/AppTask.h | 11 ++ .../identify-server/identify-server.cpp | 4 +- 5 files changed, 168 insertions(+), 20 deletions(-) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 4e3560d7fba70e..6ed9654a620149 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -48,11 +48,9 @@ algs alloc Ameba amebad -AmebaD amebaiot AmebaZ amebaz2 -AmebaZ2 announcementReason AnnounceOTAProvider AnnounceOtaProviderRequest @@ -84,8 +82,6 @@ args argv armeabi armino -Armino -ARMINO ARMmbed armv ASAN @@ -294,8 +290,8 @@ connstring conntype const ContentApp -ContentApp's ContentAppPlatform +ContentApp's ContentLaunch ContentLauncher continuousHinting @@ -1116,8 +1112,8 @@ REPL repo req Requestor -Requestor's RequestorCanConsent +Requestor's Requestors responder RestrictedEvent @@ -1164,8 +1160,8 @@ SDB SDC SDHC SDK -SDK's sdkconfig +SDK's SDKs SDKTARGETSYSROOT sdl @@ -1342,6 +1338,7 @@ trackFree TransferSession transitionTime TransportMgrBase +TriggerEffect TRNG TrustedRootCertificates tsan diff --git a/examples/lighting-app/nxp/k32w/k32w0/README.md b/examples/lighting-app/nxp/k32w/k32w0/README.md index 6b638d0660447a..410cd5b95f1fd5 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/README.md +++ b/examples/lighting-app/nxp/k32w/k32w0/README.md @@ -167,6 +167,22 @@ DS3, which can be found on the DK6 board. Also, by long pressing the **USERINTERFACE** button, the factory reset action will be initiated. +### Identify cluster LED state + +The Identify cluster server supports two identification commands: **Identify** and **TriggerEffect**. These commands allow a user to identify a particular device. For these commands, the **LED D3** is used. + +The **Identify command** will use the **LED D3** to flash with a period of 0.5 seconds. + +The **TriggerEffect command** will use the **LED D3** with the following effects: + +* _Blink_ — flash with a 1 second period for 2 seconds +* _Breathe_ — flash with a 1 second period for 15 seconds +* _Okay_ — flash with a 1 second period for 4 seconds +* _Channel change_ — same as Blink +* _Finish effect_ — complete current effect sequence and terminate +* _Stop effect_ — terminate as soon as possible + + ## Building diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp index d5f30e05b79224..9ab91ebd1a11e2 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -82,10 +82,21 @@ extern "C" void K32WUartProcess(void); using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; using namespace chip; -; AppTask AppTask::sAppTask; +static Identify gIdentify = { + chip::EndpointId{1}, + AppTask::OnIdentifyStart, + AppTask::OnIdentifyStop, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, + AppTask::OnTriggerEffect, + //Use invalid value for identifiers to enable TriggerEffect command + //to stop Identify command for each effect + (EmberAfIdentifyEffectIdentifier)(EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT - 0x10), + EMBER_ZCL_IDENTIFY_EFFECT_VARIANT_DEFAULT +}; + /* OTA related variables */ #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static DefaultOTARequestor gRequestorCore; @@ -415,15 +426,7 @@ void AppTask::ResetActionEventHandler(AppEvent * aEvent) sAppTask.CancelTimer(); sAppTask.mFunction = kFunction_NoneSelected; - /* restore initial state for the LED indicating Lighting state */ - if (LightingMgr().IsTurnedOff()) - { - sLightLED.Set(false); - } - else - { - sLightLED.Set(true); - } + RestoreLightingState(); K32W_LOG("Factory Reset was cancelled!"); } @@ -682,6 +685,129 @@ void AppTask::ActionCompleted(LightingManager::Action_t aAction) sAppTask.mFunction = kFunction_NoneSelected; } +void AppTask::RestoreLightingState(void) +{ + /* restore initial state for the LED indicating Lighting state */ + if (LightingMgr().IsTurnedOff()) + { + sLightLED.Set(false); + } + else + { + sLightLED.Set(true); + } +} + +void AppTask::OnIdentifyStart(Identify* identify) +{ + if ((kFunction_NoneSelected != sAppTask.mFunction) && (kFunction_TriggerEffect != sAppTask.mFunction)) + { + K32W_LOG("Another function is scheduled. Could not initiate Identify process!"); + return; + } + + if (kFunction_TriggerEffect == sAppTask.mFunction) + { + chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); + OnTriggerEffectComplete(&chip::DeviceLayer::SystemLayer(), identify); + } + + ChipLogProgress(Zcl,"Identify process has started. Status LED should blink with a period of 0.5 seconds."); + sAppTask.mFunction = kFunction_Identify; + sLightLED.Set(false); + sLightLED.Blink(250); +} + +void AppTask::OnIdentifyStop(Identify* identify) +{ + if (kFunction_Identify == sAppTask.mFunction) + { + ChipLogProgress(Zcl,"Identify process has stopped."); + sAppTask.mFunction = kFunction_NoneSelected; + + RestoreLightingState(); + + } +} + +void AppTask::OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState) +{ + //Let Identify command take over if called during TriggerEffect already running + if (kFunction_TriggerEffect == sAppTask.mFunction) + { + ChipLogProgress(Zcl,"TriggerEffect has stopped."); + sAppTask.mFunction = kFunction_NoneSelected; + + //TriggerEffect finished - reset identifiers + //Use invalid value for identifiers to enable TriggerEffect command + //to stop Identify command for each effect + gIdentify.mCurrentEffectIdentifier = (EmberAfIdentifyEffectIdentifier)(EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT - 0x10); + gIdentify.mTargetEffectIdentifier = (EmberAfIdentifyEffectIdentifier)(EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT - 0x10); + gIdentify.mEffectVariant = EMBER_ZCL_IDENTIFY_EFFECT_VARIANT_DEFAULT; + + RestoreLightingState(); + } +} + +void AppTask::OnTriggerEffect(Identify* identify) +{ + //Allow overlapping TriggerEffect calls + if ((kFunction_NoneSelected != sAppTask.mFunction) && (kFunction_TriggerEffect != sAppTask.mFunction)) + { + K32W_LOG("Another function is scheduled. Could not initiate Identify process!"); + return; + } + + sAppTask.mFunction = kFunction_TriggerEffect; + uint16_t timerDelay = 0; + + ChipLogProgress(Zcl,"TriggerEffect has started."); + + + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + timerDelay = 2; + break; + + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + timerDelay = 15; + break; + + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + timerDelay = 4; + break; + + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl,"Channel Change effect not supported, using effect %d", + EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK); + timerDelay = 2; + break; + + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); + timerDelay = 1; + break; + + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerEffectComplete, identify); + OnTriggerEffectComplete(&chip::DeviceLayer::SystemLayer(), identify); + break; + + default: + ChipLogProgress(Zcl, "Invalid effect identifier."); + } + + if(timerDelay) + { + sLightLED.Set(false); + sLightLED.Blink(500); + + chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(timerDelay), OnTriggerEffectComplete, + identify); + } +} + void AppTask::PostTurnOnActionRequest(int32_t aActor, LightingManager::Action_t aAction) { AppEvent event; diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h index d0ef272e00350c..a3002f5b8d06ab 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h +++ b/examples/lighting-app/nxp/k32w/k32w0/main/include/AppTask.h @@ -25,6 +25,7 @@ #include "LightingManager.h" #include +#include #include "FreeRTOS.h" #include "timers.h" @@ -49,6 +50,12 @@ class AppTask void UpdateClusterState(void); void UpdateDeviceState(void); + // Identify cluster callbacks. + static void OnIdentifyStart(Identify* identify); + static void OnIdentifyStop(Identify* identify); + static void OnTriggerEffect(Identify* identify); + static void OnTriggerEffectComplete(chip::System::Layer * systemLayer, void * appState); + private: friend AppTask & GetAppTask(void); @@ -77,6 +84,8 @@ class AppTask static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); void StartTimer(uint32_t aTimeoutInMs); + static void RestoreLightingState(void); + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static void InitOTA(intptr_t arg); static void StartOTAQuery(intptr_t arg); @@ -93,6 +102,8 @@ class AppTask kFunction_SoftwareUpdate = 0, kFunction_FactoryReset, kFunctionTurnOnTurnOff, + kFunction_Identify, + kFunction_TriggerEffect, kFunction_Invalid } Function; diff --git a/src/app/clusters/identify-server/identify-server.cpp b/src/app/clusters/identify-server/identify-server.cpp index a9294aea5bbab5..00b5f65858ebaf 100644 --- a/src/app/clusters/identify-server/identify-server.cpp +++ b/src/app/clusters/identify-server/identify-server.cpp @@ -179,9 +179,7 @@ void MatterIdentifyClusterServerAttributeChangedCallback(const app::ConcreteAttr /* finish identify process */ if (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT == identify->mCurrentEffectIdentifier && identifyTime > 0) { - (void) chip::DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onIdentifyClusterTick, - identify); - return; + Clusters::Identify::Attributes::IdentifyTime::Set(endpoint, 1); } /* stop identify process */ if (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT == identify->mCurrentEffectIdentifier && identifyTime > 0)