Skip to content

Commit

Permalink
qpg: align examples with QMatter SDK
Browse files Browse the repository at this point in the history
- Add light fixes (ColorFormat.cpp)
- introduce powercycle counting to trigger factory reset
- run code formatters
  • Loading branch information
q-thla committed Dec 15, 2022
1 parent 7fbf6da commit 1e0e6a3
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 40 deletions.
20 changes: 8 additions & 12 deletions examples/lighting-app/lighting-common/src/ColorFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,14 @@ RgbColor_t XYToRgb(uint8_t Level, uint16_t currentX, uint16_t currentY)
// X, Y and Z input refer to a D65/2° standard illuminant.
// sR, sG and sB (standard RGB) output range = 0 ÷ 255
// convert XYZ to RGB - CIE XYZ to sRGB
X = X / 100.0f;
Y = Y / 100.0f;
Z = Z / 100.0f;

r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f);
g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f);
b = (X * 0.0557f) - (Y * 0.2040f) + (Z * 1.0570f);
r = (X * 3.2410f) - (Y * 1.5374f) - (Z * 0.4986f);
g = -(X * 0.9692f) + (Y * 1.8760f) + (Z * 0.0416f);
b = (X * 0.0556f) - (Y * 0.2040f) + (Z * 1.0570f);

// apply gamma 2.2 correction
r = (r <= 0.0031308f ? 12.92f * r : (1.055f) * pow(r, (1.0f / 2.4f)) - 0.055f);
g = (g <= 0.0031308f ? 12.92f * g : (1.055f) * pow(g, (1.0f / 2.4f)) - 0.055f);
b = (b <= 0.0031308f ? 12.92f * b : (1.055f) * pow(b, (1.0f / 2.4f)) - 0.055f);
r = (r <= 0.00304f ? 12.92f * r : (1.055f) * pow(r, (1.0f / 2.4f)) - 0.055f);
g = (g <= 0.00304f ? 12.92f * g : (1.055f) * pow(g, (1.0f / 2.4f)) - 0.055f);
b = (b <= 0.00304f ? 12.92f * b : (1.055f) * pow(b, (1.0f / 2.4f)) - 0.055f);

// Round off
r = clamp(r, 0, 1);
Expand All @@ -139,7 +135,7 @@ RgbColor_t CTToRgb(CtColor_t ct)
// Algorithm credits to Tanner Helland: https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html

// Convert Mireds to centiKelvins. k = 1,000,000/mired
float ctCentiKelvin = 10000 / ct.ctMireds;
float ctCentiKelvin = 10000 / (float) ct.ctMireds;

