-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Chef] Add 2 Generic Switch devices and RPC Actions for Testing (#33255)
* Add RPC Event Service draft * Commit the draft to add_event in post attr change Commit the draft to add_event in post attribute change callback * Add PreAttributeChangeCallback * Support write events as string through RPC * Revert Chef stubs.cpp to not using AttributeDelegate * RPC can call delegate to SwitchManager/EventHandler * Rmove ununsed RPC command delegate * Rename RPC Event to RPC Actions * Simplify RPC code by setting transparent subscribe * Chef RPC Actions Draft done. TBD: Debug Optimize Error code Confirm timer is ms * Fix timer bug, remove unused comments * Add Latching Switch taglist to Descriptor Cluster * Cross platform built on ESP32/nRFConnect done And also enable the ApplicationInit * Update Generic Switch 1 * Add 2nd Generic Switch * Add chef/common/chef-descriptor-namespace.h * Remote printf * Remove TODO * Remove unused comments * Restyled by whitespace * Restyled by clang-format * Fix according to PR comments #33255 * Restyled by clang-format * Fix compilation issues * Remove unused debugging codes --------- Co-authored-by: Restyled.io <[email protected]>
- Loading branch information
Showing
29 changed files
with
5,872 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* | ||
* Copyright (c) 2024 Project CHIP Authors | ||
* | ||
* 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
// Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces | ||
constexpr const uint8_t kNamespaceCommonLevel = 5; | ||
// Common Number Namespace: 5, tag 0 (Low) | ||
constexpr const uint8_t kTagCommonLow = 0; | ||
// Common Number Namespace: 5, tag 1 (Medium) | ||
constexpr const uint8_t kTagCommonMedium = 1; | ||
// Common Number Namespace: 5, tag 2 (High) | ||
constexpr const uint8_t kTagCommonHigh = 2; | ||
|
||
constexpr const uint8_t kNamespaceCommonNumber = 7; | ||
// Common Number Namespace: 7, tag 0 (Zero) | ||
constexpr const uint8_t kTagCommonZero = 0; | ||
// Common Number Namespace: 7, tag 1 (One) | ||
constexpr const uint8_t kTagCommonOne = 1; | ||
// Common Number Namespace: 7, tag 2 (Two) | ||
constexpr const uint8_t kTagCommonTwo = 2; | ||
|
||
constexpr const uint8_t kNamespacePosition = 8; | ||
// Common Position Namespace: 8, tag: 0 (Left) | ||
constexpr const uint8_t kTagPositionLeft = 0; | ||
// Common Position Namespace: 8, tag: 1 (Right) | ||
constexpr const uint8_t kTagPositionRight = 1; | ||
// Common Position Namespace: 8, tag: 2 (Top) | ||
constexpr const uint8_t kTagPositionTop = 2; | ||
// Common Position Namespace: 8, tag: 3 (Bottom) | ||
constexpr const uint8_t kTagPositionBottom = 3; | ||
// Common Position Namespace: 8, tag: 4 (Middle) | ||
constexpr const uint8_t kTagPositionMiddle = 4; | ||
// Common Position Namespace: 8, tag: 5 (Row) | ||
constexpr const uint8_t kTagPositionRow = 5; | ||
// Common Position Namespace: 8, tag: 6 (Column) | ||
constexpr const uint8_t kTagPositionColumn = 6; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* | ||
* Copyright (c) 2024 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 "chef-rpc-actions-worker.h" | ||
#include <app-common/zap-generated/attributes/Accessors.h> | ||
#include <app-common/zap-generated/callback.h> | ||
#include <app/data-model/Nullable.h> | ||
#include <app/util/config.h> | ||
#include <lib/core/DataModelTypes.h> | ||
#include <map> | ||
#include <platform/CHIPDeviceLayer.h> | ||
|
||
using chip::app::DataModel::Nullable; | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
using namespace chip::app::Clusters; | ||
using namespace chip::rpc; | ||
|
||
static std::map<ClusterId, ActionsDelegate *> gActionsDelegateMap{}; | ||
|
||
ActionsDelegate * RpcFindActionsDelegate(ClusterId clusterId) | ||
{ | ||
if (gActionsDelegateMap.find(clusterId) != gActionsDelegateMap.end()) | ||
{ | ||
return gActionsDelegateMap[clusterId]; | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
static void RpcActionsTaskCallback(System::Layer * systemLayer, void * data) | ||
{ | ||
ChefRpcActionsWorker * worker = (ChefRpcActionsWorker *) data; | ||
|
||
worker->ProcessActionQueue(); | ||
} | ||
|
||
bool ChefRpcActionsCallback(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, uint32_t actionId, | ||
std::vector<uint32_t> args) | ||
{ | ||
ActionTask task(endpointId, clusterId, static_cast<ActionType>(type), delayMs, actionId, args); | ||
|
||
return ChefRpcActionsWorker::Instance().EnqueueAction(task); | ||
} | ||
|
||
bool ChefRpcActionsWorker::EnqueueAction(ActionTask task) | ||
{ | ||
bool kickTimer = false; | ||
|
||
if (queue.empty()) | ||
{ | ||
kickTimer = true; // kick timer when the first task is adding to the queue | ||
} | ||
|
||
queue.push(task); | ||
|
||
if (kickTimer) | ||
{ | ||
(void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(task.delayMs), RpcActionsTaskCallback, this); | ||
} | ||
return true; | ||
} | ||
|
||
void ChefRpcActionsWorker::ProcessActionQueue() | ||
{ | ||
// Dequeue the first item | ||
ActionTask task = queue.front(); | ||
queue.pop(); | ||
|
||
ActionsDelegate * delegate = RpcFindActionsDelegate(task.clusterId); | ||
if (nullptr == delegate) | ||
{ | ||
ChipLogError(NotSpecified, | ||
"Cannot run action due to not finding delegate: endpointId=%d, clusterId=%04lx, attributeId=%04lx", | ||
task.endpointId, static_cast<unsigned long>(task.clusterId), static_cast<unsigned long>(task.actionId)); | ||
return; | ||
} | ||
|
||
ActionType type = static_cast<ActionType>(task.type); | ||
|
||
switch (type) | ||
{ | ||
case ActionType::WRITE_ATTRIBUTE: { | ||
ChipLogProgress(NotSpecified, "Writing Attribute: endpointId=%d, clusterId=%04lx, attributeId=%04lx, args.size=%lu", | ||
task.endpointId, static_cast<unsigned long>(task.clusterId), static_cast<unsigned long>(task.actionId), | ||
static_cast<unsigned long>(task.args.size())); | ||
delegate->AttributeWriteHandler(task.endpointId, static_cast<chip::AttributeId>(task.actionId), task.args); | ||
} | ||
break; | ||
case ActionType::RUN_COMMAND: { | ||
ChipLogProgress(NotSpecified, "Running Command: endpointId=%d, clusterId=%04lx, commandId=%04lx, args.size=%lu", | ||
task.endpointId, static_cast<unsigned long>(task.clusterId), static_cast<unsigned long>(task.actionId), | ||
static_cast<unsigned long>(task.args.size())); | ||
delegate->CommandHandler(task.endpointId, static_cast<chip::CommandId>(task.actionId), task.args); | ||
} | ||
break; | ||
case ActionType::EMIT_EVENT: { | ||
ChipLogProgress(NotSpecified, "Emitting Event: endpointId=%d, clusterId=%04lx, eventIdId=%04lx, args.size=%lu", | ||
task.endpointId, static_cast<unsigned long>(task.clusterId), static_cast<unsigned long>(task.actionId), | ||
static_cast<unsigned long>(task.args.size())); | ||
delegate->EventHandler(task.endpointId, static_cast<chip::EventId>(task.actionId), task.args); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
if (queue.empty()) | ||
{ | ||
// Return due to no more actions in queue | ||
return; | ||
} | ||
|
||
// Run next action | ||
task = queue.front(); | ||
ChipLogProgress(NotSpecified, "StartTimer: endpointId=%d, clusterId=%04lx, eventIdId=%04lx, task.delyMs=%lu", task.endpointId, | ||
static_cast<unsigned long>(task.clusterId), static_cast<unsigned long>(task.actionId), | ||
static_cast<unsigned long>(task.delayMs)); | ||
(void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(task.delayMs), RpcActionsTaskCallback, this); | ||
} | ||
|
||
void ChefRpcActionsWorker::RegisterRpcActionsDelegate(ClusterId clusterId, ActionsDelegate * delegate) | ||
{ | ||
// Register by cluster | ||
if (nullptr == RpcFindActionsDelegate(clusterId)) | ||
{ | ||
gActionsDelegateMap[clusterId] = delegate; | ||
return; | ||
} | ||
} | ||
|
||
ChefRpcActionsWorker::ChefRpcActionsWorker() | ||
{ | ||
chip::rpc::SubscribeActions(ChefRpcActionsCallback); | ||
} | ||
|
||
static ChefRpcActionsWorker instance; | ||
|
||
ChefRpcActionsWorker & ChefRpcActionsWorker::Instance() | ||
{ | ||
return instance; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* | ||
* Copyright (c) 2024 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <app/clusters/mode-base-server/mode-base-server.h> | ||
#include <app/util/config.h> | ||
#include <cstring> | ||
#include <queue> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "Rpc.h" | ||
|
||
namespace chip { | ||
namespace app { | ||
|
||
class ActionsDelegate | ||
{ | ||
public: | ||
ActionsDelegate(ClusterId clusterId) : mClusterId(clusterId){}; | ||
|
||
virtual ~ActionsDelegate() = default; | ||
|
||
virtual void AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector<uint32_t> args) = 0; | ||
virtual void CommandHandler(chip::EndpointId endpointId, chip::CommandId commandId, std::vector<uint32_t> args) = 0; | ||
virtual void EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector<uint32_t> args) = 0; | ||
|
||
protected: | ||
ClusterId mClusterId; | ||
}; | ||
|
||
struct ActionTask | ||
{ | ||
chip::EndpointId endpointId; | ||
chip::ClusterId clusterId; | ||
chip::rpc::ActionType type; // Aligned with Storage buf | ||
uint32_t delayMs; | ||
uint32_t actionId; | ||
std::vector<uint32_t> args; | ||
ActionTask(chip::EndpointId endpoint, chip::ClusterId cluster, chip::rpc::ActionType actionType, uint32_t delay, uint32_t id, | ||
std::vector<uint32_t> arg) : | ||
endpointId(endpoint), | ||
clusterId(cluster), type(actionType), delayMs(delay), actionId(id), args(arg){}; | ||
~ActionTask(){}; | ||
}; | ||
|
||
class ChefRpcActionsWorker | ||
{ | ||
public: | ||
static ChefRpcActionsWorker & Instance(); | ||
|
||
ChefRpcActionsWorker(); | ||
|
||
bool EnqueueAction(ActionTask task); | ||
void ProcessActionQueue(); | ||
void RegisterRpcActionsDelegate(ClusterId clusterId, ActionsDelegate * delegate); | ||
|
||
private: | ||
std::queue<ActionTask> queue; | ||
}; | ||
|
||
} // namespace app | ||
} // namespace chip |
82 changes: 82 additions & 0 deletions
82
examples/chef/common/clusters/switch/SwitchEventHandler.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 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 <app-common/zap-generated/attributes/Accessors.h> | ||
#ifdef MATTER_DM_PLUGIN_SWITCH_SERVER | ||
#include <app/clusters/switch-server/switch-server.h> | ||
#include <app/server/Server.h> | ||
#include <app/util/att-storage.h> | ||
#include <platform/PlatformManager.h> | ||
|
||
#include "SwitchEventHandler.h" | ||
|
||
using namespace chip; | ||
using namespace chip::app; | ||
using namespace chip::app::Clusters; | ||
using namespace chip::app::Clusters::Switch; | ||
using namespace chip::DeviceLayer; | ||
|
||
void SwitchEventHandler::OnSwitchLatched(EndpointId endpointId, uint8_t newPosition) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); | ||
|
||
Clusters::SwitchServer::Instance().OnSwitchLatch(endpointId, newPosition); | ||
} | ||
|
||
void SwitchEventHandler::OnInitialPress(EndpointId endpointId, uint8_t newPosition) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); | ||
|
||
Clusters::SwitchServer::Instance().OnInitialPress(endpointId, newPosition); | ||
} | ||
|
||
void SwitchEventHandler::OnLongPress(EndpointId endpointId, uint8_t newPosition) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); | ||
|
||
Clusters::SwitchServer::Instance().OnLongPress(endpointId, newPosition); | ||
} | ||
|
||
void SwitchEventHandler::OnShortRelease(EndpointId endpointId, uint8_t previousPosition) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d", __func__, endpointId, previousPosition); | ||
|
||
Clusters::SwitchServer::Instance().OnShortRelease(endpointId, previousPosition); | ||
} | ||
|
||
void SwitchEventHandler::OnLongRelease(EndpointId endpointId, uint8_t previousPosition) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d", __func__, endpointId, previousPosition); | ||
|
||
Clusters::SwitchServer::Instance().OnLongRelease(endpointId, previousPosition); | ||
} | ||
|
||
void SwitchEventHandler::OnMultiPressOngoing(EndpointId endpointId, uint8_t newPosition, uint8_t count) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d, count=%d", __func__, endpointId, newPosition, count); | ||
|
||
Clusters::SwitchServer::Instance().OnMultiPressOngoing(endpointId, newPosition, count); | ||
} | ||
|
||
void SwitchEventHandler::OnMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uint8_t count) | ||
{ | ||
ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d, count=%d", __func__, endpointId, previousPosition, count); | ||
|
||
Clusters::SwitchServer::Instance().OnMultiPressComplete(endpointId, previousPosition, count); | ||
} | ||
#endif // MATTER_DM_PLUGIN_SWITCH_SERVER |
Oops, something went wrong.