Skip to content

Commit bfa80b9

Browse files
adamb-qdvdm-qorvolucicoprestyled-commits
authoredJul 25, 2024··
[QPG] QPG examples bulk update (#34501)
* [QPG] Add TotalOperationalHours counter for switch and TRV * [QPG] fix for switch to use correct previousPosition in ShortRelease event * [QPG] Use identify cluster on endpoint 2 for switch * feat(multicast): Add multicast binding for Matter Combo Switch Refs: APPSCS-4571 * [QPG] MultiPress and LongPress implementation for switch * [INTERNAL] Fix qPinCfg.h error * Set groups cluster to server in switch.zap and improve command handling for unicast and multicast * [QPG] PowerSource cluster added * Restyled by whitespace * Restyled by clang-format * Fixed .matter file --------- Co-authored-by: Dieter Van der Meulen <dieter.van.der.meulen@qorvo.com> Co-authored-by: lucicop <lucian.copat@qorvo.com> Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 1b1340f commit bfa80b9

File tree

11 files changed

+1151
-59
lines changed

11 files changed

+1151
-59
lines changed
 

‎examples/light-switch-app/qpg/include/AppTask.h

+3
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class AppTask
5858
static void FunctionHandler(AppEvent * aEvent);
5959

6060
static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState);
61+
static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState);
62+
static void MultiPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState);
63+
static void LongPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState);
6164

6265
static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
6366
static void UpdateLEDs(void);

‎examples/light-switch-app/qpg/include/SwitchManager.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ class SwitchManager
5555

5656
void Init(void);
5757
static void GenericSwitchInitialPressHandler(AppEvent * aEvent);
58-
static void GenericSwitchReleasePressHandler(AppEvent * aEvent);
58+
static void GenericSwitchShortReleaseHandler(AppEvent * aEvent);
59+
static void GenericSwitchLongReleaseHandler(AppEvent * aEvent);
60+
static void GenericSwitchLongPressHandler(AppEvent * aEvent);
61+
static void GenericSwitchMultipressCompleteHandler(AppEvent * aEvent);
62+
static void GenericSwitchMultipressOngoingHandler(AppEvent * aEvent);
5963
static void ToggleHandler(AppEvent * aEvent);
6064
static void LevelHandler(AppEvent * aEvent);
6165
static void ColorHandler(AppEvent * aEvent);

‎examples/light-switch-app/qpg/src/AppTask.cpp

+151-7
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ using namespace ::chip;
4242
#include <credentials/DeviceAttestationCredsProvider.h>
4343
#include <credentials/examples/DeviceAttestationCredsExample.h>
4444

45+
#if defined(QORVO_QPINCFG_ENABLE)
46+
#include "qPinCfg.h"
47+
#endif // QORVO_QPINCFG_ENABLE
48+
4549
#include <inet/EndPointStateOpenThread.h>
4650

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

5963
#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
6064
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
65+
#define SWITCH_MULTIPRESS_WINDOW_MS 500
66+
#define SWITCH_LONGPRESS_WINDOW_MS 3000
67+
#define SWITCH_BUTTON_PRESSED 1
68+
#define SWITCH_BUTTON_UNPRESSED 0
69+
6170
#define APP_TASK_STACK_SIZE (2 * 1024)
6271
#define APP_TASK_PRIORITY 2
6372
#define APP_EVENT_QUEUE_SIZE 10
73+
#define SECONDS_IN_HOUR (3600) // we better keep this 3600
74+
#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour
6475

