3 * Copyright (c) 2021 Project CHIP Authors
4 * Copyright (c) 2019 Google LLC.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 #include "LightingManager.h"
25 #include "app_config.h"
27 LightingManager LightingManager::sLight;
29 TimerHandle_t sLightTimer; // FreeRTOS app sw timer.
31 int LightingManager::Init()
33 int err = CHIP_NO_ERROR;
35 // Create FreeRTOS sw timer for light timer.
37 sLightTimer = xTimerCreate("LightTmr", // Just a text name, not used by the RTOS kernel
38 1, // == default timer period (mS)
39 false, // no timer reload (==one-shot)
40 (void *) this, // init timer id = light obj context
41 TimerEventHandler // timer callback handler
44 if (sLightTimer == NULL)
46 K32W_LOG("light timer create failed");
50 mState = kState_TurnOffCompleted;
51 mAutoTurnOnTimerArmed = false;
53 mAutoTurnOnDuration = 0;
58 void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB)
60 mActionInitiated_CB = aActionInitiated_CB;
61 mActionCompleted_CB = aActionCompleted_CB;
64 bool LightingManager::IsActionInProgress()
66 return (mState == kState_TurnOnInitiated || mState == kState_TurnOffInitiated) ? true : false;
69 bool LightingManager::IsTurnedOff()
71 return (mState == kState_TurnOffCompleted) ? true : false;
74 void LightingManager::EnableAutoTurnOn(bool aOn)
79 void LightingManager::SetAutoTurnOnDuration(uint32_t aDurationInSecs)
81 mAutoTurnOnDuration = aDurationInSecs;
84 bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction)
86 bool action_initiated = false;
89 // Initiate ON/OFF Action only when the previous one is complete.
90 if (mState == kState_TurnOnCompleted && aAction == TURNOFF_ACTION)
92 action_initiated = true;
94 new_state = kState_TurnOffInitiated;
96 else if (mState == kState_TurnOffCompleted && aAction == TURNON_ACTION)
98 action_initiated = true;
100 new_state = kState_TurnOnInitiated;
103 if (action_initiated)
105 if (mAutoTurnOnTimerArmed && new_state == kState_TurnOnInitiated)
107 // If auto turnon timer has been armed and someone initiates turn on the ligth,
108 // cancel the timer and continue as normal.
109 mAutoTurnOnTimerArmed = false;
114 StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS);
116 // Since the timer started successfully, update the state and trigger callback
119 if (mActionInitiated_CB)
121 mActionInitiated_CB(aAction, aActor);
125 return action_initiated;
128 void LightingManager::StartTimer(uint32_t aTimeoutMs)
130 if (xTimerIsTimerActive(sLightTimer))
132 K32W_LOG("light timer already started!");
137 // timer is not active, change its period to required value.
138 // This also causes the timer to start. FreeRTOS- Block for a maximum of
139 // 100 ticks if the change period command cannot immediately be sent to the
140 // timer command queue.
141 if (xTimerChangePeriod(sLightTimer, aTimeoutMs / portTICK_PERIOD_MS, 100) != pdPASS)
143 K32W_LOG("light timer start() failed");
148 void LightingManager::CancelTimer(void)
150 if (xTimerStop(sLightTimer, 0) == pdFAIL)
152 K32W_LOG("light timer stop() failed");
157 void LightingManager::TimerEventHandler(TimerHandle_t xTimer)
159 // Get light obj context from timer id.
160 LightingManager * light = static_cast<LightingManager *>(pvTimerGetTimerID(xTimer));
162 // The timer event handler will be called in the context of the timer task
163 // once sLightTimer expires. Post an event to apptask queue with the actual handler
164 // so that the event can be handled in the context of the apptask.
166 event.Type = AppEvent::kEventType_Timer;
167 event.TimerEvent.Context = light;
169 if (light->mAutoTurnOnTimerArmed)
171 event.Handler = AutoReTurnOnTimerEventHandler;
172 GetAppTask().PostEvent(&event);
176 event.Handler = ActuatorMovementTimerEventHandler;
177 GetAppTask().PostEvent(&event);
181 void LightingManager::AutoReTurnOnTimerEventHandler(AppEvent * aEvent)
183 LightingManager * light = static_cast<LightingManager *>(aEvent->TimerEvent.Context);
186 // Make sure auto light timer is still armed.
187 if (!light->mAutoTurnOnTimerArmed)
192 light->mAutoTurnOnTimerArmed = false;
194 K32W_LOG("Auto Turn On has been triggered!");
196 light->InitiateAction(actor, TURNON_ACTION);
199 void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent)
201 Action_t actionCompleted = INVALID_ACTION;
203 LightingManager * light = static_cast<LightingManager *>(aEvent->TimerEvent.Context);
205 if (light->mState == kState_TurnOnInitiated)
207 light->mState = kState_TurnOnCompleted;
208 actionCompleted = TURNON_ACTION;
210 else if (light->mState == kState_TurnOffInitiated)
212 light->mState = kState_TurnOffCompleted;
213 actionCompleted = TURNOFF_ACTION;
216 if (actionCompleted != INVALID_ACTION)
218 if (light->mActionCompleted_CB)
220 light->mActionCompleted_CB(actionCompleted);
223 if (light->mAutoTurnOn && actionCompleted == TURNOFF_ACTION)
225 // Start the timer for auto turn on
226 light->StartTimer(light->mAutoTurnOnDuration * 1000);
228 light->mAutoTurnOnTimerArmed = true;
230 K32W_LOG("Auto Turn On enabled. Will be triggered in %u seconds", light->mAutoTurnOnDuration);