blob: 3ee4cd19d30a60a9f852629f6a85332275e963ca [file] [log] [blame]
/*
*
* Copyright (c) 2022-2023 Project CHIP Authors
* All rights reserved.
*
* 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.
*/
#include "AppTask.h"
#include <app-common/zap-generated/attributes/Accessors.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
namespace {
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
LEDWidget sContactSensorLED;
#endif
} // namespace
AppTask AppTask::sAppTask;
CHIP_ERROR AppTask::Init(void)
{
#if APP_USE_EXAMPLE_START_BUTTON
SetExampleButtonCallbacks(ContactActionEventHandler);
#endif
InitCommonParts();
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
sContactSensorLED.Init(GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios));
sContactSensorLED.Set(ContactSensorMgr().IsContactClosed());
#endif
UpdateDeviceState();
ContactSensorMgr().SetCallback(OnStateChanged);
CHIP_ERROR err = ConnectivityMgr().SetBLEDeviceName("TelinkSensor");
if (err != CHIP_NO_ERROR)
{
LOG_ERR("SetBLEDeviceName fail");
return err;
}
return CHIP_NO_ERROR;
}
void AppTask::OnStateChanged(ContactSensorManager::State aState)
{
// If the contact state was changed, update LED state and cluster state (only if button was pressed).
// - turn on the contact LED if contact sensor is in closed state.
// - turn off the lock LED if contact sensor is in opened state.
if (ContactSensorManager::State::kContactClosed == aState)
{
LOG_INF("Contact state changed to CLOSED");
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
sContactSensorLED.Set(true);
#endif
}
else if (ContactSensorManager::State::kContactOpened == aState)
{
LOG_INF("Contact state changed to OPEN");
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
sContactSensorLED.Set(false);
#endif
}
if (sAppTask.IsSyncClusterToButtonAction())
{
sAppTask.UpdateClusterState();
}
}
void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction)
{
AppEvent event;
event.Type = AppEvent::kEventType_Contact;
event.ContactEvent.Action = static_cast<uint8_t>(aAction);
event.Handler = ContactActionEventHandler;
sAppTask.PostEvent(&event);
}
void AppTask::UpdateClusterStateInternal(intptr_t arg)
{
uint8_t newValue = ContactSensorMgr().IsContactClosed();
ChipLogProgress(NotSpecified, "StateValue::Set : %d", newValue);
// write the new boolean state value
EmberAfStatus status = app::Clusters::BooleanState::Attributes::StateValue::Set(1, newValue);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
ChipLogError(NotSpecified, "ERR: updating boolean status value %x", status);
}
}
void AppTask::ContactActionEventHandler(AppEvent * aEvent)
{
ContactSensorManager::Action action = ContactSensorManager::Action::kInvalid;
CHIP_ERROR err = CHIP_NO_ERROR;
ChipLogProgress(NotSpecified, "ContactActionEventHandler");
if (aEvent->Type == AppEvent::kEventType_Contact)
{
action = static_cast<ContactSensorManager::Action>(aEvent->ContactEvent.Action);
}
else if (aEvent->Type == AppEvent::kEventType_Button)
{
if (ContactSensorMgr().IsContactClosed())
{
action = ContactSensorManager::Action::kSignalLost;
}
else
{
action = ContactSensorManager::Action::kSignalDetected;
}
sAppTask.SetSyncClusterToButtonAction(true);
}
else
{
err = APP_ERROR_UNHANDLED_EVENT;
action = ContactSensorManager::Action::kInvalid;
}
if (err == CHIP_NO_ERROR)
{
ContactSensorMgr().InitiateAction(action);
}
}
void AppTask::UpdateClusterState(void)
{
PlatformMgr().ScheduleWork(UpdateClusterStateInternal, 0);
}
void AppTask::UpdateDeviceState(void)
{
PlatformMgr().ScheduleWork(UpdateDeviceStateInternal, 0);
}
void AppTask::UpdateDeviceStateInternal(intptr_t arg)
{
bool stateValueAttrValue = 0;
/* get boolean state attribute value */
(void) app::Clusters::BooleanState::Attributes::StateValue::Get(1, &stateValueAttrValue);
ChipLogProgress(NotSpecified, "StateValue::Get : %d", stateValueAttrValue);
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
sContactSensorLED.Set(stateValueAttrValue);
#endif
}