6576
namespace {
6677
TaskHandle_t sAppTaskHandle;
@@ -70,6 +81,9 @@ bool sIsThreadProvisioned = false;
7081
bool sIsThreadEnabled = false;
7182
bool sHaveBLEConnections = false;
7283
bool sIsBLEAdvertisingEnabled = false;
84+
bool sIsMultipressOngoing = false;
85+
bool sLongPressDetected = false;
86+
uint8_t sSwitchButtonState = SWITCH_BUTTON_UNPRESSED;
7387

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

144-
Identify gIdentify = {
158+
Identify gIdentifyEp1 = {
145159
chip::EndpointId{ 1 },
146160
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); },
147161
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); },
148-
Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator,
162+
Clusters::Identify::IdentifyTypeEnum::kNone,
163+
OnTriggerIdentifyEffect,
164+
};
165+
166+
Identify gIdentifyEp2 = {
167+
chip::EndpointId{ 2 },
168+
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); },
169+
[](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); },
170+
Clusters::Identify::IdentifyTypeEnum::kNone,
149171
OnTriggerIdentifyEffect,
150172
};
151173

@@ -224,6 +246,14 @@ CHIP_ERROR AppTask::Init()
224246
{
225247
CHIP_ERROR err = CHIP_NO_ERROR;
226248

249+
#if defined(QORVO_QPINCFG_ENABLE)
250+
qResult_t res = Q_OK;
251+
res = qPinCfg_Init(NULL);
252+
if (res != Q_OK)
253+
{
254+
ChipLogError(NotSpecified, "qPinCfg_Init failed: %d", res);
255+
}
256+
#endif // QORVO_QPINCFG_ENABLE
227257
PlatformMgr().AddEventHandler(MatterEventHandler, 0);
228258

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

288+
err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
289+
TotalHoursTimerHandler, this);
290+
291+
if (err != CHIP_NO_ERROR)
292+
{
293+
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
294+
}
295+
258296
return err;
259297
}
260298

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

276314
void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed)
277315
{
278-
ChipLogProgress(NotSpecified, "ButtonEventHandler %d, %d", btnIdx, btnPressed);
316+
CHIP_ERROR err = CHIP_NO_ERROR;
317+
318+
ChipLogDetail(NotSpecified, "ButtonEventHandler %d, %d", btnIdx, btnPressed);
279319

280320
AppEvent button_event = {};
281321
button_event.Type = AppEvent::kEventType_Button;
@@ -297,13 +337,54 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed)
297337
case APP_FUNCTION2_SWITCH: {
298338
if (!btnPressed)
299339
{
300-
ChipLogProgress(NotSpecified, "Switch release press");
301-
button_event.Handler = SwitchMgr().GenericSwitchReleasePressHandler;
340+
ChipLogDetail(NotSpecified, "Switch button released");
341+
342+
button_event.Handler =
343+
sLongPressDetected ? SwitchMgr().GenericSwitchLongReleaseHandler : SwitchMgr().GenericSwitchShortReleaseHandler;
344+
345+
sIsMultipressOngoing = true;
346+
sSwitchButtonState = SWITCH_BUTTON_UNPRESSED;
347+
sLongPressDetected = false;
348+
349+
chip::DeviceLayer::SystemLayer().CancelTimer(MultiPressTimeoutHandler, NULL);
350+
// we start the MultiPress feature window after releasing the button
351+
err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(SWITCH_MULTIPRESS_WINDOW_MS),
352+
MultiPressTimeoutHandler, NULL);
353+
354+
if (err != CHIP_NO_ERROR)
355+
{
356+
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
357+
}
302358
}
303359
else
304360
{
305-
ChipLogProgress(NotSpecified, "Switch initial press");
306-
button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
361+
ChipLogDetail(NotSpecified, "Switch button pressed");
362+
363+
sSwitchButtonState = SWITCH_BUTTON_PRESSED;
364+
365+
chip::DeviceLayer::SystemLayer().CancelTimer(LongPressTimeoutHandler, NULL);
366+
// we need to check if this is short or long press
367+
err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(SWITCH_LONGPRESS_WINDOW_MS),
368+
LongPressTimeoutHandler, NULL);
369+
370+
if (err != CHIP_NO_ERROR)
371+
{
372+
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
373+
}
374+
375+
// if we have active multipress window we need to send extra event
376+
if (sIsMultipressOngoing)
377+
{
378+
ChipLogDetail(NotSpecified, "Switch MultipressOngoing");
379+
button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
380+
sAppTask.PostEvent(&button_event);
381+
chip::DeviceLayer::SystemLayer().CancelTimer(MultiPressTimeoutHandler, NULL);
382+
button_event.Handler = SwitchMgr().GenericSwitchMultipressOngoingHandler;
383+
}
384+
else
385+
{
386+
button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
387+
}
307388
}
308389
break;
309390
}
@@ -348,6 +429,69 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState)
348429
sAppTask.PostEvent(&event);
349430
}
350431

