From e4771afcb0a855a5e0d53c54a3e6415915784e6b Mon Sep 17 00:00:00 2001 From: Rehan Rasool Date: Tue, 11 Oct 2022 19:10:25 +0000 Subject: [PATCH] Pull request #184: Cherry-Pick Thermostat Updates Merge in WMN_TOOLS/matter from cherry-pick/thermostat_updates to RC_0.4.0 Squashed commit of the following: commit dc14eae3bde510ceb498bd4d59ee90f318dba306 Author: Ezra Hale Date: Thu Sep 8 14:01:13 2022 +0000 Pull request #75: updated thermostat README to remove mention of light switch Merge in WMN_TOOLS/matter from fix_thermostat_doc to RC_0.3.0 Squashed commit of the following: commit 75541a429db4164b7c09b8c165114cbd67f9372e Author: Ezra Hale Date: Thu Sep 8 08:51:26 2022 -0400 further minor cleanup on the urls etc... commit 7a90c063f2f936dfed3489060c7abb54bf6be2f5 Author: Ezra Hale Date: Thu Sep 8 08:43:56 2022 -0400 projectchip -> project-chip commit 1e30b31f1eab975c7dfd6d3b925485e8ac23f570 Author: Ezra Hale Date: Thu Sep 8 08:22:09 2022 -0400 addressed comments, fixed errors caused by brute force replace of CHIP commit 4d97ea794d56f97f950d949bf723931edf27d7b8 Author: Ezra Hale Date: Wed Sep 7 13:51:18 2022 -0400 chip -> matter commit 6b9d0f57c0489b7f213d7dd8f12b26b023f7032e Author: Ezra Hale Date: Wed Sep 7 13:28:42 2022 -0400 updated thermostat README to remove mention of light switch commit 220622601d8c58e0d9d1583edc6b472ebc91f126 Author: Shayna Kaushal Date: Wed Sep 7 15:59:53 2022 +0000 Pull request #62: Thermostat updates Merge in WMN_TOOLS/matter from thermostat_updates to RC_0.3.0 Squashed commit of the following: commit 7d27ef4020e859b35c1f43b142c82af1eaed7a60 Author: shayna Date: Tue Sep 6 16:24:44 2022 -0400 [thermo] get/set attributes done commit ae9eee59524145a062dcf950ce07996c02c631aa Author: Shayna Kaushal Date: Tue Sep 6 12:15:09 2022 -0400 [thermo] jenkins: wifi thermostat build commit 7ec590237f1c3de688953f0a408561275ea386c6 Author: Shayna Kaushal Date: Tue Sep 6 10:32:08 2022 -0400 [thermo] jenkins trial commit a6b5f390ab08c43611770d553f2b3b03985c4cbd Author: Shayna Kaushal Date: Fri Sep 2 17:26:28 2022 -0400 no changes - added comments to be removed commit 818fb2fd098b5eb12f800c76329380d9cbdb5617 Author: Shayna Kaushal Date: Fri Sep 2 11:12:28 2022 -0400 [thermo] some comments resolved, todo: read attributes commit 64a2cf609bdfa0f40dab187aaedb4a24d95f205a Author: Shayna Kaushal Date: Thu Sep 1 15:47:58 2022 -0400 [thermo] cleaned commit bb75e776644941054d06069608d370ee00f8f8f8 Author: Shayna Kaushal Date: Thu Sep 1 15:47:06 2022 -0400 [thermo] cleaned commit cec89f46cfa7011d5e8eabd6bdb09152a675a5b2 Author: Shayna Kaushal Date: Thu Sep 1 15:40:33 2022 -0400 [thermo] readme edits commit 20f1608706c0cdacefb8fbf72c62b54db0c64e64 Author: Shayna Kaushal Date: Thu Sep 1 15:23:06 2022 -0400 [thermo] added limits commit 9d012ab60ec602f809c6f1c2d8b7a8f1cfc465e7 Author: Shayna Kaushal Date: Thu Sep 1 12:56:23 2022 -0400 [thermo] cleaned - todo: add limits, docs commit 23150e76b129b9e0181965a987e6a0b62fbda651 Author: Shayna Kaushal Date: Thu Sep 1 10:16:27 2022 -0400 code added, todo: clean+docs --- examples/thermostat/efr32/README.md | 80 +++-- examples/thermostat/efr32/include/AppTask.h | 72 +++- examples/thermostat/efr32/src/AppTask.cpp | 357 +++++++++++++++++++- 3 files changed, 469 insertions(+), 40 deletions(-) diff --git a/examples/thermostat/efr32/README.md b/examples/thermostat/efr32/README.md index 5bc31b87d2d989..96ce49a0624252 100644 --- a/examples/thermostat/efr32/README.md +++ b/examples/thermostat/efr32/README.md @@ -1,20 +1,28 @@ -# CHIP EFR32 Light Switch Example +# Matter EFR32 Thermostat Example -An example showing the use of CHIP on the Silicon Labs EFR32 MG12. +An example showing the use of Matter on the Silicon Labs EFR32 MG12 and MG24.
-- [CHIP EFR32 Light Switch Example](#chip-efr32-light-switch-example) - - [Introduction](#introduction) +- Matter EFR32 Thermostat Example + - [Introduction](#intro) - [Building](#building) - - [Note](#note) + - [Linux](#linux) + - [Mac OS X](#mac-os-x) - [Flashing the Application](#flashing-the-application) - [Viewing Logging Output](#viewing-logging-output) - [Running the Complete Example](#running-the-complete-example) - [Notes](#notes) + - [On Border Router:](#on-border-router) + - [On PC(Linux):](#on-pclinux) - [Running RPC console](#running-rpc-console) - [Memory settings](#memory-settings) - [OTA Software Update](#ota-software-update) + - [Building options](#building-options) + - [Disabling logging](#disabling-logging) + - [Debug build / release build](#debug-build--release-build) + - [Disabling LCD](#disabling-lcd) + - [KVS maximum entry count](#kvs-maximum-entry-count)
@@ -22,20 +30,20 @@ An example showing the use of CHIP on the Silicon Labs EFR32 MG12. ## Introduction -The EFR32 light switch example provides a baseline demonstration of a on-off -light switch device, built using CHIP and the Silicon Labs gecko SDK. It can be -controlled by a Chip controller over Openthread network. +The EFR32 thermostat example provides a baseline demonstration of a thermostat +device, built using Matter and the Silicon Labs gecko SDK. It can be controlled +by a Matter controller over OpenThread network. The EFR32 device can be commissioned over Bluetooth Low Energy where the device -and the Chip controller will exchange security information with the Rendez-vous -procedure. Thread Network credentials are then provided to the EFR32 device -which will then join the network. +and the Matter controller will exchange security information with the +Rendez-vous procedure. Thread Network credentials are then provided to the EFR32 +device which will then join the network. The LCD on the Silabs WSTK shows a QR Code containing the needed commissioning information for the BLE connection and starting the Rendez-vous procedure. -The light switch example is intended to serve both as a means to explore the -workings of CHIP as well as a template for creating real products based on the +The thermostat example is intended to serve both as a means to explore the +workings of Matter as well as a template for creating real products based on the Silicon Labs platform. @@ -44,14 +52,15 @@ Silicon Labs platform. - Download the [Simplicity Commander](https://www.silabs.com/mcu/programming-options) - command line tool, and ensure that `commander` is your shell search path. + command line tool, and ensure that `commander` is in your shell search path. (For Mac OS X, `commander` is located inside `Commander.app/Contents/MacOS/`.) -- Download and install a suitable ARM gcc tool chain: +- Download and install a suitable ARM GCC tool chain: [GNU Arm Embedded Toolchain 9-2019-q4-major](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) -- Install some additional tools(likely already present for CHIP developers): +- Install some additional tools (likely already present for Matter + developers): #### Linux @@ -116,7 +125,7 @@ Silicon Labs platform. ./scripts/examples/gn_efr32_example.sh examples/thermostat/efr32/ out/thermostat-app BRD4161A chip_build_libshell=true -* Build the example as Sleepy End Device (SED) +* Build the example as a Sleepy End Device (SED) $ ./scripts/examples/gn_efr32_example.sh ./examples/thermostat/efr32/ ./out/thermostat-app_SED BRD4161A --sed @@ -224,7 +233,7 @@ combination with JLinkRTTClient as follows: commissioned on the same openthread network - User interface : **LCD** The LCD on Silabs WSTK shows a QR Code. This QR - Code is be scanned by the CHIP Tool app For the Rendez-vous procedure over + Code is be scanned by the Chip Tool app For the Rendez-vous procedure over BLE * On devices that do not have or support the LCD Display like the BRD4166A Thunderboard Sense 2, @@ -253,16 +262,30 @@ combination with JLinkRTTClient as follows: **Push Button 0** - - _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode - for 30 seconds. The device will then switch to a slower interval advertisement. - After 15 minutes, the advertisement stops. + - _Press and Release_ : - - _Pressed and hold for 6 s_ : Initiates the factory reset of the device. - Releasing the button within the 6-second window cancels the factory reset - procedure. **LEDs** blink in unison when the factory reset procedure is - initiated. + - Decreases temperature by 0.01C depending on current mode. -* You can provision and control the Chip device using the python controller, + - Start, or restart, BLE advertisement in fast mode. It will advertise + in this mode for 30 seconds. The device will then switch to a + slower interval advertisement. + After 15 minutes, the advertisement stops. + + - _Pressed and hold for 6.5 s_ : Initiates the factory reset of the device. + Releasing button within the 0.5-second window cancels initiation of factory + reset. + Releasing the button within the 6-second window post that cancels the + factory reset procedure. **LEDs** blink in unison when the factory reset + procedure is initiated. + + **Push Button 1** + + - _Press and Release_ : Increases temperature by 0.01C depending on current + mode. + + - _Pressed and hold for 1 s_ : Toggles the mode of the thermostat. + +* You can provision and control the Matter device using the python controller, [CHIPTool](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) standalone, Android or iOS app @@ -303,7 +326,8 @@ via 2002::2 - To use the chip-rpc console after it has been installed run: - `chip-console --device /dev/tty. -b 115200 -o //pw_log.out` + chip-console --device /dev/tty. -b 115200 -o + //pw_log.out` - Then you can simulate a button press or release using the following command where : idx = 0 or 1 for Button PB0 or PB1 action = 0 for PRESSED, 1 for @@ -313,7 +337,7 @@ via 2002::2 ## Memory settings -While most of the RAM usage in CHIP is static, allowing easier debugging and +While most of the RAM usage in Matter is static, allowing easier debugging and optimization with symbols analysis, we still need some HEAP for the crypto and OpenThread. Size of the HEAP can be modified by changing the value of the `configTOTAL_HEAP_SIZE` define inside of the FreeRTOSConfig.h file of this diff --git a/examples/thermostat/efr32/include/AppTask.h b/examples/thermostat/efr32/include/AppTask.h index 800dda99ad37ac..8ff69994575c46 100644 --- a/examples/thermostat/efr32/include/AppTask.h +++ b/examples/thermostat/efr32/include/AppTask.h @@ -93,6 +93,15 @@ class AppTask : public BaseApplication */ static void OnIdentifyStop(Identify * identify); + enum ThermoFunction_t + { + kFunction_Nothing = 0, + kFunction_AppFn = 1, + kFunction_Temp = 2, + + kFunction_Invalid + } ThermoFunction; + private: static AppTask sAppTask; @@ -113,10 +122,65 @@ class AppTask : public BaseApplication static void ButtonHandler(AppEvent * aEvent); /** - * @brief PB1 Button event processing function - * Function triggers a thermostat action sent to the CHIP task + * @brief Function called to start the mode timer * - * @param aEvent button event being processed + * @param aTimeoutMs timer duration in ms + */ + static void StartModeTimer(uint32_t aTimeoutInMs); + + /** + * @brief Function to stop the mode timer + */ + static void CancelModeTimer(); + + /** + * @brief Function called to start the app function timer + * + * @param aTimeoutMs timer duration in ms + */ + static void StartAppFnTimer(uint32_t aTimeoutInMs); + + /** + * @brief Function to stop app function timer + */ + static void CancelAppFnTimer(); + + /** + * @brief Mode Timer finished callback function + * Post an ModeHandler event + * + * @param xTimer timer that finished + */ + static void ModeTimerEventHandler(TimerHandle_t xTimer); + + /** + * @brief App Function Timer finished callback function + * Post an AppFnHandler event + * + * @param xTimer timer that finished + */ + static void AppFnTimerEventHandler(TimerHandle_t xTimer); + + /** + * @brief Mode Timer Event processing function + * Handles toggling the mode + * + * @param aEvent post event being processed + */ + static void ModeHandler(AppEvent * aEvent); + + /** + * @brief App Function Timer Event processing function + * Calls factory reset handler from BaseApplication.cpp + * + * @param aEvent post event being processed + */ + static void AppFnHandler(AppEvent * aEvent); + + /** + * @brief Handles temperature changes depending on timer status + * + * @param aEvent post event being processed */ - static void ThermostatActionEventHandler(AppEvent * aEvent); + static void TemperatureHandler(AppEvent * aEvent); }; diff --git a/examples/thermostat/efr32/src/AppTask.cpp b/examples/thermostat/efr32/src/AppTask.cpp index 2b518669162649..d67a95a2afb4e0 100644 --- a/examples/thermostat/efr32/src/AppTask.cpp +++ b/examples/thermostat/efr32/src/AppTask.cpp @@ -39,7 +39,13 @@ #include #include +#include +#include #include +#include +#include +#include +#include #include #include #include @@ -50,6 +56,7 @@ #include #include + /********************************************************** * Defines and Constants *********************************************************/ @@ -57,12 +64,44 @@ #define APP_FUNCTION_BUTTON &sl_button_btn0 #define APP_THERMOSTAT &sl_button_btn1 +#define HEATING_MODE 1 +#define COOLING_MODE 0 + +#define MODE_TIMER 1000 +#define APP_FN_TIMER 500 + +#define MIN_HEATINGSETPOINT_LIMIT 700 +#define MAX_HEATINGSETPOINT_LIMIT 3000 +#define MIN_COOLINGSETPOINT_LIMIT 1600 +#define MAX_COOLINGSETPOINT_LIMIT 3200 + using namespace chip; using namespace ::chip::DeviceLayer; + /********************************************************** * Variable declarations *********************************************************/ + +TimerHandle_t sModeTimer; +TimerHandle_t sAppFnTimer; + +bool mModeTimerActive; +bool mAppFnTimerActive; + +bool startModeTimerVar; +bool startAppFnTimerVar; + +int thermostat_mode = HEATING_MODE; + +int16_t heatingSetpoint = 0; +int16_t coolingSetpoint = 0; + +AppTask::ThermoFunction_t btn1State; +AppTask::ThermoFunction_t btn0State; + +AppEvent reset_button_event = {}; + namespace { EmberAfIdentifyEffectIdentifier sIdentifyEffect = EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT; @@ -143,6 +182,30 @@ CHIP_ERROR AppTask::Init() { CHIP_ERROR err = CHIP_NO_ERROR; + sModeTimer = xTimerCreate("ThermModeTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = app task obj context + ModeTimerEventHandler // timer callback handler + ); + if (sModeTimer == NULL) + { + EFR32_LOG("Creation of sModeTimer failed."); + appError(APP_ERROR_CREATE_TIMER_FAILED); + } + + sAppFnTimer = xTimerCreate("ThermFnTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = app task obj context + AppFnTimerEventHandler // timer callback handler + ); + if (sAppFnTimer == NULL) + { + EFR32_LOG("Creation of aAppFnTimer failed."); + appError(APP_ERROR_CREATE_TIMER_FAILED); + } + #ifdef DISPLAY_ENABLED GetLCD().Init((uint8_t *) "Thermostat-App"); #endif @@ -186,6 +249,31 @@ void AppTask::AppTaskMain(void * pvParameter) { sAppTask.DispatchEvent(&event); eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + + if(startModeTimerVar == true) + { + StartModeTimer(MODE_TIMER); + startModeTimerVar = false; + } + if(startAppFnTimerVar == true) + { + StartAppFnTimer(APP_FN_TIMER); + startAppFnTimerVar = false; + } + if ((mModeTimerActive == true) && (btn1State == kFunction_Temp)) + { + CancelModeTimer(); + TemperatureHandler(&event); + startModeTimerVar = false; + btn1State = kFunction_Nothing; + } + if ((mAppFnTimerActive == true) && (btn0State == kFunction_Temp)) + { + CancelAppFnTimer(); + TemperatureHandler(&event); + startAppFnTimerVar = false; + btn0State = kFunction_Nothing; + } } } } @@ -208,15 +296,224 @@ void AppTask::OnIdentifyStop(Identify * identify) #endif } -void AppTask::ThermostatActionEventHandler(AppEvent * aEvent) + +void AppTask::CancelModeTimer() +{ + if (xTimerStop(sModeTimer, 0) == pdFAIL) + { + EFR32_LOG("thermostat mode timer stop() failed"); + appError(APP_ERROR_STOP_TIMER_FAILED); + } + mModeTimerActive = false; +} + +void AppTask::StartModeTimer(uint32_t aTimeoutInMs) { - if (aEvent->Type == AppEvent::kEventType_Button) + if (xTimerIsTimerActive(sModeTimer)) + { + EFR32_LOG("mode timer already started!"); + CancelModeTimer(); + } + + if (xTimerChangePeriod(sModeTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) { - EFR32_LOG("App Button was pressed!"); - // TODO: Implement button functionnality + EFR32_LOG("mode timer start() failed"); + appError(APP_ERROR_START_TIMER_FAILED); } + mModeTimerActive = true; } + +void AppTask::CancelAppFnTimer() +{ + if (xTimerStop(sAppFnTimer, 0) == pdFAIL) + { + EFR32_LOG("thermostat AppFn timer stop() failed"); + appError(APP_ERROR_STOP_TIMER_FAILED); + } + mAppFnTimerActive = false; +} + +void AppTask::StartAppFnTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sAppFnTimer)) + { + EFR32_LOG("thermostat AppFn timer already started!"); + CancelAppFnTimer(); + } + if (xTimerChangePeriod(sAppFnTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + EFR32_LOG("thermostat AppFn timer start() failed"); + appError(APP_ERROR_START_TIMER_FAILED); + } + mAppFnTimerActive = true; +} + + +void AppTask::ModeTimerEventHandler(TimerHandle_t xTimer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = (void *) xTimer; + event.Handler = ModeHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::AppFnTimerEventHandler(TimerHandle_t xTimer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = (void *) xTimer; + event.Handler = AppFnHandler; + sAppTask.PostEvent(&event); +} + + +void AppTask::TemperatureHandler(AppEvent * aEvent) +{ + if (btn1State == kFunction_Temp) + { + CancelModeTimer(); + + chip::EndpointId endpointId = 1; + + if (thermostat_mode == HEATING_MODE) + { + int16_t maxHeatingSetpointLimit = MAX_HEATINGSETPOINT_LIMIT; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::Get(endpointId, &heatingSetpoint); + chip::app::Clusters::Thermostat::Attributes::AbsMaxHeatSetpointLimit::Get(endpointId, &maxHeatingSetpointLimit); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + + if (heatingSetpoint < maxHeatingSetpointLimit) + { + heatingSetpoint += 1; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::Set(endpointId, heatingSetpoint); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + } + else + { + EFR32_LOG("No change: Maximum temperature limit reached.") + } + } + else + { + int16_t maxCoolingSetpointLimit = MAX_COOLINGSETPOINT_LIMIT; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::Get(endpointId, &coolingSetpoint); + chip::app::Clusters::Thermostat::Attributes::AbsMaxCoolSetpointLimit::Get(endpointId, &maxCoolingSetpointLimit); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + + if (coolingSetpoint < maxCoolingSetpointLimit) + { + coolingSetpoint += 1; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::Set(endpointId, coolingSetpoint); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + } + else + { + EFR32_LOG("No change: Maximum temperature limit reached.") + } + } + btn1State = kFunction_Nothing; + EFR32_LOG("Current temperature set to Heating: %d, Cooling: %d, with Mode: %d", heatingSetpoint, coolingSetpoint, thermostat_mode); + } + else if (btn0State == kFunction_Temp) + { + CancelAppFnTimer(); + + chip::EndpointId endpointId = 1; + + if (thermostat_mode == HEATING_MODE) + { + int16_t minHeatingSetpointLimit = MIN_HEATINGSETPOINT_LIMIT; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::Get(endpointId, &heatingSetpoint); + chip::app::Clusters::Thermostat::Attributes::AbsMinHeatSetpointLimit::Get(endpointId, &minHeatingSetpointLimit); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + + if (heatingSetpoint > minHeatingSetpointLimit) + { + heatingSetpoint -= 1; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::Set(endpointId, heatingSetpoint); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + } + else + { + EFR32_LOG("No change: Minimum temperature limit reached.") + } + } + else + { + int16_t minCoolingSetpointLimit = MIN_COOLINGSETPOINT_LIMIT; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::Get(endpointId, &coolingSetpoint); + chip::app::Clusters::Thermostat::Attributes::AbsMinCoolSetpointLimit::Get(endpointId, &minCoolingSetpointLimit); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + + if (coolingSetpoint > minCoolingSetpointLimit) + { + coolingSetpoint -= 1; + + chip::DeviceLayer::PlatformMgr().LockChipStack(); + chip::app::Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::Set(endpointId, coolingSetpoint); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + } + else + { + EFR32_LOG("No change: Minimum temperature limit reached.") + } + } + btn0State = kFunction_Nothing; + EFR32_LOG("Current temperature set to Heating: %d, Cooling: %d, with Mode: %d", heatingSetpoint, coolingSetpoint, thermostat_mode); + } +} + + +void AppTask::ModeHandler(AppEvent * aEvent) +{ + if (aEvent->Type != AppEvent::kEventType_Timer) + { + return; + } + + if (thermostat_mode == HEATING_MODE) + { + thermostat_mode = COOLING_MODE; + } + else + { + thermostat_mode = HEATING_MODE; + } + EFR32_LOG("Thermostat Mode set to: %d, with current temperature Heating: %d, Cooling: %d", thermostat_mode, heatingSetpoint, coolingSetpoint); + btn1State = kFunction_Nothing; + CancelModeTimer(); +} + + +void AppTask::AppFnHandler(AppEvent * aEvent) +{ + if (aEvent->Type != AppEvent::kEventType_Timer) + { + return; + } + EFR32_LOG("Initiating Factory Reset. Release button within %ums to stop.", APP_FN_TIMER); + reset_button_event.Handler = BaseApplication::ButtonHandler; + sAppTask.PostEvent(&reset_button_event); + btn0State = kFunction_Nothing; +} + + void AppTask::ButtonEventHandler(const sl_button_t * buttonHandle, uint8_t btnAction) { if (buttonHandle == NULL) @@ -228,14 +525,58 @@ void AppTask::ButtonEventHandler(const sl_button_t * buttonHandle, uint8_t btnAc button_event.Type = AppEvent::kEventType_Button; button_event.ButtonEvent.Action = btnAction; - if (buttonHandle == APP_THERMOSTAT && btnAction == SL_SIMPLE_BUTTON_PRESSED) + if (buttonHandle == APP_THERMOSTAT) { - button_event.Handler = ThermostatActionEventHandler; + if (btnAction == SL_SIMPLE_BUTTON_PRESSED) + { + btn1State = kFunction_AppFn; + startModeTimerVar = true; + button_event.Handler = ModeHandler; + } + else + { + if (mModeTimerActive == true) + { + btn1State = kFunction_Temp; + } + else + { + btn1State = kFunction_Nothing; + } + startModeTimerVar = false; + button_event.Handler = TemperatureHandler; + } sAppTask.PostEvent(&button_event); } + else if (buttonHandle == APP_FUNCTION_BUTTON) { - button_event.Handler = BaseApplication::ButtonHandler; + if (btnAction) + { + reset_button_event.Type = AppEvent::kEventType_Button; + reset_button_event.ButtonEvent.Action = btnAction; + + btn0State = kFunction_AppFn; + startAppFnTimerVar = true; + button_event.Handler = AppFnHandler; + reset_button_event.Handler = AppFnHandler; + } + else + { + reset_button_event.ButtonEvent.Action = btnAction; + + if (mAppFnTimerActive == true) + { + btn0State = kFunction_Temp; + } + else + { + btn0State = kFunction_Nothing; + } + startAppFnTimerVar = false; + button_event.Handler = TemperatureHandler; + } sAppTask.PostEvent(&button_event); + sAppTask.PostEvent(&reset_button_event); } -} +} \ No newline at end of file