Skip to content

Commit

Permalink
[WIP] Adding boolean state sensor control to Chef
Browse files Browse the repository at this point in the history
- Add new RPCs to set/read BooleanState cluster
- Update nRF, ESP32 and Linux chef examples to include
- Update some docs that were stale
- Allow StatusUtils for RPC to deal with CHIP_ERROR

Issue project-chip#25225
Fixes project-chip#31725
  • Loading branch information
tcarmelveilleux committed Jan 28, 2024
1 parent 09324e7 commit 393662c
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 5 deletions.
6 changes: 3 additions & 3 deletions examples/chef/NEW_CHEF_DEVICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ Basic device availability should show when running:

### Compilation

This example uses `rootnode_contactsensor_lFAGG1bfRO` for commands. Substitute
This example uses `rootnode_contactsensor_27f76aeaf5` for commands. Substitute
your own device for testing newly created devices.

```
./examples/chef/chef.py \
-t linux \
-d rootnode_contactsensor_lFAGG1bfRO \
-d rootnode_contactsensor_27f76aeaf5 \
-b
```

Expand All @@ -113,5 +113,5 @@ Where options used are:
### Execution

Build will be available in
`examples/chef/linux/out/rootnode_contactsensor_lFAGG1bfRO` (path will vary
`examples/chef/linux/out/rootnode_contactsensor_27f76aeaf5` (path will vary
based on platform and device being built)
13 changes: 13 additions & 0 deletions examples/chef/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ pw_proto_library(attributes_service
pw_protobuf.common_proto
)

pw_proto_library(boolean_state_service
SOURCES
${CHIP_ROOT}/examples/common/pigweed/protos/boolean_state_service.proto
PREFIX
boolean_sate_service
STRIP_PREFIX
${CHIP_ROOT}/examples/common/pigweed/protos
DEPS
pw_protobuf.common_proto
)

pw_proto_library(button_service
SOURCES
${CHIP_ROOT}/examples/common/pigweed/protos/button_service.proto
Expand Down Expand Up @@ -191,6 +202,7 @@ pw_proto_library(wifi_service

target_link_libraries(${COMPONENT_LIB} PUBLIC
attributes_service.nanopb_rpc
boolean_state_service.nanopb_rpc
button_service.nanopb_rpc
descriptor_service.nanopb_rpc
device_service.nanopb_rpc
Expand All @@ -215,6 +227,7 @@ target_link_options(${COMPONENT_LIB}

target_compile_options(${COMPONENT_LIB} PRIVATE
"-DPW_RPC_ATTRIBUTE_SERVICE=1"
"-DPW_RPC_BOOLEAN_STATE_SERVICE=1"
"-DPW_RPC_BUTTON_SERVICE=1"
"-DPW_RPC_DEVICE_SERVICE=1"
"-DPW_RPC_DESCRIPTOR_SERVICE=1"
Expand Down
2 changes: 2 additions & 0 deletions examples/chef/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ executable("${sample_name}") {
defines = [
"PW_RPC_ENABLED",
"PW_RPC_ATTRIBUTE_SERVICE=1",
"PW_RPC_BOOLEAN_STATE_SERVICE=1",
"PW_RPC_BUTTON_SERVICE=1",
"PW_RPC_DESCRIPTOR_SERVICE=1",
"PW_RPC_DEVICE_SERVICE=1",
Expand All @@ -95,6 +96,7 @@ executable("${sample_name}") {
"$dir_pw_trace_tokenized:trace_rpc_service",
"${chip_root}/config/linux/lib/pw_rpc:pw_rpc",
"${chip_root}/examples/common/pigweed:attributes_service.nanopb_rpc",
"${chip_root}/examples/common/pigweed:boolean_state_service.nanopb_rpc",
"${chip_root}/examples/common/pigweed:button_service.nanopb_rpc",
"${chip_root}/examples/common/pigweed:descriptor_service.nanopb_rpc",
"${chip_root}/examples/common/pigweed:device_service.nanopb_rpc",
Expand Down
13 changes: 13 additions & 0 deletions examples/chef/nrfconnect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ pw_proto_library(attributes_service
pw_protobuf.common_proto
)

pw_proto_library(boolean_state_service
SOURCES
${CHIP_ROOT}/examples/common/pigweed/protos/boolean_state_service.proto
PREFIX
boolean_state_service
STRIP_PREFIX
${CHIP_ROOT}/examples/common/pigweed/protos
DEPS
pw_protobuf.common_proto
)

pw_proto_library(descriptor_service
SOURCES
${CHIP_ROOT}/examples/common/pigweed/protos/descriptor_service.proto
Expand Down Expand Up @@ -202,13 +213,15 @@ target_include_directories(app PRIVATE

target_compile_options(app PRIVATE
"-DPW_RPC_ATTRIBUTE_SERVICE=1"
"-DPW_RPC_BOOLEAN_STATE_SERVICE=1"
"-DPW_RPC_DESCRIPTOR_SERVICE=1"
"-DPW_RPC_DEVICE_SERVICE=1"
"-DPW_RPC_THREAD_SERVICE=1"
)

target_link_libraries(app PRIVATE
attributes_service.nanopb_rpc
boolean_state_service.nanopb_rpc
descriptor_service.nanopb_rpc
device_service.nanopb_rpc
thread_service.nanopb_rpc
Expand Down
7 changes: 7 additions & 0 deletions examples/common/pigweed/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ pw_proto_library("attributes_service") {
prefix = "attributes_service"
}

pw_proto_library("boolean_state_service") {
sources = [ "protos/boolean_state_service.proto" ]
deps = [ "$dir_pw_protobuf:common_protos" ]
strip_prefix = "protos"
prefix = "boolean_state_service"
}

pw_proto_library("device_service") {
sources = [ "protos/device_service.proto" ]
inputs = [ "protos/device_service.options" ]
Expand Down
37 changes: 37 additions & 0 deletions examples/common/pigweed/protos/boolean_state_service.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
syntax = "proto3";

import 'pw_protobuf_protos/common.proto';

package chip.rpc;

// This may eventually contain more attributes.
message BooleanStateState {
bool state_value = 1;
}

message BooleanStateSetRequest {
uint32 endpoint_id = 1;
bool state_value = 2;
}

message BooleanStateSetResponse {
uint64 event_number = 1;
}

message BooleanStateGetRequest {
uint32 endpoint_id = 1;
}

message BooleanStateGetResponse {
BooleanStateState state = 1;
}

service BooleanState {
// Set will return generated event number (caused by change) if all supported fields are successfully applied, any
// unsupported fields will be ignored.
rpc Set(BooleanStateSetRequest) returns (BooleanStateSetResponse){}

// Get will populate all of the supported boolean state cluster state fields
// with the current values.
rpc Get(BooleanStateGetRequest) returns (BooleanStateGetResponse){}
}
72 changes: 72 additions & 0 deletions examples/common/pigweed/rpc_services/BooleanState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
*
* 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/util/attribute-storage.h"
#include "boolean_state_service/boolean_state_service.rpc.pb.h"
#include "pigweed/rpc_services/internal/StatusUtils.h"
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/EventLogging.h>
#include <platform/PlatformManager.h>

namespace chip {
namespace rpc {

class BooleanState final : public pw_rpc::nanopb::BooleanState::Service<BooleanState>
{
public:
virtual ~BooleanState() = default;

virtual pw::Status Set(const chip_rpc_BooleanStateSetRequest & request, chip_rpc_BooleanStateSetResponse & response)
{
EndpointId endpointId = request.endpoint_id;
bool newState = request.state_value;

EventNumber eventNumber;
{
DeviceLayer::StackLock lock;

// Update attribute first, then emit StateChange event only on success.
RETURN_STATUS_IF_NOT_OK(app::Clusters::BooleanState::Attributes::StateValue::Set(endpointId, newState));

chip::app::Clusters::BooleanState::Events::StateChange::Type event{ newState };
RETURN_STATUS_IF_NOT_OK(app::LogEvent(event, endpointId, eventNumber));
}

response.event_number = static_cast<uint64_t>(eventNumber);
return pw::OkStatus();
}

virtual pw::Status Get(const chip_rpc_BooleanStateGetRequest & request, chip_rpc_BooleanStateGetResponse & response)
{
EndpointId endpointId = request.endpoint_id;
bool state_value = false;

{
DeviceLayer::StackLock lock;
RETURN_STATUS_IF_NOT_OK(app::Clusters::BooleanState::Attributes::StateValue::Get(endpointId, &state_value));
}

response.state.state_value = state_value;
return pw::OkStatus();
}
};

} // namespace rpc
} // namespace chip
26 changes: 24 additions & 2 deletions examples/common/pigweed/rpc_services/internal/StatusUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
#pragma once

#include "app/util/attribute-storage.h"
#include "protocols/interaction_model/StatusCode.h"
#include "pw_status/status.h"

#define RETURN_STATUS_IF_NOT_OK(expr) \
do \
{ \
pw::Status __status = chip::rpc::EmberStatusToPwStatus(expr); \
pw::Status __status = chip::rpc::EmberOrChipStatusToPwStatus(expr); \
if (!__status.ok()) \
{ \
return __status; \
Expand All @@ -35,7 +36,7 @@
namespace chip {
namespace rpc {

constexpr pw::Status EmberStatusToPwStatus(EmberAfStatus ember_status)
constexpr pw::Status EmberOrChipStatusToPwStatus(EmberAfStatus ember_status)
{
switch (ember_status)
{
Expand All @@ -50,5 +51,26 @@ constexpr pw::Status EmberStatusToPwStatus(EmberAfStatus ember_status)
}
}

constexpr pw::Status EmberOrChipStatusToPwStatus(CHIP_ERROR chip_error_status)
{
switch (chip_error_status.AsInteger())
{
case CHIP_NO_ERROR.AsInteger():
return pw::OkStatus();
case CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute).AsInteger():
case CHIP_IM_GLOBAL_STATUS(UnsupportedCommand).AsInteger():
case CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint).AsInteger():
case CHIP_IM_GLOBAL_STATUS(UnsupportedEvent).AsInteger():
return pw::Status::NotFound();
case CHIP_IM_GLOBAL_STATUS(UnsupportedAccess).AsInteger():
return pw::Status::PermissionDenied();
case CHIP_IM_GLOBAL_STATUS(InvalidAction).AsInteger():
case CHIP_IM_GLOBAL_STATUS(InvalidCommand).AsInteger():
return pw::Status::InvalidArgument();
default:
return pw::Status::Unknown();
}
}

} // namespace rpc
} // namespace chip
12 changes: 12 additions & 0 deletions examples/platform/esp32/Rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#include "pigweed/rpc_services/Attributes.h"
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
#include "pigweed/rpc_services/BooleanState.h"
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
#if CONFIG_DEVICE_TYPE_M5STACK
#include "ScreenManager.h"
Expand Down Expand Up @@ -275,6 +279,10 @@ StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE];
Attributes attributes_service;
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
BooleanState boolean_state_service;
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
Esp32Button button_service;
#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
Expand Down Expand Up @@ -309,6 +317,10 @@ void RegisterServices(pw::rpc::Server & server)
server.RegisterService(attributes_service);
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
server.RegisterService(boolean_state_service);
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
server.RegisterService(button_service);
#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
Expand Down
12 changes: 12 additions & 0 deletions examples/platform/linux/Rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
#include "pigweed/rpc_services/Attributes.h"
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
#include "pigweed/rpc_services/BooleanState.h"
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_DESCRIPTOR_SERVICE) && PW_RPC_DESCRIPTOR_SERVICE
#include "pigweed/rpc_services/Descriptor.h"
#endif // defined(PW_RPC_DESCRIPTOR_SERVICE) && PW_RPC_DESCRIPTOR_SERVICE
Expand Down Expand Up @@ -68,6 +72,10 @@ namespace {
Attributes attributes_service;
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
BooleanState boolean_state_service;
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_DESCRIPTOR_SERVICE) && PW_RPC_DESCRIPTOR_SERVICE
Descriptor descriptor_service;
#endif // defined(PW_RPC_DESCRIPTOR_SERVICE) && PW_RPC_DESCRIPTOR_SERVICE
Expand All @@ -90,6 +98,10 @@ void RegisterServices(pw::rpc::Server & server)
server.RegisterService(attributes_service);
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
server.RegisterService(boolean_state_service);
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_DESCRIPTOR_SERVICE) && PW_RPC_DESCRIPTOR_SERVICE
server.RegisterService(descriptor_service);
#endif // defined(PW_RPC_DESCRIPTOR_SERVICE) && PW_RPC_DESCRIPTOR_SERVICE
Expand Down
12 changes: 12 additions & 0 deletions examples/platform/nrfconnect/Rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
#include "pigweed/rpc_services/Attributes.h"
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
#include "pigweed/rpc_services/BooleanState.h"
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
#include "pigweed/rpc_services/Button.h"
#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
Expand Down Expand Up @@ -139,6 +143,10 @@ struct k_thread rpc_thread_data;
Attributes attributes_service;
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
BooleanState boolean_state_service;
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
NrfButton button_service;
#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
Expand Down Expand Up @@ -177,6 +185,10 @@ void RegisterServices(pw::rpc::Server & server)
server.RegisterService(attributes_service);
#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE

#if defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE
server.RegisterService(boolean_state_service);
#endif // defined(PW_RPC_BOOLEAN_STATE_SERVICE) && PW_RPC_BOOLEAN_STATE_SERVICE

#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
server.RegisterService(button_service);
#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE
Expand Down

0 comments on commit 393662c

Please sign in to comment.