432+
void AppTask::MultiPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState)
433+
{
434+
ChipLogDetail(NotSpecified, "MultiPressTimeoutHandler");
435+
436+
sIsMultipressOngoing = false;
437+
438+
AppEvent multipress_event = {};
439+
multipress_event.Type = AppEvent::kEventType_Button;
440+
multipress_event.Handler = SwitchMgr().GenericSwitchMultipressCompleteHandler;
441+
442+
sAppTask.PostEvent(&multipress_event);
443+
}
444+
445+
void AppTask::LongPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState)
446+
{
447+
ChipLogDetail(NotSpecified, "LongPressTimeoutHandler");
448+
449+
// if the button is still pressed after threshold time, this is a LongPress, otherwise jsut ignore it
450+
if (sSwitchButtonState == SWITCH_BUTTON_PRESSED)
451+
{
452+
sLongPressDetected = true;
453+
AppEvent longpress_event = {};
454+
longpress_event.Type = AppEvent::kEventType_Button;
455+
longpress_event.Handler = SwitchMgr().GenericSwitchLongPressHandler;
456+
457+
sAppTask.PostEvent(&longpress_event);
458+
}
459+
}
460+
461+
void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState)
462+
{
463+
ChipLogDetail(NotSpecified, "HourlyTimer");
464+
465+
CHIP_ERROR err;
466+
uint32_t totalOperationalHours = 0;
467+
468+
err = ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours);
469+
470+
if (err == CHIP_NO_ERROR)
471+
{
472+
ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours +
473+
(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR));
474+
}
475+
else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)
476+
{
477+
totalOperationalHours = 0; // set this explicitly to 0 for safety
478+
ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours +
479+
(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR));
480+
}
481+
else
482+
{
483+
ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
484+
}
485+
486+
err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
487+
TotalHoursTimerHandler, nullptr);
488+
489+
if (err != CHIP_NO_ERROR)
490+
{
491+
ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
492+
}
493+
}
494+
351495
void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
352496
{
353497
if (aEvent->Type != AppEvent::kEventType_Timer)

‎examples/light-switch-app/qpg/src/SwitchManager.cpp

+76-7
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
SwitchManager SwitchManager::sSwitch;
2727
using namespace ::chip;
2828
using namespace chip::DeviceLayer;
29+
static uint8_t multiPressCount = 1;
2930

3031
void SwitchManager::Init(void)
3132
{
32-
// init - TODO
33+
uint8_t multiPressMax = 2;
34+
chip::app::Clusters::Switch::Attributes::MultiPressMax::Set(GENERICSWITCH_ENDPOINT_ID, multiPressMax);
3335
}
3436

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

5053
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
5154
}
@@ -118,29 +121,95 @@ void SwitchManager::GenericSwitchInitialPressHandler(AppEvent * aEvent)
118121
return;
119122
}
120123

121-
ChipLogProgress(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition);
124+
ChipLogDetail(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition);
122125
SystemLayer().ScheduleLambda([newPosition] {
123126
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);
124127
// InitialPress event takes newPosition as event data
125128
chip::app::Clusters::SwitchServer::Instance().OnInitialPress(GENERICSWITCH_ENDPOINT_ID, newPosition);
126129
});
127130
}
128131

129-
void SwitchManager::GenericSwitchReleasePressHandler(AppEvent * aEvent)
132+
void SwitchManager::GenericSwitchLongPressHandler(AppEvent * aEvent)
130133
{
131-
// Release moves Position from 1 (press) to 0
132-
uint8_t newPosition = 0;
134+
// Press moves Position from 0 (idle) to 1 (press)
135+
uint8_t newPosition = 1;
133136

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

140-
ChipLogProgress(NotSpecified, "GenericSwitchReleasePress new position %d", newPosition);
143+
ChipLogDetail(NotSpecified, "GenericSwitchLongPress new position %d", newPosition);
141144
SystemLayer().ScheduleLambda([newPosition] {
145+
// LongPress event takes newPosition as event data
146+
chip::app::Clusters::SwitchServer::Instance().OnLongPress(GENERICSWITCH_ENDPOINT_ID, newPosition);
147+
});
148+
}
149+
150+
void SwitchManager::GenericSwitchShortReleaseHandler(AppEvent * aEvent)
151+
{
152+
// Release moves Position from 1 (press) to 0
153+
uint8_t newPosition = 0;
154+
uint8_t previousPosition = 1;
155+
156+
if (aEvent->Type != AppEvent::kEventType_Button)
157+
{
158+
ChipLogError(NotSpecified, "Event type not supported!");
159+
return;
160+
}
161+
162+
ChipLogDetail(NotSpecified, "GenericSwitchShortRelease new position %d", newPosition);
163+
SystemLayer().ScheduleLambda([newPosition, previousPosition] {
142164
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);
143165
// Short Release event takes newPosition as event data
144-
chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, newPosition);
166+
chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, previousPosition);
167+
});
168+
}
169+
170+
void SwitchManager::GenericSwitchLongReleaseHandler(AppEvent * aEvent)
171+
{
172+
// Release moves Position from 1 (press) to 0
173+
uint8_t newPosition = 0;
174+
uint8_t previousPosition = 1;
175+
176+
if (aEvent->Type != AppEvent::kEventType_Button)
177+
{
178+
ChipLogError(NotSpecified, "Event type not supported!");
179+
return;
180+
}
181+
182+
ChipLogDetail(NotSpecified, "GenericSwitchLongRelease new position %d", newPosition);
183+
SystemLayer().ScheduleLambda([newPosition, previousPosition] {
184+
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);
185+
// LongRelease event takes newPosition as event data
186+
chip::app::Clusters::SwitchServer::Instance().OnLongRelease(GENERICSWITCH_ENDPOINT_ID, previousPosition);
187+
});
188+
}
189+
190+
void SwitchManager::GenericSwitchMultipressOngoingHandler(AppEvent * aEvent)
191+
{
192+
uint8_t newPosition = 1;
193+
194+
multiPressCount++;
195+
196+
ChipLogDetail(NotSpecified, "GenericSwitchMultiPressOngoing (%d)", multiPressCount);
197+
198+
SystemLayer().ScheduleLambda([newPosition] {
199+
chip::app::Clusters::SwitchServer::Instance().OnMultiPressOngoing(GENERICSWITCH_ENDPOINT_ID, newPosition, multiPressCount);
145200
});
146201
}
202+
203+
void SwitchManager::GenericSwitchMultipressCompleteHandler(AppEvent * aEvent)
204+
{
205+
uint8_t previousPosition = 0;
206+
207+
ChipLogProgress(NotSpecified, "GenericSwitchMultiPressComplete (%d)", multiPressCount);
208+
209+
SystemLayer().ScheduleLambda([previousPosition] {
210+
chip::app::Clusters::SwitchServer::Instance().OnMultiPressComplete(GENERICSWITCH_ENDPOINT_ID, previousPosition,
211+
multiPressCount);
212+
});
213+
214+
multiPressCount = 1;
215+
}

0 commit comments

Comments
 (0)
Please sign in to comment.