blob: be91419dcd835b30422a393efe3474172ddb5bac [file] [log] [blame]
{{> header}}
#pragma once
#import <Matter/Matter.h>
#include <cstdint>
#include <string>
#include <type_traits>
#include <commands/clusters/ComplexArgument.h>
#include <app/data-model/DecodableList.h>
#include <commands/clusters/ClusterCommandBridge.h>
#include <commands/clusters/ReportCommandBridge.h>
#include <commands/clusters/WriteAttributeCommandBridge.h>
#include <app-common/zap-generated/cluster-objects.h>
{{> clusters_header}}
{{#chip_client_clusters includeAll=true}}
{{> cluster_header}}
{{#chip_cluster_commands}}
/*
* Command {{asUpperCamelCase name}}
*/
class {{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}: public ClusterCommand
{
public:
{{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}(): ClusterCommand("{{cleanse_label_as_kebab_case name}}"){{#zcl_command_arguments}}{{#if_chip_complex}}, mComplex_{{asUpperCamelCase label}}(&mRequest.{{asLowerCamelCase label}}){{/if_chip_complex}}{{/zcl_command_arguments}}
{
{{#chip_cluster_command_arguments}}
{{#if_chip_complex}}
AddArgument("{{asUpperCamelCase label}}", &mComplex_{{asUpperCamelCase label}});
{{else if (isString type)}}
AddArgument("{{asUpperCamelCase label}}", &mRequest.{{asLowerCamelCase label}});
{{else}}
AddArgument("{{asUpperCamelCase label}}", {{as_type_min_value type language='c++'}}, {{as_type_max_value type language='c++'}}, &mRequest.{{asLowerCamelCase label}});
{{/if_chip_complex}}
{{/chip_cluster_command_arguments}}
ClusterCommand::AddArguments();
}
CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
{
ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) command ({{asHex code 8}}) on endpoint %u", endpointId);
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
MTRBaseCluster{{asUpperCamelCase clusterName}} * cluster = [[MTRBaseCluster{{asUpperCamelCase clusterName}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
__auto_type * params = [[MTR{{asUpperCamelCase clusterName}}Cluster{{asUpperCamelCase name}}Params alloc] init];
params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
{{#chip_cluster_command_arguments}}
{{>decodable_value target=(concat "params." (asStructPropertyName label)) source=(concat "mRequest." (asLowerCamelCase label)) cluster=parent.clusterName type=type depth=0}}
{{/chip_cluster_command_arguments}}
uint16_t repeatCount = mRepeatCount.ValueOr(1);
uint16_t __block responsesNeeded = repeatCount;
while (repeatCount--)
{
[cluster {{asLowerCamelCase name}}WithParams:params completion:
{{#if hasSpecificResponse}}
^(MTR{{asUpperCamelCase clusterName}}Cluster{{asUpperCamelCase responseName}}Params * _Nullable values, NSError * _Nullable error) {
NSLog(@"Values: %@", values);
{{else}}
^(NSError * _Nullable error) {
{{/if}}
responsesNeeded--;
if (error != nil) {
mError = error;
LogNSError("Error", error);
}
if (responsesNeeded == 0) {
SetCommandExitStatus(mError);
}
}];
}
return CHIP_NO_ERROR;
}
private:
{{#if (hasArguments)}}
chip::app::Clusters::{{asUpperCamelCase clusterName}}::Commands::{{asUpperCamelCase name}}::Type mRequest;
{{/if}}
{{#chip_cluster_command_arguments}}
{{#if_chip_complex}}
TypedComplexArgument<{{zapTypeToEncodableClusterObjectType type ns=parent.parent.name}}> mComplex_{{asUpperCamelCase label}};
{{/if_chip_complex}}
{{/chip_cluster_command_arguments}}
};
{{/chip_cluster_commands}}
{{#chip_server_cluster_attributes}}
{{#*inline "attribute"}}Attribute{{asUpperCamelCase name}}{{/inline}}
/*
* Attribute {{asUpperCamelCase name}}
*/
class Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public ReadAttribute
{
public:
Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): ReadAttribute("{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}")
{
}
~Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}()
{
}
CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
{
ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) ReadAttribute ({{asHex code 8}}) on endpoint %u", endpointId);
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
{{#if_is_fabric_scoped_struct type}}
MTRReadParams * params = [[MTRReadParams alloc] init];
if (mFabricFiltered.HasValue()) {
params.filterByFabric = mFabricFiltered.Value();
}
{{/if_is_fabric_scoped_struct}}
[cluster readAttribute{{asUpperCamelCase name}}With
{{~#if_is_fabric_scoped_struct type~}}
Params:params completion:
{{~else~}}
Completion:
{{~/if_is_fabric_scoped_struct~}}
^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
NSLog(@"{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} response %@", [value description]);
if (error != nil) {
LogNSError("{{asUpperCamelCase parent.name}} {{asUpperCamelCase name}} read Error", error);
}
SetCommandExitStatus(error);
}];
return CHIP_NO_ERROR;
}
};
{{#if isWritableAttribute}}
{{! No list support for writing yet. Need to figure out how to represent the
values. }}
class Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public WriteAttribute
{
public:
Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): WriteAttribute("{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}"){{#if_chip_complex}}, mComplex(&mValue){{/if_chip_complex}}
{
AddArgument("attr-name", "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}");
{{#if_chip_complex}}
AddArgument("attr-value", &mComplex);
{{else if (isString type)}}
AddArgument("attr-value", &mValue);
{{else}}
AddArgument("attr-value", {{as_type_min_value type language='c++'}}, {{as_type_max_value type language='c++'}}, &mValue);
{{/if_chip_complex}}
WriteAttribute::AddArguments();
}
~Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}()
{
}
CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
{
ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) WriteAttribute ({{asHex code 8}}) on endpoint %u", endpointId);
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
MTRWriteParams * params = [[MTRWriteParams alloc] init];
params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
{{#if_chip_complex}}
{{asObjectiveCType type parent.name}} value;
{{>decodable_value target="value" source="mValue" cluster=parent.name errorCode="return err;" depth=0}}
{{else if (isOctetString type)}}
{{asObjectiveCType type parent.name}} value = [[NSData alloc] initWithBytes:mValue.data() length:mValue.size()];
{{else if (isString type)}}
{{asObjectiveCType type parent.name}} value = [[NSString alloc] initWithBytes:mValue.data() length:mValue.size() encoding:NSUTF8StringEncoding];
{{else}}
{{asObjectiveCType type parent.name}} value = [NSNumber numberWith{{asObjectiveCNumberType "" type false}}:mValue];
{{/if_chip_complex}}
[cluster writeAttribute{{asUpperCamelCase name}}WithValue:value params:params completion:^(NSError * _Nullable error) {
if (error != nil) {
LogNSError("{{asUpperCamelCase parent.name}} {{asUpperCamelCase name}} write Error", error);
}
SetCommandExitStatus(error);
}];
return CHIP_NO_ERROR;
}
private:
{{#if_chip_complex}}
{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}} mValue;
TypedComplexArgument<{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}}> mComplex;
{{else if (isOctetString type)}}
chip::ByteSpan mValue;
{{else if (isCharString type)}}
chip::ByteSpan mValue;
{{else}}
{{chipType}} mValue;
{{/if_chip_complex}}
};
{{/if}}
{{#if isReportableAttribute}}
class SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public SubscribeAttribute
{
public:
SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): SubscribeAttribute("{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}")
{
}
~SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}()
{
}
CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
{
ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) ReportAttribute ({{asHex code 8}}) on endpoint %u", endpointId);
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
if (mKeepSubscriptions.HasValue()) {
params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
}
if (mFabricFiltered.HasValue()) {
params.filterByFabric = mFabricFiltered.Value();
}
if (mAutoResubscribe.HasValue()) {
params.resubscribeIfLost = mAutoResubscribe.Value();
}
[cluster subscribe{{>attribute}}WithParams:params
subscriptionEstablished:^(){ mSubscriptionEstablished=YES; }
reportHandler:^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
NSLog(@"{{asUpperCamelCase parent.name}}.{{asUpperCamelCase name}} response %@", [value description]);
SetCommandExitStatus(error);
}];
return CHIP_NO_ERROR;
}
};
{{/if}}
{{/chip_server_cluster_attributes}}
{{/chip_client_clusters}}
/*----------------------------------------------------------------------------*\
| Register all Clusters commands |
\*----------------------------------------------------------------------------*/
{{#chip_client_clusters includeAll=true}}
void registerCluster{{asUpperCamelCase name}}(Commands & commands)
{
using namespace chip::app::Clusters::{{asUpperCamelCase name}};
const char * clusterName = "{{asUpperCamelCase name}}";
commands_list clusterCommands = {
make_unique<ClusterCommand>(Id), //
{{#chip_cluster_commands}}
make_unique<{{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}>(), //
{{/chip_cluster_commands}}
{{#chip_server_cluster_attributes}}
{{#first}}
make_unique<ReadAttribute>(Id), //
{{/first}}
make_unique<Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
{{#first}}
make_unique<WriteAttribute>(Id), //
{{/first}}
{{#if isWritableAttribute}}
make_unique<Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
{{/if}}
{{#first}}
make_unique<SubscribeAttribute>(Id), //
{{/first}}
{{#if isReportableAttribute}}
make_unique<SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
{{/if}}
{{/chip_server_cluster_attributes}}
};
commands.Register(clusterName, clusterCommands);
}
{{/chip_client_clusters}}
void registerClusterAny(Commands & commands)
{
const char * clusterName = "Any";
commands_list clusterCommands = {
make_unique<ClusterCommand>(), //
make_unique<ReadAttribute>(), //
make_unique<WriteAttribute>(), //
make_unique<SubscribeAttribute>(), //
make_unique<SubscribeEvent>(), //
};
commands.Register(clusterName, clusterCommands);
}
void registerClusters(Commands & commands)
{
registerClusterAny(commands);
{{#chip_client_clusters includeAll=true}}
registerCluster{{asUpperCamelCase name}}(commands);
{{/chip_client_clusters}}
}