// Red
if (ctCentiKelvin <= 66)
Expand Down Expand Up @@ -174,7 +170,7 @@ RgbColor_t CTToRgb(CtColor_t ct)
}
else
{
b = 138.5177312231 * log(ctCentiKelvin - 10) - 305.0447927307;
b = 138.5177312231f * log(ctCentiKelvin - 10) - 305.0447927307f;
}
}
rgb.r = (uint8_t) clamp(r, 0, 255);
Expand Down
4 changes: 2 additions & 2 deletions examples/lighting-app/qpg/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ qpg_executable("lighting_app") {
"${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerDelegate.cpp",
"${examples_plat_dir}/app/main.cpp",
"${examples_plat_dir}/ota/ota.cpp",
"${examples_plat_dir}/powercycle_counting.c",
"include/LightingManager.h",
"src/AppTask.cpp",
"src/LightingManager.cpp",
Expand Down Expand Up @@ -85,8 +86,7 @@ qpg_executable("lighting_app") {
"${examples_plat_dir}/ota",
]

defines = []

defines = [ "GP_APP_DIVERSITY_POWERCYCLECOUNTING" ]
if (chip_enable_pw_rpc) {
defines += [
"PW_RPC_ENABLED",
Expand Down
68 changes: 61 additions & 7 deletions examples/lighting-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
* limitations under the License.
*/

#if !defined(GP_APP_DIVERSITY_POWERCYCLECOUNTING)
#error This application requires powercycle counting.
#endif

#include "gpSched.h"
#include "powercycle_counting.h"
#include "qvIO.h"

#include "AppConfig.h"
#include "AppEvent.h"
#include "AppTask.h"
#include "ota.h"
#include "powercycle_counting.h"

#include <app/server/OnboardingCodesUtil.h>

Expand Down Expand Up @@ -61,13 +68,16 @@ using namespace ::chip::DeviceLayer;
#define APP_EVENT_QUEUE_SIZE 10
#define QPG_LIGHT_ENDPOINT_ID (1)

static uint8_t countdown = 0;

namespace {
TaskHandle_t sAppTaskHandle;
QueueHandle_t sAppEventQueue;

bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sHaveBLEConnections = false;
bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sHaveBLEConnections = false;
bool sIsBLEAdvertisingEnabled = false;

// 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 @@ -137,6 +147,7 @@ Identify gIdentify = {
/**********************************************************
* OffWithEffect Callbacks
*********************************************************/

void OnTriggerOffWithEffect(OnOffEffect * effect)
{
chip::app::Clusters::OnOff::OnOffEffectIdentifier effectId = effect->mEffectIdentifier;
Expand Down Expand Up @@ -259,6 +270,8 @@ CHIP_ERROR AppTask::Init()
{
CHIP_ERROR err = CHIP_NO_ERROR;

gpAppFramework_Reset_Init();

PlatformMgr().AddEventHandler(MatterEventHandler, 0);

ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);
Expand Down Expand Up @@ -331,7 +344,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent)
{
// Toggle Dimming of light between 2 fixed levels
uint8_t val = 0x0;
val = LightingMgr().GetLevel() == 0x7f ? 0x1 : 0x7f;
val = LightingMgr().GetLevel() == 0x40 ? 0xff : 0x40;
action = LightingManager::LEVEL_ACTION;

sAppTask.mSyncClusterToButtonAction = true;
Expand Down Expand Up @@ -530,7 +543,7 @@ void AppTask::ActionCompleted(LightingManager::Action_t aAction)

void AppTask::PostEvent(const AppEvent * aEvent)
{
if (sAppEventQueue != NULL)
if (sAppEventQueue != nullptr)
{
if (!xQueueSend(sAppEventQueue, aEvent, 1))
{
Expand All @@ -539,7 +552,7 @@ void AppTask::PostEvent(const AppEvent * aEvent)
}
else
{
ChipLogError(NotSpecified, "Event Queue is NULL should never happen");
ChipLogError(NotSpecified, "Event Queue is nullptr should never happen");
}
}

Expand All @@ -564,6 +577,7 @@ void AppTask::UpdateClusterState(void)

// Write the new on/off value
EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(QPG_LIGHT_ENDPOINT_ID, LightingMgr().IsTurnedOn());

if (status != EMBER_ZCL_STATUS_SUCCESS)
{
ChipLogError(NotSpecified, "ERR: updating on/off %x", status);
Expand Down Expand Up @@ -591,14 +605,19 @@ void AppTask::UpdateLEDs(void)
// Otherwise, blink the LED ON for a very short time.
if (sIsThreadProvisioned && sIsThreadEnabled)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
qvIO_LedSet(SYSTEM_STATE_LED, true);
}
else if (sHaveBLEConnections)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
}
else if (sIsBLEAdvertisingEnabled)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 50, 50);
}
else
{
// not commisioned yet
qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
}
}
Expand Down Expand Up @@ -631,7 +650,42 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t)
break;
}

case DeviceEventType::kCHIPoBLEAdvertisingChange: {
sIsBLEAdvertisingEnabled = (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started);
UpdateLEDs();
break;
}

default:
break;
}
}

static void NextCountdown(void)
{
if (countdown > 0)
{
LightingMgr().InitiateAction((countdown % 2 == 0) ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, 0, 0, 0);
countdown--;
gpSched_ScheduleEvent(1000000UL, NextCountdown);
}
else
{
ConfigurationMgr().InitiateFactoryReset();
}
}

extern "C" {
void gpAppFramework_Reset_cbTriggerResetCountCompleted(void)
{
uint8_t resetCount = gpAppFramework_Reset_GetResetCount();

ChipLogProgress(NotSpecified, "%d resets so far", resetCount);
if (resetCount == 10)
{
ChipLogProgress(NotSpecified, "Factory Reset Triggered!");
countdown = 5;
NextCountdown();
}
}
}
12 changes: 7 additions & 5 deletions examples/lighting-app/qpg/src/LightingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,24 @@
#include <lib/support/logging/CHIPLogging.h>

// initialization values for Blue in XY color space
constexpr XyColor_t kBlueXY = { 9830, 3932 };
constexpr XyColor_t kBlueXY = { 9830, 3932 };
constexpr XyColor_t kWhiteXY = { 20495, 21563 };

// initialization values for Blue in HSV color space
constexpr HsvColor_t kBlueHSV = { 240, 100, 255 };
constexpr HsvColor_t kBlueHSV = { 240, 100, 255 };
constexpr HsvColor_t kWhiteHSV = { 0, 0, 255 };

// default initialization value for the light level after start
constexpr uint8_t kDefaultLevel = 64;
constexpr uint8_t kDefaultLevel = 1;

LightingManager LightingManager::sLight;

