glc002-firmware/zcl_onOffCb.c

313 lines
7.1 KiB
C
Raw Normal View History

2022-04-01 16:59:22 +00:00
/********************************************************************************************************
* @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();
2022-04-01 17:14:59 +00:00
if (cmd == ZCL_CMD_ONOFF_ON)
{
2022-04-01 16:59:22 +00:00
pOnOff->globalSceneControl = TRUE;
pOnOff->onOff = ZCL_ONOFF_STATUS_ON;
2022-04-01 17:14:59 +00:00
if (pOnOff->onTime == 0)
{
2022-04-01 16:59:22 +00:00
pOnOff->offWaitTime = 0;
}
2022-04-01 17:14:59 +00:00
}
else if (cmd == ZCL_CMD_ONOFF_OFF)
{
2022-04-01 16:59:22 +00:00
pOnOff->onOff = ZCL_ONOFF_STATUS_OFF;
pOnOff->onTime = 0;
2022-04-01 17:14:59 +00:00
}
else
{
if (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF)
{
2022-04-01 16:59:22 +00:00
pOnOff->globalSceneControl = TRUE;
pOnOff->onOff = ZCL_ONOFF_STATUS_ON;
2022-04-01 17:14:59 +00:00
if (pOnOff->onTime == 0)
{
2022-04-01 16:59:22 +00:00
pOnOff->offWaitTime = 0;
}
2022-04-01 17:14:59 +00:00
}
else
{
2022-04-01 16:59:22 +00:00
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();
2022-04-01 17:14:59 +00:00
if ((pOnOff->onOff == ZCL_ONOFF_STATUS_ON) && pOnOff->onTime)
{
2022-04-01 16:59:22 +00:00
pOnOff->onTime--;
2022-04-01 17:14:59 +00:00
if (pOnOff->onTime <= 0)
{
2022-04-01 16:59:22 +00:00
pOnOff->offWaitTime = 0;
sampleLight_onoff(ZCL_CMD_ONOFF_OFF);
}
}
2022-04-01 17:14:59 +00:00
if ((pOnOff->onOff == ZCL_ONOFF_STATUS_OFF) && pOnOff->offWaitTime)
{
2022-04-01 16:59:22 +00:00
pOnOff->offWaitTime--;
2022-04-01 17:14:59 +00:00
if (pOnOff->offWaitTime <= 0)
{
2022-04-01 16:59:22 +00:00
onWithTimedOffTimerEvt = NULL;
return -1;
}
}
2022-04-01 17:14:59 +00:00
if (pOnOff->onTime || pOnOff->offWaitTime)
{
2022-04-01 16:59:22 +00:00
return 0;
2022-04-01 17:14:59 +00:00
}
else
{
2022-04-01 16:59:22 +00:00
onWithTimedOffTimerEvt = NULL;
return -1;
}
}
/*********************************************************************
* @fn sampleLight_OnWithTimedOffTimerStop
*
* @brief force to stop the OnWithTimedOff timer
*
* @param
*
* @return
*/
static void sampleLight_OnWithTimedOffTimerStop(void)
{
2022-04-01 17:14:59 +00:00
if (onWithTimedOffTimerEvt)
{
2022-04-01 16:59:22 +00:00
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();
2022-04-07 17:22:16 +00:00
// Discard
2022-04-01 17:14:59 +00:00
if (cmd->onOffCtrl.bits.acceptOnlyWhenOn && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF))
{
2022-04-01 16:59:22 +00:00
return;
}
2022-04-01 17:14:59 +00:00
if (pOnOff->offWaitTime && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF))
{
2022-04-01 16:59:22 +00:00
pOnOff->offWaitTime = min2(pOnOff->offWaitTime, cmd->offWaitTime);
2022-04-01 17:14:59 +00:00
}
else
{
2022-04-01 16:59:22 +00:00
pOnOff->onTime = max2(pOnOff->onTime, cmd->onTime);
pOnOff->offWaitTime = cmd->offWaitTime;
sampleLight_onoff(ZCL_CMD_ONOFF_ON);
}
2022-04-07 17:22:16 +00:00
if (pOnOff->onTime < 0xFFFF && pOnOff->offWaitTime < 0xFFFF)
2022-04-01 17:14:59 +00:00
{
if (pOnOff->onTime || pOnOff->offWaitTime)
{
2022-04-01 16:59:22 +00:00
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)
{
2022-04-01 17:14:59 +00:00
// TODO: FIXED ME
2022-04-01 16:59:22 +00:00
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();
2022-04-01 17:14:59 +00:00
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;
2022-04-01 16:59:22 +00:00
}
}
return ZCL_STA_SUCCESS;
}
2022-04-01 17:14:59 +00:00
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */