From e79282f9031a05d4c1da691fa1a28e3b16ff41b9 Mon Sep 17 00:00:00 2001 From: Arun Padakanti Date: Mon, 25 Nov 2024 23:41:28 +0530 Subject: [PATCH 1/5] Level Control cluster implementation for light-switch --- .../light-switch-common/light-switch-app.zap | 18 ++++ .../silabs/include/AppEvent.h | 1 + .../light-switch-app/silabs/include/AppTask.h | 2 + .../silabs/include/BindingHandler.h | 2 + .../silabs/include/LightSwitchMgr.h | 5 + .../light-switch-app/silabs/src/AppTask.cpp | 66 ++++++++++--- .../silabs/src/BindingHandler.cpp | 51 ++++++++++ .../silabs/src/LightSwitchMgr.cpp | 14 +++ .../silabs/src/ShellCommands.cpp | 96 +++++++++++++++++++ 9 files changed, 241 insertions(+), 14 deletions(-) diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap index 595b0d8f83..02fa237b36 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.zap +++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap @@ -4733,6 +4733,24 @@ } ] }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "MoveToLevelWithOnOff", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + }, { "name": "Descriptor", "code": 29, diff --git a/examples/light-switch-app/silabs/include/AppEvent.h b/examples/light-switch-app/silabs/include/AppEvent.h index 7a19b719ed..6d7c944ecd 100644 --- a/examples/light-switch-app/silabs/include/AppEvent.h +++ b/examples/light-switch-app/silabs/include/AppEvent.h @@ -38,6 +38,7 @@ struct AppEvent { struct { + uint8_t ButtonId; uint8_t Action; } ButtonEvent; struct diff --git a/examples/light-switch-app/silabs/include/AppTask.h b/examples/light-switch-app/silabs/include/AppTask.h index 71ca4b427b..9c5dbade25 100644 --- a/examples/light-switch-app/silabs/include/AppTask.h +++ b/examples/light-switch-app/silabs/include/AppTask.h @@ -102,4 +102,6 @@ class AppTask : public BaseApplication * @param aEvent button event being processed */ static void SwitchActionEventHandler(AppEvent * aEvent); + static void LevelUpEventHandler(AppEvent * aEvent); + static void LevelDownEventHandler(AppEvent * aEvent); }; diff --git a/examples/light-switch-app/silabs/include/BindingHandler.h b/examples/light-switch-app/silabs/include/BindingHandler.h index aed08be25e..636af11526 100644 --- a/examples/light-switch-app/silabs/include/BindingHandler.h +++ b/examples/light-switch-app/silabs/include/BindingHandler.h @@ -22,6 +22,7 @@ CHIP_ERROR InitBindingHandler(); void SwitchWorkerFunction(intptr_t context); +void LevelWorkerFunction(intptr_t context); void BindingWorkerFunction(intptr_t context); struct BindingCommandData @@ -29,5 +30,6 @@ struct BindingCommandData chip::EndpointId localEndpointId = 1; chip::CommandId commandId; chip::ClusterId clusterId; + uint8_t level; bool isGroup = false; }; diff --git a/examples/light-switch-app/silabs/include/LightSwitchMgr.h b/examples/light-switch-app/silabs/include/LightSwitchMgr.h index adfe75fda9..3684d2bcdd 100644 --- a/examples/light-switch-app/silabs/include/LightSwitchMgr.h +++ b/examples/light-switch-app/silabs/include/LightSwitchMgr.h @@ -23,6 +23,9 @@ #include #include +#define MIN_LEVEL 0 +#define MAX_LEVEL 254 + class LightSwitchMgr { public: @@ -45,6 +48,8 @@ class LightSwitchMgr void GenericSwitchOnShortRelease(); void TriggerLightSwitchAction(LightSwitchAction action, bool isGroupCommand = false); + void TriggerLevelControlAction(uint8_t level, bool isGroupCommand = false); + uint8_t currentLevel; static LightSwitchMgr & GetInstance() { return sSwitch; } diff --git a/examples/light-switch-app/silabs/src/AppTask.cpp b/examples/light-switch-app/silabs/src/AppTask.cpp index 140a99136d..15fc7b1982 100644 --- a/examples/light-switch-app/silabs/src/AppTask.cpp +++ b/examples/light-switch-app/silabs/src/AppTask.cpp @@ -52,6 +52,8 @@ #define APP_FUNCTION_BUTTON 0 #define APP_LIGHT_SWITCH 1 +#define LEVEL_UP_SWITCH 1 +#define LEVEL_DOWN_SWITCH 0 namespace { constexpr chip::EndpointId kLightSwitchEndpoint = 1; constexpr chip::EndpointId kGenericSwitchEndpoint = 2; @@ -130,7 +132,7 @@ void AppTask::AppTaskMain(void * pvParameter) } } -void AppTask::SwitchActionEventHandler(AppEvent * aEvent) +void AppTask::LevelUpEventHandler(AppEvent * aEvent) { VerifyOrReturn(aEvent->Type == AppEvent::kEventType_Button); @@ -138,16 +140,53 @@ void AppTask::SwitchActionEventHandler(AppEvent * aEvent) if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonPressed)) { - mCurrentButtonState = !mCurrentButtonState; - LightSwitchMgr::LightSwitchAction action = - mCurrentButtonState ? LightSwitchMgr::LightSwitchAction::On : LightSwitchMgr::LightSwitchAction::Off; - - LightSwitchMgr::GetInstance().TriggerLightSwitchAction(action); + if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL) + { + LightSwitchMgr::LightSwitchAction action = LightSwitchMgr::LightSwitchAction::On; + LightSwitchMgr::GetInstance().TriggerLightSwitchAction(action); + mCurrentButtonState = true; + } + // level implementation + if (LightSwitchMgr::GetInstance().currentLevel <= MAX_LEVEL) + { + LightSwitchMgr::GetInstance().currentLevel++; + LightSwitchMgr::GetInstance().TriggerLevelControlAction(LightSwitchMgr::GetInstance().currentLevel); + } +#ifdef DISPLAY_ENABLED + sAppTask.GetLCD().WriteDemoUI(mCurrentButtonState); +#endif LightSwitchMgr::GetInstance().GenericSwitchOnInitialPress(); + } + else if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonReleased)) + { + LightSwitchMgr::GetInstance().GenericSwitchOnShortRelease(); + } +} +void AppTask::LevelDownEventHandler(AppEvent * aEvent) +{ + VerifyOrReturn(aEvent->Type == AppEvent::kEventType_Button); + + static bool mCurrentButtonState = false; + + if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonPressed)) + { + // level implementation + if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL) + { + LightSwitchMgr::GetInstance().currentLevel--; + LightSwitchMgr::GetInstance().TriggerLevelControlAction(LightSwitchMgr::GetInstance().currentLevel); + } + if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL) + { + LightSwitchMgr::LightSwitchAction action = LightSwitchMgr::LightSwitchAction::Off; + LightSwitchMgr::GetInstance().TriggerLightSwitchAction(action); + mCurrentButtonState = false; + } #ifdef DISPLAY_ENABLED sAppTask.GetLCD().WriteDemoUI(mCurrentButtonState); #endif + LightSwitchMgr::GetInstance().GenericSwitchOnInitialPress(); } else if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonReleased)) { @@ -157,18 +196,17 @@ void AppTask::SwitchActionEventHandler(AppEvent * aEvent) void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) { - AppEvent button_event = {}; - button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.Action = btnAction; - - if (button == APP_LIGHT_SWITCH) + AppEvent button_event = {}; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.Action = btnAction; + if (button == LEVEL_UP_SWITCH) { - button_event.Handler = SwitchActionEventHandler; + button_event.Handler = LevelUpEventHandler; sAppTask.PostEvent(&button_event); } - else if (button == APP_FUNCTION_BUTTON) + else if (button == LEVEL_DOWN_SWITCH) { - button_event.Handler = BaseApplication::ButtonHandler; + button_event.Handler = LevelDownEventHandler; sAppTask.PostEvent(&button_event); } } diff --git a/examples/light-switch-app/silabs/src/BindingHandler.cpp b/examples/light-switch-app/silabs/src/BindingHandler.cpp index 56f7c306f9..1b923e5185 100644 --- a/examples/light-switch-app/silabs/src/BindingHandler.cpp +++ b/examples/light-switch-app/silabs/src/BindingHandler.cpp @@ -61,6 +61,28 @@ void ProcessOnOffUnicastBindingCommand(CommandId commandId, const EmberBindingTa } } +void ProcessLevelControlUnicastBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, + Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, + BindingCommandData * data) +{ + auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) { + ChipLogProgress(NotSpecified, "MoveToLevel command succeeds"); + }; + + auto onFailure = [](CHIP_ERROR error) { + ChipLogError(NotSpecified, "MoveToLevel command failed: %" CHIP_ERROR_FORMAT, error.Format()); + }; + + switch (commandId) + { + case Clusters::LevelControl::Commands::Move::Id: + Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; + moveCommand.level = data->level; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveCommand, onSuccess, onFailure); + break; + } +} + void ProcessOnOffGroupBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding) { Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager(); @@ -85,6 +107,20 @@ void ProcessOnOffGroupBindingCommand(CommandId commandId, const EmberBindingTabl } } +void ProcessLevelControlGroupBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, BindingCommandData * data) +{ + Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager(); + + switch (commandId) + { + case Clusters::LevelControl::Commands::Move::Id: + Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; + moveCommand.level = data->level; + Controller::InvokeCommandRequest(exchangeMgr, binding.fabricIndex, binding.groupId, moveCommand); + break; + } +} + void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, void * context) { VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); @@ -97,6 +133,9 @@ void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, Operation case Clusters::OnOff::Id: ProcessOnOffGroupBindingCommand(data->commandId, binding); break; + case Clusters::LevelControl::Id: + ProcessLevelControlGroupBindingCommand(data->commandId, binding, data); + break; } } else if (binding.type == MATTER_UNICAST_BINDING && !data->isGroup) @@ -108,6 +147,10 @@ void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, Operation ProcessOnOffUnicastBindingCommand(data->commandId, binding, peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value()); break; + case Clusters::LevelControl::Id: + ProcessLevelControlUnicastBindingCommand(data->commandId, binding, peer_device->GetExchangeManager(), + peer_device->GetSecureSession().Value(), data); + break; } } } @@ -141,6 +184,14 @@ void SwitchWorkerFunction(intptr_t context) BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data)); } +void LevelWorkerFunction(intptr_t context) +{ + VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "LevelWorkerFunction - Invalid work data")); + + BindingCommandData * data = reinterpret_cast(context); + BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data)); +} + void BindingWorkerFunction(intptr_t context) { VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "BindingWorkerFunction - Invalid work data")); diff --git a/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp b/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp index b33ac42630..9b25883919 100644 --- a/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp +++ b/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp @@ -125,6 +125,20 @@ void LightSwitchMgr::TriggerLightSwitchAction(LightSwitchAction action, bool isG DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); } +void LightSwitchMgr::TriggerLevelControlAction(uint8_t level, bool isGroupCommand) +{ + BindingCommandData * data = Platform::New(); + + data->clusterId = chip::app::Clusters::LevelControl::Id; + data->isGroup = isGroupCommand; + + data->commandId = chip::app::Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; + data->level = level; + + ChipLogProgress(DeviceLayer, "Level is - %d", data->level); + DeviceLayer::PlatformMgr().ScheduleWork(LevelWorkerFunction, reinterpret_cast(data)); +} + void LightSwitchMgr::GenericSwitchWorkerFunction(intptr_t context) { diff --git a/examples/light-switch-app/silabs/src/ShellCommands.cpp b/examples/light-switch-app/silabs/src/ShellCommands.cpp index 167453906e..9b3337d0fb 100644 --- a/examples/light-switch-app/silabs/src/ShellCommands.cpp +++ b/examples/light-switch-app/silabs/src/ShellCommands.cpp @@ -20,6 +20,7 @@ #include "ShellCommands.h" #include "BindingHandler.h" +#include "LightSwitchMgr.h" #include #include @@ -38,9 +39,11 @@ using Shell::streamer_printf; Engine sShellSwitchSubCommands; Engine sShellSwitchOnOffSubCommands; +Engine sShellSwitchLevelControlSubCommands; Engine sShellSwitchGroupsSubCommands; Engine sShellSwitchGroupsOnOffSubCommands; +Engine sShellSwitchGroupsLevelControlSubCommands; Engine sShellSwitchBindingSubCommands; @@ -114,6 +117,45 @@ CHIP_ERROR ToggleSwitchCommandHandler(int argc, char ** argv) return CHIP_NO_ERROR; } +/******************************************************** + * LevelControl switch shell functions + *********************************************************/ + +CHIP_ERROR LevelControlHelpHandler(int argc, char ** argv) +{ + sShellSwitchLevelControlSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR LevelControlSwitchCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return LevelControlHelpHandler(argc, argv); + } + + return sShellSwitchLevelControlSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR MoveToLevelCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; + data->clusterId = Clusters::LevelControl::Id; + data->level = atoi(argv[0]); + if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL && data->level == MIN_LEVEL) + { + OffSwitchCommandHandler(0,NULL); + } + if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL && data->level > MIN_LEVEL) + { + OnSwitchCommandHandler(1,NULL); + } + LightSwitchMgr::GetInstance().currentLevel = data->level; + DeviceLayer::PlatformMgr().ScheduleWork(LevelWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + /******************************************************** * bind switch shell functions *********************************************************/ @@ -238,6 +280,47 @@ CHIP_ERROR GroupToggleSwitchCommandHandler(int argc, char ** argv) return CHIP_NO_ERROR; } +/******************************************************** + * Groups LevelControl switch shell functions + *********************************************************/ + +CHIP_ERROR GroupsLevelControlHelpHandler(int argc, char ** argv) +{ + sShellSwitchGroupsLevelControlSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR GroupsLevelControlSwitchCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return GroupsLevelControlHelpHandler(argc, argv); + } + + return sShellSwitchGroupsLevelControlSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR GroupLevelControlSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; + data->clusterId = Clusters::LevelControl::Id; + data->level = atoi(argv[0]); + data->isGroup = true; + + if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL && data->level == MIN_LEVEL) + { + OffSwitchCommandHandler(0,NULL); + } + if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL && data->level > MIN_LEVEL) + { + OnSwitchCommandHandler(1,NULL); + } + LightSwitchMgr::GetInstance().currentLevel = data->level; + DeviceLayer::PlatformMgr().ScheduleWork(LevelWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + /** * @brief configures switch matter shell */ @@ -246,6 +329,7 @@ void RegisterSwitchCommands() static const shell_command_t sSwitchSubCommands[] = { { &SwitchHelpHandler, "help", "Usage: switch " }, { &OnOffSwitchCommandHandler, "onoff", " Usage: switch onoff " }, + { &LevelControlSwitchCommandHandler, "levelcontrol", " Usage: switch levelcontrol " }, { &GroupsSwitchCommandHandler, "groups", "Usage: switch groups " }, { &BindingSwitchCommandHandler, "binding", "Usage: switch binding " } }; @@ -257,6 +341,11 @@ void RegisterSwitchCommands() { &ToggleSwitchCommandHandler, "toggle", "Sends toggle command to bound lighting app" } }; + static const shell_command_t sSwitchLevelControlSubCommands[] = { + { &LevelControlHelpHandler, "help", "Usage : switch levelcontrol " }, + { &MoveToLevelCommandHandler, "move-to-level-with-on-off", "Sends move-to-level command to bound lighting app" }, + }; + static const shell_command_t sSwitchGroupsSubCommands[] = { { &GroupsHelpHandler, "help", "Usage: switch groups " }, { &GroupsOnOffSwitchCommandHandler, "onoff", "Usage: switch groups onoff " } }; @@ -268,6 +357,11 @@ void RegisterSwitchCommands() { &GroupToggleSwitchCommandHandler, "toggle", "Sends toggle command to group" } }; + static const shell_command_t sSwitchGroupsLevelControlSubCommands[] = { + { &GroupsLevelControlHelpHandler, "help", "Usage: switch groups levelcontrol " }, + { &GroupLevelControlSwitchCommandHandler, "move-to-level-with-on-off", "Sends move-to-level command to bound group" }, + }; + static const shell_command_t sSwitchBindingSubCommands[] = { { &BindingHelpHandler, "help", "Usage: switch binding " }, { &BindingGroupBindCommandHandler, "group", "Usage: switch binding group " }, @@ -278,7 +372,9 @@ void RegisterSwitchCommands() "Light-switch commands. Usage: switch " }; sShellSwitchGroupsOnOffSubCommands.RegisterCommands(sSwitchGroupsOnOffSubCommands, ArraySize(sSwitchGroupsOnOffSubCommands)); + sShellSwitchGroupsLevelControlSubCommands.RegisterCommands(sSwitchGroupsLevelControlSubCommands, ArraySize(sSwitchGroupsLevelControlSubCommands)); sShellSwitchOnOffSubCommands.RegisterCommands(sSwitchOnOffSubCommands, ArraySize(sSwitchOnOffSubCommands)); + sShellSwitchLevelControlSubCommands.RegisterCommands(sSwitchLevelControlSubCommands, ArraySize(sSwitchLevelControlSubCommands)); sShellSwitchGroupsSubCommands.RegisterCommands(sSwitchGroupsSubCommands, ArraySize(sSwitchGroupsSubCommands)); sShellSwitchBindingSubCommands.RegisterCommands(sSwitchBindingSubCommands, ArraySize(sSwitchBindingSubCommands)); sShellSwitchSubCommands.RegisterCommands(sSwitchSubCommands, ArraySize(sSwitchSubCommands)); From 68201f8ee4bdf148bce4b822b7fb69f3f7b5a24c Mon Sep 17 00:00:00 2001 From: Arun Padakanti Date: Wed, 27 Nov 2024 00:34:11 +0530 Subject: [PATCH 2/5] Added group support for Level control and code-cleanup --- .../silabs/include/BindingHandler.h | 1 - .../light-switch-app/silabs/src/AppTask.cpp | 68 +++++-------------- .../silabs/src/BindingHandler.cpp | 28 +++----- .../silabs/src/LightSwitchMgr.cpp | 2 +- .../silabs/src/ShellCommands.cpp | 4 +- 5 files changed, 29 insertions(+), 74 deletions(-) diff --git a/examples/light-switch-app/silabs/include/BindingHandler.h b/examples/light-switch-app/silabs/include/BindingHandler.h index 636af11526..79d1d98738 100644 --- a/examples/light-switch-app/silabs/include/BindingHandler.h +++ b/examples/light-switch-app/silabs/include/BindingHandler.h @@ -22,7 +22,6 @@ CHIP_ERROR InitBindingHandler(); void SwitchWorkerFunction(intptr_t context); -void LevelWorkerFunction(intptr_t context); void BindingWorkerFunction(intptr_t context); struct BindingCommandData diff --git a/examples/light-switch-app/silabs/src/AppTask.cpp b/examples/light-switch-app/silabs/src/AppTask.cpp index 15fc7b1982..3fb600e6db 100644 --- a/examples/light-switch-app/silabs/src/AppTask.cpp +++ b/examples/light-switch-app/silabs/src/AppTask.cpp @@ -52,8 +52,6 @@ #define APP_FUNCTION_BUTTON 0 #define APP_LIGHT_SWITCH 1 -#define LEVEL_UP_SWITCH 1 -#define LEVEL_DOWN_SWITCH 0 namespace { constexpr chip::EndpointId kLightSwitchEndpoint = 1; constexpr chip::EndpointId kGenericSwitchEndpoint = 2; @@ -132,7 +130,7 @@ void AppTask::AppTaskMain(void * pvParameter) } } -void AppTask::LevelUpEventHandler(AppEvent * aEvent) +void AppTask::SwitchActionEventHandler(AppEvent * aEvent) { VerifyOrReturn(aEvent->Type == AppEvent::kEventType_Button); @@ -140,53 +138,18 @@ void AppTask::LevelUpEventHandler(AppEvent * aEvent) if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonPressed)) { - if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL) - { - LightSwitchMgr::LightSwitchAction action = LightSwitchMgr::LightSwitchAction::On; - LightSwitchMgr::GetInstance().TriggerLightSwitchAction(action); - mCurrentButtonState = true; - } - // level implementation - if (LightSwitchMgr::GetInstance().currentLevel <= MAX_LEVEL) - { - LightSwitchMgr::GetInstance().currentLevel++; - LightSwitchMgr::GetInstance().TriggerLevelControlAction(LightSwitchMgr::GetInstance().currentLevel); - } -#ifdef DISPLAY_ENABLED - sAppTask.GetLCD().WriteDemoUI(mCurrentButtonState); -#endif - LightSwitchMgr::GetInstance().GenericSwitchOnInitialPress(); - } - else if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonReleased)) - { - LightSwitchMgr::GetInstance().GenericSwitchOnShortRelease(); - } -} + mCurrentButtonState = !mCurrentButtonState; + LightSwitchMgr::LightSwitchAction action = + mCurrentButtonState ? LightSwitchMgr::LightSwitchAction::On : LightSwitchMgr::LightSwitchAction::Off; -void AppTask::LevelDownEventHandler(AppEvent * aEvent) -{ - VerifyOrReturn(aEvent->Type == AppEvent::kEventType_Button); - - static bool mCurrentButtonState = false; + LightSwitchMgr::GetInstance().TriggerLightSwitchAction(action); + LightSwitchMgr::GetInstance().currentLevel = mCurrentButtonState ? MAX_LEVEL : MIN_LEVEL; + LightSwitchMgr::GetInstance().TriggerLevelControlAction(LightSwitchMgr::GetInstance().currentLevel); + LightSwitchMgr::GetInstance().GenericSwitchOnInitialPress(); - if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonPressed)) - { - // level implementation - if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL) - { - LightSwitchMgr::GetInstance().currentLevel--; - LightSwitchMgr::GetInstance().TriggerLevelControlAction(LightSwitchMgr::GetInstance().currentLevel); - } - if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL) - { - LightSwitchMgr::LightSwitchAction action = LightSwitchMgr::LightSwitchAction::Off; - LightSwitchMgr::GetInstance().TriggerLightSwitchAction(action); - mCurrentButtonState = false; - } #ifdef DISPLAY_ENABLED sAppTask.GetLCD().WriteDemoUI(mCurrentButtonState); #endif - LightSwitchMgr::GetInstance().GenericSwitchOnInitialPress(); } else if (aEvent->ButtonEvent.Action == static_cast(SilabsPlatform::ButtonAction::ButtonReleased)) { @@ -196,17 +159,18 @@ void AppTask::LevelDownEventHandler(AppEvent * aEvent) void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) { - AppEvent button_event = {}; - button_event.Type = AppEvent::kEventType_Button; - button_event.ButtonEvent.Action = btnAction; - if (button == LEVEL_UP_SWITCH) + AppEvent button_event = {}; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.Action = btnAction; + + if (button == APP_LIGHT_SWITCH) { - button_event.Handler = LevelUpEventHandler; + button_event.Handler = SwitchActionEventHandler; sAppTask.PostEvent(&button_event); } - else if (button == LEVEL_DOWN_SWITCH) + else if (button == APP_FUNCTION_BUTTON) { - button_event.Handler = LevelDownEventHandler; + button_event.Handler = BaseApplication::ButtonHandler; sAppTask.PostEvent(&button_event); } } diff --git a/examples/light-switch-app/silabs/src/BindingHandler.cpp b/examples/light-switch-app/silabs/src/BindingHandler.cpp index 1b923e5185..6e2a76c3b6 100644 --- a/examples/light-switch-app/silabs/src/BindingHandler.cpp +++ b/examples/light-switch-app/silabs/src/BindingHandler.cpp @@ -75,11 +75,11 @@ void ProcessLevelControlUnicastBindingCommand(CommandId commandId, const EmberBi switch (commandId) { - case Clusters::LevelControl::Commands::Move::Id: - Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; - moveCommand.level = data->level; - Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveCommand, onSuccess, onFailure); - break; + case Clusters::LevelControl::Commands::Move::Id: + Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; + moveCommand.level = data->level; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveCommand, onSuccess, onFailure); + break; } } @@ -113,11 +113,11 @@ void ProcessLevelControlGroupBindingCommand(CommandId commandId, const EmberBind switch (commandId) { - case Clusters::LevelControl::Commands::Move::Id: - Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; - moveCommand.level = data->level; - Controller::InvokeCommandRequest(exchangeMgr, binding.fabricIndex, binding.groupId, moveCommand); - break; + case Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id: + Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; + moveCommand.level = data->level; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, moveCommand); + break; } } @@ -184,14 +184,6 @@ void SwitchWorkerFunction(intptr_t context) BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data)); } -void LevelWorkerFunction(intptr_t context) -{ - VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "LevelWorkerFunction - Invalid work data")); - - BindingCommandData * data = reinterpret_cast(context); - BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data)); -} - void BindingWorkerFunction(intptr_t context) { VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "BindingWorkerFunction - Invalid work data")); diff --git a/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp b/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp index 9b25883919..7cfaa85540 100644 --- a/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp +++ b/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp @@ -136,7 +136,7 @@ void LightSwitchMgr::TriggerLevelControlAction(uint8_t level, bool isGroupComman data->level = level; ChipLogProgress(DeviceLayer, "Level is - %d", data->level); - DeviceLayer::PlatformMgr().ScheduleWork(LevelWorkerFunction, reinterpret_cast(data)); + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); } void LightSwitchMgr::GenericSwitchWorkerFunction(intptr_t context) diff --git a/examples/light-switch-app/silabs/src/ShellCommands.cpp b/examples/light-switch-app/silabs/src/ShellCommands.cpp index 9b3337d0fb..7e48218bb1 100644 --- a/examples/light-switch-app/silabs/src/ShellCommands.cpp +++ b/examples/light-switch-app/silabs/src/ShellCommands.cpp @@ -152,7 +152,7 @@ CHIP_ERROR MoveToLevelCommandHandler(int argc, char ** argv) OnSwitchCommandHandler(1,NULL); } LightSwitchMgr::GetInstance().currentLevel = data->level; - DeviceLayer::PlatformMgr().ScheduleWork(LevelWorkerFunction, reinterpret_cast(data)); + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); return CHIP_NO_ERROR; } @@ -317,7 +317,7 @@ CHIP_ERROR GroupLevelControlSwitchCommandHandler(int argc, char ** argv) OnSwitchCommandHandler(1,NULL); } LightSwitchMgr::GetInstance().currentLevel = data->level; - DeviceLayer::PlatformMgr().ScheduleWork(LevelWorkerFunction, reinterpret_cast(data)); + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); return CHIP_NO_ERROR; } From f68295cc733c7ba93fb08eb164ee38c56bc3afa7 Mon Sep 17 00:00:00 2001 From: Arun Padakanti Date: Wed, 27 Nov 2024 00:38:06 +0530 Subject: [PATCH 3/5] Updated Device type to dimmablelight in zap --- .../light-switch-common/light-switch-app.zap | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap index 02fa237b36..3101a57697 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.zap +++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap @@ -4400,29 +4400,29 @@ }, { "id": 2, - "name": "MA-onofflightswitch", + "name": "MA-dimmablelight", "deviceTypeRef": { - "code": 259, + "code": 257, "profileId": 259, - "label": "MA-onofflightswitch", - "name": "MA-onofflightswitch" + "label": "MA-dimmablelight", + "name": "MA-dimmablelight" }, "deviceTypes": [ { - "code": 259, + "code": 257, "profileId": 259, - "label": "MA-onofflightswitch", - "name": "MA-onofflightswitch" + "label": "MA-dimmablelight", + "name": "MA-dimmablelight" } ], "deviceVersions": [ 1 ], "deviceIdentifiers": [ - 259 + 257 ], - "deviceTypeName": "MA-onofflightswitch", - "deviceTypeCode": 259, + "deviceTypeName": "MA-dimmablelight", + "deviceTypeCode": 257, "deviceTypeProfileId": 259, "clusters": [ { @@ -5651,7 +5651,7 @@ "parentEndpointIdentifier": null }, { - "endpointTypeName": "MA-onofflightswitch", + "endpointTypeName": "MA-dimmablelight", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, From a4b092808af4b60dd95bb1a8920cfa6fa9657384 Mon Sep 17 00:00:00 2001 From: Arun Padakanti Date: Wed, 27 Nov 2024 14:40:19 +0530 Subject: [PATCH 4/5] Addressed review comments --- .../silabs/include/AppEvent.h | 1 - .../light-switch-app/silabs/include/AppTask.h | 2 -- .../silabs/src/BindingHandler.cpp | 19 +++++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/light-switch-app/silabs/include/AppEvent.h b/examples/light-switch-app/silabs/include/AppEvent.h index 6d7c944ecd..7a19b719ed 100644 --- a/examples/light-switch-app/silabs/include/AppEvent.h +++ b/examples/light-switch-app/silabs/include/AppEvent.h @@ -38,7 +38,6 @@ struct AppEvent { struct { - uint8_t ButtonId; uint8_t Action; } ButtonEvent; struct diff --git a/examples/light-switch-app/silabs/include/AppTask.h b/examples/light-switch-app/silabs/include/AppTask.h index 9c5dbade25..71ca4b427b 100644 --- a/examples/light-switch-app/silabs/include/AppTask.h +++ b/examples/light-switch-app/silabs/include/AppTask.h @@ -102,6 +102,4 @@ class AppTask : public BaseApplication * @param aEvent button event being processed */ static void SwitchActionEventHandler(AppEvent * aEvent); - static void LevelUpEventHandler(AppEvent * aEvent); - static void LevelDownEventHandler(AppEvent * aEvent); }; diff --git a/examples/light-switch-app/silabs/src/BindingHandler.cpp b/examples/light-switch-app/silabs/src/BindingHandler.cpp index 6e2a76c3b6..3c4dab061d 100644 --- a/examples/light-switch-app/silabs/src/BindingHandler.cpp +++ b/examples/light-switch-app/silabs/src/BindingHandler.cpp @@ -35,11 +35,11 @@ void ProcessOnOffUnicastBindingCommand(CommandId commandId, const EmberBindingTa Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle) { auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) { - ChipLogProgress(NotSpecified, "OnOff command succeeds"); + ChipLogProgress(AppServer, "OnOff command succeeds"); }; auto onFailure = [](CHIP_ERROR error) { - ChipLogError(NotSpecified, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format()); + ChipLogError(AppServer, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format()); }; switch (commandId) @@ -66,11 +66,11 @@ void ProcessLevelControlUnicastBindingCommand(CommandId commandId, const EmberBi BindingCommandData * data) { auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) { - ChipLogProgress(NotSpecified, "MoveToLevel command succeeds"); + ChipLogProgress(AppServer, "LevelControl command succeeds"); }; auto onFailure = [](CHIP_ERROR error) { - ChipLogError(NotSpecified, "MoveToLevel command failed: %" CHIP_ERROR_FORMAT, error.Format()); + ChipLogError(AppServer, "LevelControl command failed: %" CHIP_ERROR_FORMAT, error.Format()); }; switch (commandId) @@ -123,7 +123,7 @@ void ProcessLevelControlGroupBindingCommand(CommandId commandId, const EmberBind void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, void * context) { - VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); + VerifyOrReturn(context != nullptr, ChipLogError(AppServer, "OnDeviceConnectedFn: context is null")); BindingCommandData * data = static_cast(context); if (binding.type == MATTER_MULTICAST_BINDING && data->isGroup) @@ -148,6 +148,7 @@ void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, Operation peer_device->GetSecureSession().Value()); break; case Clusters::LevelControl::Id: + VerifyOrDie(peer_device != nullptr && peer_device->ConnectionReady()); ProcessLevelControlUnicastBindingCommand(data->commandId, binding, peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), data); break; @@ -157,7 +158,7 @@ void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, Operation void LightSwitchContextReleaseHandler(void * context) { - VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "LightSwitchContextReleaseHandler: context is null")); + VerifyOrReturn(context != nullptr, ChipLogError(AppServer, "LightSwitchContextReleaseHandler: context is null")); Platform::Delete(static_cast(context)); } @@ -178,15 +179,17 @@ void InitBindingHandlerInternal(intptr_t arg) void SwitchWorkerFunction(intptr_t context) { - VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "SwitchWorkerFunction - Invalid work data")); + VerifyOrReturn(context != 0, ChipLogError(AppServer, "SwitchWorkerFunction - Invalid work data")); BindingCommandData * data = reinterpret_cast(context); BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data)); + + Platform::Delete(data); } void BindingWorkerFunction(intptr_t context) { - VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "BindingWorkerFunction - Invalid work data")); + VerifyOrReturn(context != 0, ChipLogError(AppServer, "BindingWorkerFunction - Invalid work data")); EmberBindingTableEntry * entry = reinterpret_cast(context); AddBindingEntry(*entry); From 56fc42c0705b42b8be0c8910d21fbe06e6f8627e Mon Sep 17 00:00:00 2001 From: Arun Padakanti Date: Wed, 27 Nov 2024 15:18:29 +0530 Subject: [PATCH 5/5] Made structural changes --- .../silabs/include/BindingHandler.h | 8 +++++++- .../silabs/src/BindingHandler.cpp | 4 ++-- .../silabs/src/LightSwitchMgr.cpp | 10 +++++----- .../silabs/src/ShellCommands.cpp | 20 +++++++++---------- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/examples/light-switch-app/silabs/include/BindingHandler.h b/examples/light-switch-app/silabs/include/BindingHandler.h index 79d1d98738..8a579499cd 100644 --- a/examples/light-switch-app/silabs/include/BindingHandler.h +++ b/examples/light-switch-app/silabs/include/BindingHandler.h @@ -29,6 +29,12 @@ struct BindingCommandData chip::EndpointId localEndpointId = 1; chip::CommandId commandId; chip::ClusterId clusterId; - uint8_t level; bool isGroup = false; + union + { + struct + { + uint8_t level; + } LevelData; + }; }; diff --git a/examples/light-switch-app/silabs/src/BindingHandler.cpp b/examples/light-switch-app/silabs/src/BindingHandler.cpp index 3c4dab061d..62fab2a907 100644 --- a/examples/light-switch-app/silabs/src/BindingHandler.cpp +++ b/examples/light-switch-app/silabs/src/BindingHandler.cpp @@ -77,7 +77,7 @@ void ProcessLevelControlUnicastBindingCommand(CommandId commandId, const EmberBi { case Clusters::LevelControl::Commands::Move::Id: Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; - moveCommand.level = data->level; + moveCommand.level = data->LevelData.level; Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveCommand, onSuccess, onFailure); break; } @@ -115,7 +115,7 @@ void ProcessLevelControlGroupBindingCommand(CommandId commandId, const EmberBind { case Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id: Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type moveCommand; - moveCommand.level = data->level; + moveCommand.level = data->LevelData.level; Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, moveCommand); break; } diff --git a/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp b/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp index 7cfaa85540..3322517afc 100644 --- a/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp +++ b/examples/light-switch-app/silabs/src/LightSwitchMgr.cpp @@ -129,13 +129,13 @@ void LightSwitchMgr::TriggerLevelControlAction(uint8_t level, bool isGroupComman { BindingCommandData * data = Platform::New(); - data->clusterId = chip::app::Clusters::LevelControl::Id; - data->isGroup = isGroupCommand; + data->clusterId = chip::app::Clusters::LevelControl::Id; + data->isGroup = isGroupCommand; - data->commandId = chip::app::Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; - data->level = level; + data->commandId = chip::app::Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; + data->LevelData.level = level; - ChipLogProgress(DeviceLayer, "Level is - %d", data->level); + ChipLogProgress(DeviceLayer, "Level is - %d", data->LevelData.level); DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); } diff --git a/examples/light-switch-app/silabs/src/ShellCommands.cpp b/examples/light-switch-app/silabs/src/ShellCommands.cpp index 7e48218bb1..8d8e3513d9 100644 --- a/examples/light-switch-app/silabs/src/ShellCommands.cpp +++ b/examples/light-switch-app/silabs/src/ShellCommands.cpp @@ -142,16 +142,16 @@ CHIP_ERROR MoveToLevelCommandHandler(int argc, char ** argv) BindingCommandData * data = Platform::New(); data->commandId = Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; data->clusterId = Clusters::LevelControl::Id; - data->level = atoi(argv[0]); - if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL && data->level == MIN_LEVEL) + data->LevelData.level = atoi(argv[0]); + if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL && data->LevelData.level == MIN_LEVEL) { OffSwitchCommandHandler(0,NULL); } - if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL && data->level > MIN_LEVEL) + if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL && data->LevelData.level > MIN_LEVEL) { - OnSwitchCommandHandler(1,NULL); + OnSwitchCommandHandler(0,NULL); } - LightSwitchMgr::GetInstance().currentLevel = data->level; + LightSwitchMgr::GetInstance().currentLevel = data->LevelData.level; DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); return CHIP_NO_ERROR; } @@ -305,18 +305,18 @@ CHIP_ERROR GroupLevelControlSwitchCommandHandler(int argc, char ** argv) BindingCommandData * data = Platform::New(); data->commandId = Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Id; data->clusterId = Clusters::LevelControl::Id; - data->level = atoi(argv[0]); + data->LevelData.level = atoi(argv[0]); data->isGroup = true; - if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL && data->level == MIN_LEVEL) + if (LightSwitchMgr::GetInstance().currentLevel > MIN_LEVEL && data->LevelData.level == MIN_LEVEL) { OffSwitchCommandHandler(0,NULL); } - if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL && data->level > MIN_LEVEL) + if (LightSwitchMgr::GetInstance().currentLevel == MIN_LEVEL && data->LevelData.level > MIN_LEVEL) { - OnSwitchCommandHandler(1,NULL); + OnSwitchCommandHandler(0,NULL); } - LightSwitchMgr::GetInstance().currentLevel = data->level; + LightSwitchMgr::GetInstance().currentLevel = data->LevelData.level; DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); return CHIP_NO_ERROR; }