CHIP_ERROR LightingManager::Init()
{
mState = kState_Off;
mLevel = kDefaultLevel;
mXY = kBlueXY;
mHSV = kBlueHSV;
mXY = kWhiteXY;
mHSV = kWhiteHSV;
mRGB = XYToRgb(mLevel, mXY.x, mXY.y);

return CHIP_NO_ERROR;
Expand Down
10 changes: 9 additions & 1 deletion examples/lighting-app/qpg/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,13 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &
*/
void emberAfOnOffClusterInitCallback(EndpointId endpoint)
{
// No additional init currently - startup state handled by cluster.
bool onOffValue = false;

EmberAfStatus status = OnOff::Attributes::OnOff::Get(1, &onOffValue);

if (status == EMBER_ZCL_STATUS_SUCCESS)
{
LightingMgr().InitiateAction(onOffValue ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, 0, 1,
(uint8_t *) onOffValue);
}
}
1 change: 1 addition & 0 deletions examples/lock-app/qpg/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ qpg_executable("lock_app") {
output_name = "chip-${qpg_target_ic}-lock-example.out"

sources = [
"${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerDelegate.cpp",
"${examples_plat_dir}/app/main.cpp",
"${examples_plat_dir}/ota/ota.cpp",
"src/AppTask.cpp",
Expand Down
47 changes: 36 additions & 11 deletions examples/lock-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerDelegate.h>
#include <app/clusters/general-diagnostics-server/general-diagnostics-server.h>
#include <app/server/Dnssd.h>
#include <app/server/Server.h>
#include <app/util/attribute-storage.h>
Expand All @@ -43,17 +45,17 @@

using namespace ::chip;
using namespace ::chip::app;
using namespace chip::TLV;
using namespace chip::Credentials;
using namespace chip::DeviceLayer;
using namespace ::chip::TLV;
using namespace ::chip::Credentials;
using namespace ::chip::DeviceLayer;

#include <platform/CHIPDeviceLayer.h>

#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
#define OTA_START_TRIGGER_TIMEOUT 1500

#define APP_TASK_STACK_SIZE (2 * 1024)
#define APP_TASK_STACK_SIZE (3 * 1024)
#define APP_TASK_PRIORITY 2
#define APP_EVENT_QUEUE_SIZE 10
#define QPG_LOCK_ENDPOINT_ID (1)
Expand All @@ -62,9 +64,14 @@ namespace {
TaskHandle_t sAppTaskHandle;
QueueHandle_t sAppEventQueue;

bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sHaveBLEConnections = false;
bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sHaveBLEConnections = false;
bool sIsBLEAdvertisingEnabled = false;

// 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,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(AppEvent)];

Expand Down Expand Up @@ -124,6 +131,12 @@ void AppTask::InitServer(intptr_t arg)
nativeParams.unlockCb = UnlockOpenThreadTask;
nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance();
initParams.endpointNativeParams = static_cast<void *>(&nativeParams);

// Use GenericFaultTestEventTriggerDelegate to inject faults
static GenericFaultTestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;

chip::Server::GetInstance().Init(initParams);

#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
Expand Down Expand Up @@ -469,7 +482,7 @@ void AppTask::PostLockActionRequest(int32_t aActor, BoltLockManager::Action_t aA

void AppTask::PostEvent(const AppEvent * aEvent)
{
if (sAppEventQueue != NULL)
if (sAppEventQueue != nullptr)
{
if (!xQueueSend(sAppEventQueue, aEvent, 1))
{
Expand All @@ -478,7 +491,7 @@ void AppTask::PostEvent(const AppEvent * aEvent)
}
else
{
ChipLogError(NotSpecified, "Event Queue is NULL should never happen");
ChipLogError(NotSpecified, "Event Queue is nullptr should never happen");
}
}

Expand All @@ -504,7 +517,8 @@ void AppTask::UpdateClusterState(void)

ChipLogProgress(NotSpecified, "UpdateClusterState");

EmberAfStatus status = DoorLock::Attributes::LockState::Set(DOOR_LOCK_SERVER_ENDPOINT, newValue);
EmberAfStatus status = DoorLock::Attributes::LockState::Set(QPG_LOCK_ENDPOINT_ID, newValue);

if (status != EMBER_ZCL_STATUS_SUCCESS)
{
ChipLogError(NotSpecified, "ERR: updating DoorLock %x", status);
Expand All @@ -525,14 +539,19 @@ void AppTask::UpdateLEDs(void)
// Otherwise, blink the LED ON for a very short time.
if (sIsThreadProvisioned && sIsThreadEnabled)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
qvIO_LedSet(SYSTEM_STATE_LED, true);
}
else if (sHaveBLEConnections)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
}
else if (sIsBLEAdvertisingEnabled)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 50, 50);
}
else
{
// not commisioned yet
qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
}
}
Expand Down Expand Up @@ -565,6 +584,12 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t)
break;
}

case DeviceEventType::kCHIPoBLEAdvertisingChange: {
sIsBLEAdvertisingEnabled = (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started);
UpdateLEDs();
break;
}

default:
break;
}
Expand Down
Loading

0 comments on commit 1e0e6a3

Please sign in to comment.