glc002-firmware/zcl_onOffCb.c

313 lines
7.1 KiB
C

/********************************************************************************************************
* @file zcl_onOffCb.c
*
* @brief This is the source file for zcl_onOffCb
*
* @author Zigbee Group
* @date 2021
*
* @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************************************/
#if (__PROJECT_TL_DIMMABLE_LIGHT__)
/**********************************************************************
* INCLUDES
*/
#include "tl_common.h"
#include "zb_api.h"
#include "zcl_include.h"
#include "sampleLight.h"
#include "sampleLightCtrl.h"
/**********************************************************************
* LOCAL VARIABLES
*/
static ev_timer_event_t *onWithTimedOffTimerEvt = NULL;
/**********************************************************************
* FUNCTIONS
*/
/*********************************************************************
* @fn sampleLight_onOffInit
*
* @brief
*
* @param None
*
* @return None
*/
void sampleLight_onOffInit(void)
{
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
sampleLight_onoff(pOnOff->onOff);
}
/*********************************************************************
* @fn sampleLight_updateOnOff
*
* @brief
*
* @param None
*
* @return None
*/
void sampleLight_updateOnOff(void)
{
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
hwLight_onOffUpdate(pOnOff->onOff);
}
/*********************************************************************
* @fn sampleLight_onoff
*
* @brief
*
* @param ZCL_CMD_ONOFF_ON / ZCL_ONOFF_STATUS_OFF
*
* @return None
*/
void sampleLight_onoff(u8 cmd)
{
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
if (cmd == ZCL_CMD_ONOFF_ON)
{
pOnOff->globalSceneControl = TRUE;
pOnOff->onOff = ZCL_ONOFF_STATUS_ON;
if (pOnOff->onTime == 0)
{
pOnOff->offWaitTime = 0;
}
}
else if (cmd == ZCL_CMD_ONOFF_OFF)
{
pOnOff->onOff = ZCL_ONOFF_STATUS_OFF;
pOnOff->onTime = 0;
}
else
{
if (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF)
{
pOnOff->globalSceneControl = TRUE;
pOnOff->onOff = ZCL_ONOFF_STATUS_ON;
if (pOnOff->onTime == 0)
{
pOnOff->offWaitTime = 0;
}
}
else
{
pOnOff->onOff = ZCL_ONOFF_STATUS_OFF;
pOnOff->onTime = 0;
}
}
light_fresh();
#ifdef ZCL_SCENE
zcl_sceneAttr_t *pScene = zcl_sceneAttrGet();
pScene->sceneValid = 0;
#endif
}
/*********************************************************************
* @fn sampleLight_OnWithTimedOffTimerCb
*
* @brief timer event to process the ON_WITH_TIMED_OFF command
*
* @param arg
*
* @return 0: timer continue on; -1: timer will be canceled
*/
static s32 sampleLight_OnWithTimedOffTimerCb(void *arg)
{
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
if ((pOnOff->onOff == ZCL_ONOFF_STATUS_ON) && pOnOff->onTime)
{
pOnOff->onTime--;
if (pOnOff->onTime <= 0)
{
pOnOff->offWaitTime = 0;
sampleLight_onoff(ZCL_CMD_ONOFF_OFF);
}
}
if ((pOnOff->onOff == ZCL_ONOFF_STATUS_OFF) && pOnOff->offWaitTime)
{
pOnOff->offWaitTime--;
if (pOnOff->offWaitTime <= 0)
{
onWithTimedOffTimerEvt = NULL;
return -1;
}
}
if (pOnOff->onTime || pOnOff->offWaitTime)
{
return 0;
}
else
{
onWithTimedOffTimerEvt = NULL;
return -1;
}
}
/*********************************************************************
* @fn sampleLight_OnWithTimedOffTimerStop
*
* @brief force to stop the OnWithTimedOff timer
*
* @param
*
* @return
*/
static void sampleLight_OnWithTimedOffTimerStop(void)
{
if (onWithTimedOffTimerEvt)
{
TL_ZB_TIMER_CANCEL(&onWithTimedOffTimerEvt);
}
}
/*********************************************************************
* @fn sampleLight_onoff_onWithTimedOffProcess
*
* @brief
*
* @param cmd
*
* @return None
*/
static void sampleLight_onoff_onWithTimedOffProcess(zcl_onoff_onWithTimeOffCmd_t *cmd)
{
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
// Discard
if (cmd->onOffCtrl.bits.acceptOnlyWhenOn && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF))
{
return;
}
if (pOnOff->offWaitTime && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF))
{
pOnOff->offWaitTime = min2(pOnOff->offWaitTime, cmd->offWaitTime);
}
else
{
pOnOff->onTime = max2(pOnOff->onTime, cmd->onTime);
pOnOff->offWaitTime = cmd->offWaitTime;
sampleLight_onoff(ZCL_CMD_ONOFF_ON);
}
if (pOnOff->onTime < 0xFFFF && pOnOff->offWaitTime < 0xFFFF)
{
if (pOnOff->onTime || pOnOff->offWaitTime)
{
sampleLight_OnWithTimedOffTimerStop();
onWithTimedOffTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_OnWithTimedOffTimerCb, NULL, ZCL_ONOFF_TIMER_INTERVAL);
}
}
}
/*********************************************************************
* @fn sampleLight_onoff_offWithEffectProcess
*
* @brief
*
* @param cmd
*
* @return None
*/
static void sampleLight_onoff_offWithEffectProcess(zcl_onoff_offWithEffectCmd_t *cmd)
{
// TODO: FIXED ME
sampleLight_onoff(ZCL_CMD_ONOFF_OFF);
}
/*********************************************************************
* @fn sampleLight_onoff_onWithRecallGlobalSceneProcess
*
* @brief
*
* @param cmd
*
* @return None
*/
static void sampleLight_onoff_onWithRecallGlobalSceneProcess(void)
{
}
/*********************************************************************
* @fn sampleLight_onOffCb
*
* @brief Handler for ZCL ONOFF command. This function will set ONOFF attribute first.
*
* @param pAddrInfo
* @param cmdId - onoff cluster command id
* @param cmdPayload
*
* @return status_t
*/
status_t sampleLight_onOffCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload)
{
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
if (pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT)
{
switch (cmdId)
{
case ZCL_CMD_ONOFF_ON:
case ZCL_CMD_ONOFF_OFF:
case ZCL_CMD_ONOFF_TOGGLE:
sampleLight_onoff(cmdId);
break;
case ZCL_CMD_OFF_WITH_EFFECT:
if (pOnOff->globalSceneControl == TRUE)
{
/* TODO: store its settings in its global scene */
pOnOff->globalSceneControl = FALSE;
}
sampleLight_onoff_offWithEffectProcess((zcl_onoff_offWithEffectCmd_t *)cmdPayload);
break;
case ZCL_CMD_ON_WITH_RECALL_GLOBAL_SCENE:
if (pOnOff->globalSceneControl == FALSE)
{
sampleLight_onoff_onWithRecallGlobalSceneProcess();
pOnOff->globalSceneControl = TRUE;
}
break;
case ZCL_CMD_ON_WITH_TIMED_OFF:
sampleLight_onoff_onWithTimedOffProcess((zcl_onoff_onWithTimeOffCmd_t *)cmdPayload);
break;
default:
break;
}
}
return ZCL_STA_SUCCESS;
}
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */