Skip to content

Commit

Permalink
Add timed write attributes support in IDL (project-chip#25756)
Browse files Browse the repository at this point in the history
* Parser support for timed writes

* Small doc update

* Matter idl support for timed write

* Fix indent and codegen all

* Remove extra line from readme

* Fix conditional in requires_timed_write
  • Loading branch information
andy31415 authored Mar 21, 2023
1 parent f5e32c1 commit f459a4e
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4208,7 +4208,7 @@ server cluster UnitTesting = 4294048773 {
attribute int16s rangeRestrictedInt16s = 41;
attribute LONG_OCTET_STRING listLongOctetString[] = 42;
attribute TestFabricScoped listFabricScoped[] = 43;
attribute boolean timedWriteBoolean = 48;
timedwrite attribute boolean timedWriteBoolean = 48;
attribute boolean generalErrorBoolean = 49;
attribute boolean clusterErrorBoolean = 50;
attribute nullable boolean nullableBoolean = 16384;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3528,7 +3528,7 @@ server cluster UnitTesting = 4294048773 {
attribute int16s rangeRestrictedInt16s = 41;
attribute LONG_OCTET_STRING listLongOctetString[] = 42;
attribute TestFabricScoped listFabricScoped[] = 43;
attribute boolean timedWriteBoolean = 48;
timedwrite attribute boolean timedWriteBoolean = 48;
attribute boolean generalErrorBoolean = 49;
attribute boolean clusterErrorBoolean = 50;
attribute nullable boolean nullableBoolean = 16384;
Expand Down
3 changes: 3 additions & 0 deletions scripts/py_matter_idl/matter_idl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ server cluster AccessControl = 31 {
attribute AccessControlEntry acl[] = 0; // attributes are read-write by default
attribute ExtensionEntry extension[] = 1; // and require a (spec defined) number
// attributes may require timed writes
timedwrite attribute int16u require_timed_writes = 3;
// Access control privileges on attributes default to:
//
// access(read: view, write: operate)
Expand Down
1 change: 1 addition & 0 deletions scripts/py_matter_idl/matter_idl/matter_grammar.lark
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ attribute_with_access: attribute_access? struct_field
attribute: attribute_qualities "attribute"i attribute_with_access ";"
attribute_quality: "readonly"i -> attr_readonly
| "nosubscribe"i -> attr_nosubscribe
| "timedwrite"i -> attr_timed
attribute_qualities: attribute_quality* -> attribute_qualities

request_struct: "request"i struct
Expand Down
3 changes: 3 additions & 0 deletions scripts/py_matter_idl/matter_idl/matter_idl_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ def attr_readonly(self, _):
def attr_nosubscribe(self, _):
return AttributeQuality.NOSUBSCRIBE

def attr_timed(self, _):
return AttributeQuality.TIMED_WRITE

def attribute_qualities(self, qualities):
return UnionOfAllFlags(qualities) or AttributeQuality.NONE

Expand Down
5 changes: 5 additions & 0 deletions scripts/py_matter_idl/matter_idl/matter_idl_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class AttributeQuality(enum.Flag):
READABLE = enum.auto()
WRITABLE = enum.auto()
NOSUBSCRIBE = enum.auto()
TIMED_WRITE = enum.auto()


class AttributeStorage(enum.Enum):
Expand Down Expand Up @@ -135,6 +136,10 @@ def is_writable(self):
def is_subscribable(self):
return not (AttributeQuality.NOSUBSCRIBE & self.qualities)

@property
def requires_timed_write(self):
return AttributeQuality.TIMED_WRITE & self.qualities


@dataclass
class Struct:
Expand Down
27 changes: 27 additions & 0 deletions scripts/py_matter_idl/matter_idl/test_matter_idl_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,33 @@ def test_sized_attribute(self):
)])
self.assertEqual(actual, expected)

def test_timed_attributes(self):
actual = parseText("""
server cluster MyCluster = 1 {
attribute int32u attr1 = 1;
timedwrite attribute int32u attr2 = 2;
attribute int32u attr3 = 3;
timedwrite attribute octet_string<44> attr4[] = 4;
}
""")

expected = Idl(clusters=[
Cluster(side=ClusterSide.SERVER,
name="MyCluster",
code=1,
attributes=[
Attribute(qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE, definition=Field(
data_type=DataType(name="int32u"), code=1, name="attr1")),
Attribute(qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE | AttributeQuality.TIMED_WRITE, definition=Field(
data_type=DataType(name="int32u"), code=2, name="attr2")),
Attribute(qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE, definition=Field(
data_type=DataType(name="int32u"), code=3, name="attr3")),
Attribute(qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE | AttributeQuality.TIMED_WRITE, definition=Field(
data_type=DataType(name="octet_string", max_length=44), code=4, name="attr4", is_list=True)),
]
)])
self.assertEqual(actual, expected)

def test_attribute_access(self):
actual = parseText("""
server cluster MyCluster = 1 {
Expand Down
5 changes: 4 additions & 1 deletion src/app/zap-templates/templates/app/MatterIDL.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@
{{/zcl_events}}
{{#chip_server_cluster_attributes}}
{{#unless isGlobalAttribute}}
{{! ensure indent }}{{#unless isWritableAttribute~}}
{{! ensure indent }}{{#if mustUseTimedWrite~}}
timedwrite {{!marker to place a space even with whitespace removal~}}
{{~/if~}}
{{~#unless isWritableAttribute~}}
readonly {{!marker to place a space even with whitespace removal~}}
{{~/unless~}}
{{~!TODO: write only attributes should also be supported~}}
Expand Down
2 changes: 1 addition & 1 deletion src/controller/data_model/controller-clusters.matter
Original file line number Diff line number Diff line change
Expand Up @@ -4539,7 +4539,7 @@ client cluster UnitTesting = 4294048773 {
attribute int16s rangeRestrictedInt16s = 41;
attribute LONG_OCTET_STRING listLongOctetString[] = 42;
attribute TestFabricScoped listFabricScoped[] = 43;
attribute boolean timedWriteBoolean = 48;
timedwrite attribute boolean timedWriteBoolean = 48;
attribute boolean generalErrorBoolean = 49;
attribute boolean clusterErrorBoolean = 50;
attribute boolean unsupported = 255;
Expand Down

0 comments on commit f459a4e

Please sign in to comment.