AppTask.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. *
  3. * Copyright (c) 2022-2023 Project CHIP Authors
  4. * All rights reserved.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "AppTask.h"
  19. #include <app-common/zap-generated/attributes/Accessors.h>
  20. #include <zephyr/kernel.h>
  21. #include <zephyr/logging/log.h>
  22. LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
  23. namespace {
  24. #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
  25. LEDWidget sContactSensorLED;
  26. #endif
  27. } // namespace
  28. AppTask AppTask::sAppTask;
  29. CHIP_ERROR AppTask::Init(void)
  30. {
  31. #if APP_USE_EXAMPLE_START_BUTTON
  32. SetExampleButtonCallbacks(ContactActionEventHandler);
  33. #endif
  34. InitCommonParts();
  35. #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
  36. sContactSensorLED.Init(GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios));
  37. sContactSensorLED.Set(ContactSensorMgr().IsContactClosed());
  38. #endif
  39. UpdateDeviceState();
  40. ContactSensorMgr().SetCallback(OnStateChanged);
  41. return CHIP_NO_ERROR;
  42. }
  43. void AppTask::OnStateChanged(ContactSensorManager::State aState)
  44. {
  45. // If the contact state was changed, update LED state and cluster state (only if button was pressed).
  46. // - turn on the contact LED if contact sensor is in closed state.
  47. // - turn off the lock LED if contact sensor is in opened state.
  48. if (ContactSensorManager::State::kContactClosed == aState)
  49. {
  50. LOG_INF("Contact state changed to CLOSED");
  51. #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
  52. sContactSensorLED.Set(true);
  53. #endif
  54. }
  55. else if (ContactSensorManager::State::kContactOpened == aState)
  56. {
  57. LOG_INF("Contact state changed to OPEN");
  58. #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
  59. sContactSensorLED.Set(false);
  60. #endif
  61. }
  62. if (sAppTask.IsSyncClusterToButtonAction())
  63. {
  64. sAppTask.UpdateClusterState();
  65. }
  66. }
  67. void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction)
  68. {
  69. AppEvent event;
  70. event.Type = AppEvent::kEventType_Contact;
  71. event.ContactEvent.Action = static_cast<uint8_t>(aAction);
  72. event.Handler = ContactActionEventHandler;
  73. sAppTask.PostEvent(&event);
  74. }
  75. void AppTask::UpdateClusterStateInternal(intptr_t arg)
  76. {
  77. uint8_t newValue = ContactSensorMgr().IsContactClosed();
  78. ChipLogProgress(NotSpecified, "StateValue::Set : %d", newValue);
  79. // write the new boolean state value
  80. EmberAfStatus status = app::Clusters::BooleanState::Attributes::StateValue::Set(1, newValue);
  81. if (status != EMBER_ZCL_STATUS_SUCCESS)
  82. {
  83. ChipLogError(NotSpecified, "ERR: updating boolean status value %x", status);
  84. }
  85. }
  86. void AppTask::ContactActionEventHandler(AppEvent * aEvent)
  87. {
  88. ContactSensorManager::Action action = ContactSensorManager::Action::kInvalid;
  89. CHIP_ERROR err = CHIP_NO_ERROR;
  90. ChipLogProgress(NotSpecified, "ContactActionEventHandler");
  91. if (aEvent->Type == AppEvent::kEventType_Contact)
  92. {
  93. action = static_cast<ContactSensorManager::Action>(aEvent->ContactEvent.Action);
  94. }
  95. else if (aEvent->Type == AppEvent::kEventType_Button)
  96. {
  97. if (ContactSensorMgr().IsContactClosed())
  98. {
  99. action = ContactSensorManager::Action::kSignalLost;
  100. }
  101. else
  102. {
  103. action = ContactSensorManager::Action::kSignalDetected;
  104. }
  105. sAppTask.SetSyncClusterToButtonAction(true);
  106. }
  107. else
  108. {
  109. err = APP_ERROR_UNHANDLED_EVENT;
  110. action = ContactSensorManager::Action::kInvalid;
  111. }
  112. if (err == CHIP_NO_ERROR)
  113. {
  114. ContactSensorMgr().InitiateAction(action);
  115. }
  116. }
  117. void AppTask::UpdateClusterState(void)
  118. {
  119. PlatformMgr().ScheduleWork(UpdateClusterStateInternal, 0);
  120. }
  121. void AppTask::UpdateDeviceState(void)
  122. {
  123. PlatformMgr().ScheduleWork(UpdateDeviceStateInternal, 0);
  124. }
  125. void AppTask::UpdateDeviceStateInternal(intptr_t arg)
  126. {
  127. bool stateValueAttrValue = 0;
  128. /* get boolean state attribute value */
  129. (void) app::Clusters::BooleanState::Attributes::StateValue::Get(1, &stateValueAttrValue);
  130. ChipLogProgress(NotSpecified, "StateValue::Get : %d", stateValueAttrValue);
  131. #if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
  132. sContactSensorLED.Set(stateValueAttrValue);
  133. #endif
  134. }