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

[QPG] QPG examples bulk update #34501

Merged
merged 11 commits into from
Jul 25, 2024
3 changes: 3 additions & 0 deletions examples/light-switch-app/qpg/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class AppTask
static void FunctionHandler(AppEvent * aEvent);

static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState);
static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState);
static void MultiPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState);
static void LongPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState);

static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
static void UpdateLEDs(void);
Expand Down
6 changes: 5 additions & 1 deletion examples/light-switch-app/qpg/include/SwitchManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ class SwitchManager

void Init(void);
static void GenericSwitchInitialPressHandler(AppEvent * aEvent);
static void GenericSwitchReleasePressHandler(AppEvent * aEvent);
static void GenericSwitchShortReleaseHandler(AppEvent * aEvent);
static void GenericSwitchLongReleaseHandler(AppEvent * aEvent);
static void GenericSwitchLongPressHandler(AppEvent * aEvent);
static void GenericSwitchMultipressCompleteHandler(AppEvent * aEvent);
static void GenericSwitchMultipressOngoingHandler(AppEvent * aEvent);
static void ToggleHandler(AppEvent * aEvent);
static void LevelHandler(AppEvent * aEvent);
static void ColorHandler(AppEvent * aEvent);
Expand Down
158 changes: 151 additions & 7 deletions examples/light-switch-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ using namespace ::chip;
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>

#if defined(QORVO_QPINCFG_ENABLE)
#include "qPinCfg.h"
#endif // QORVO_QPINCFG_ENABLE

#include <inet/EndPointStateOpenThread.h>

#include <DeviceInfoProviderImpl.h>
Expand All @@ -58,9 +62,16 @@ using namespace ::chip::DeviceLayer;

#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
#define SWITCH_MULTIPRESS_WINDOW_MS 500
#define SWITCH_LONGPRESS_WINDOW_MS 3000
#define SWITCH_BUTTON_PRESSED 1
#define SWITCH_BUTTON_UNPRESSED 0

#define APP_TASK_STACK_SIZE (2 * 1024)
#define APP_TASK_PRIORITY 2
#define APP_EVENT_QUEUE_SIZE 10
#define SECONDS_IN_HOUR (3600) // we better keep this 3600
#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour

namespace {
TaskHandle_t sAppTaskHandle;
Expand All @@ -70,6 +81,9 @@ bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sHaveBLEConnections = false;
bool sIsBLEAdvertisingEnabled = false;
bool sIsMultipressOngoing = false;
bool sLongPressDetected = false;
uint8_t sSwitchButtonState = SWITCH_BUTTON_UNPRESSED;

// NOTE! This key is for test/certification only and should not be available in production devices!
uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
Expand Down Expand Up @@ -141,11 +155,19 @@ void OnTriggerIdentifyEffect(Identify * identify)
}
}

Identify gIdentify = {
Identify gIdentifyEp1 = {
chip::EndpointId{ 1 },
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); },
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); },
Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator,
Clusters::Identify::IdentifyTypeEnum::kNone,
OnTriggerIdentifyEffect,
};

Identify gIdentifyEp2 = {
chip::EndpointId{ 2 },
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); },
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); },
Clusters::Identify::IdentifyTypeEnum::kNone,
OnTriggerIdentifyEffect,
};

Expand Down Expand Up @@ -224,6 +246,14 @@ CHIP_ERROR AppTask::Init()
{
CHIP_ERROR err = CHIP_NO_ERROR;

#if defined(QORVO_QPINCFG_ENABLE)
qResult_t res = Q_OK;
res = qPinCfg_Init(NULL);
if (res != Q_OK)
{
ChipLogError(NotSpecified, "qPinCfg_Init failed: %d", res);
}
#endif // QORVO_QPINCFG_ENABLE
PlatformMgr().AddEventHandler(MatterEventHandler, 0);

ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);
Expand Down Expand Up @@ -255,6 +285,14 @@ CHIP_ERROR AppTask::Init()
sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled();
UpdateLEDs();

err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
TotalHoursTimerHandler, this);

if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
}

return err;
}

Expand All @@ -275,7 +313,9 @@ void AppTask::AppTaskMain(void * pvParameter)

void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed)
{
ChipLogProgress(NotSpecified, "ButtonEventHandler %d, %d", btnIdx, btnPressed);
CHIP_ERROR err = CHIP_NO_ERROR;

ChipLogDetail(NotSpecified, "ButtonEventHandler %d, %d", btnIdx, btnPressed);

AppEvent button_event = {};
button_event.Type = AppEvent::kEventType_Button;
Expand All @@ -297,13 +337,54 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed)
case APP_FUNCTION2_SWITCH: {
if (!btnPressed)
{
ChipLogProgress(NotSpecified, "Switch release press");
button_event.Handler = SwitchMgr().GenericSwitchReleasePressHandler;
ChipLogDetail(NotSpecified, "Switch button released");

button_event.Handler =
sLongPressDetected ? SwitchMgr().GenericSwitchLongReleaseHandler : SwitchMgr().GenericSwitchShortReleaseHandler;

sIsMultipressOngoing = true;
sSwitchButtonState = SWITCH_BUTTON_UNPRESSED;
sLongPressDetected = false;

chip::DeviceLayer::SystemLayer().CancelTimer(MultiPressTimeoutHandler, NULL);
// we start the MultiPress feature window after releasing the button
err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(SWITCH_MULTIPRESS_WINDOW_MS),
MultiPressTimeoutHandler, NULL);

if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
}
}
else
{
ChipLogProgress(NotSpecified, "Switch initial press");
button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
ChipLogDetail(NotSpecified, "Switch button pressed");

sSwitchButtonState = SWITCH_BUTTON_PRESSED;

chip::DeviceLayer::SystemLayer().CancelTimer(LongPressTimeoutHandler, NULL);
// we need to check if this is short or long press
err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(SWITCH_LONGPRESS_WINDOW_MS),
LongPressTimeoutHandler, NULL);

if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
}

// if we have active multipress window we need to send extra event
if (sIsMultipressOngoing)
{
ChipLogDetail(NotSpecified, "Switch MultipressOngoing");
button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
sAppTask.PostEvent(&button_event);
chip::DeviceLayer::SystemLayer().CancelTimer(MultiPressTimeoutHandler, NULL);
button_event.Handler = SwitchMgr().GenericSwitchMultipressOngoingHandler;
}
else
{
button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
}
}
break;
}
Expand Down Expand Up @@ -348,6 +429,69 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState)
sAppTask.PostEvent(&event);
}

void AppTask::MultiPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState)
{
ChipLogDetail(NotSpecified, "MultiPressTimeoutHandler");

sIsMultipressOngoing = false;

AppEvent multipress_event = {};
multipress_event.Type = AppEvent::kEventType_Button;
multipress_event.Handler = SwitchMgr().GenericSwitchMultipressCompleteHandler;

sAppTask.PostEvent(&multipress_event);
}

void AppTask::LongPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState)
{
ChipLogDetail(NotSpecified, "LongPressTimeoutHandler");

// if the button is still pressed after threshold time, this is a LongPress, otherwise jsut ignore it
if (sSwitchButtonState == SWITCH_BUTTON_PRESSED)
{
sLongPressDetected = true;
AppEvent longpress_event = {};
longpress_event.Type = AppEvent::kEventType_Button;
longpress_event.Handler = SwitchMgr().GenericSwitchLongPressHandler;

sAppTask.PostEvent(&longpress_event);
}
}

void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState)
{
ChipLogDetail(NotSpecified, "HourlyTimer");

CHIP_ERROR err;
uint32_t totalOperationalHours = 0;

err = ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours);

if (err == CHIP_NO_ERROR)
{
ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours +
(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR));
}
else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)
{
totalOperationalHours = 0; // set this explicitly to 0 for safety
ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours +
(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR));
}
else
{
ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
}

err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
TotalHoursTimerHandler, nullptr);

if (err != CHIP_NO_ERROR)
{
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
}
}

void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
if (aEvent->Type != AppEvent::kEventType_Timer)
Expand Down
83 changes: 76 additions & 7 deletions examples/light-switch-app/qpg/src/SwitchManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@
SwitchManager SwitchManager::sSwitch;
using namespace ::chip;
using namespace chip::DeviceLayer;
static uint8_t multiPressCount = 1;

void SwitchManager::Init(void)
{
// init - TODO
uint8_t multiPressMax = 2;
chip::app::Clusters::Switch::Attributes::MultiPressMax::Set(GENERICSWITCH_ENDPOINT_ID, multiPressMax);
}

void SwitchManager::ToggleHandler(AppEvent * aEvent)
Expand All @@ -46,6 +48,7 @@ void SwitchManager::ToggleHandler(AppEvent * aEvent)
data->localEndpointId = SWITCH_ENDPOINT_ID;
data->clusterId = chip::app::Clusters::OnOff::Id;
data->commandId = chip::app::Clusters::OnOff::Commands::Toggle::Id;
data->isGroup = true;

DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
}
Expand Down Expand Up @@ -118,29 +121,95 @@ void SwitchManager::GenericSwitchInitialPressHandler(AppEvent * aEvent)
return;
}

ChipLogProgress(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition);
ChipLogDetail(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition);
SystemLayer().ScheduleLambda([newPosition] {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);
// InitialPress event takes newPosition as event data
chip::app::Clusters::SwitchServer::Instance().OnInitialPress(GENERICSWITCH_ENDPOINT_ID, newPosition);
});
}

void SwitchManager::GenericSwitchReleasePressHandler(AppEvent * aEvent)
void SwitchManager::GenericSwitchLongPressHandler(AppEvent * aEvent)
{
// Release moves Position from 1 (press) to 0
uint8_t newPosition = 0;
// Press moves Position from 0 (idle) to 1 (press)
uint8_t newPosition = 1;

if (aEvent->Type != AppEvent::kEventType_Button)
{
ChipLogError(NotSpecified, "Event type not supported!");
return;
}

ChipLogProgress(NotSpecified, "GenericSwitchReleasePress new position %d", newPosition);
ChipLogDetail(NotSpecified, "GenericSwitchLongPress new position %d", newPosition);
SystemLayer().ScheduleLambda([newPosition] {
// LongPress event takes newPosition as event data
chip::app::Clusters::SwitchServer::Instance().OnLongPress(GENERICSWITCH_ENDPOINT_ID, newPosition);
});
}

void SwitchManager::GenericSwitchShortReleaseHandler(AppEvent * aEvent)
{
// Release moves Position from 1 (press) to 0
uint8_t newPosition = 0;
uint8_t previousPosition = 1;

if (aEvent->Type != AppEvent::kEventType_Button)
{
ChipLogError(NotSpecified, "Event type not supported!");
return;
}

ChipLogDetail(NotSpecified, "GenericSwitchShortRelease new position %d", newPosition);
SystemLayer().ScheduleLambda([newPosition, previousPosition] {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);
// Short Release event takes newPosition as event data
chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, newPosition);
chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, previousPosition);
});
}

void SwitchManager::GenericSwitchLongReleaseHandler(AppEvent * aEvent)
{
// Release moves Position from 1 (press) to 0
uint8_t newPosition = 0;
uint8_t previousPosition = 1;

if (aEvent->Type != AppEvent::kEventType_Button)
{
ChipLogError(NotSpecified, "Event type not supported!");
return;
}

ChipLogDetail(NotSpecified, "GenericSwitchLongRelease new position %d", newPosition);
SystemLayer().ScheduleLambda([newPosition, previousPosition] {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);
// LongRelease event takes newPosition as event data
chip::app::Clusters::SwitchServer::Instance().OnLongRelease(GENERICSWITCH_ENDPOINT_ID, previousPosition);
});
}

void SwitchManager::GenericSwitchMultipressOngoingHandler(AppEvent * aEvent)
{
uint8_t newPosition = 1;

multiPressCount++;

ChipLogDetail(NotSpecified, "GenericSwitchMultiPressOngoing (%d)", multiPressCount);

SystemLayer().ScheduleLambda([newPosition] {
chip::app::Clusters::SwitchServer::Instance().OnMultiPressOngoing(GENERICSWITCH_ENDPOINT_ID, newPosition, multiPressCount);
});
}

void SwitchManager::GenericSwitchMultipressCompleteHandler(AppEvent * aEvent)
{
uint8_t previousPosition = 0;

ChipLogProgress(NotSpecified, "GenericSwitchMultiPressComplete (%d)", multiPressCount);

SystemLayer().ScheduleLambda([previousPosition] {
chip::app::Clusters::SwitchServer::Instance().OnMultiPressComplete(GENERICSWITCH_ENDPOINT_ID, previousPosition,
multiPressCount);
});

multiPressCount = 1;
}
Loading
Loading