diff --git a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImInvokeCommand.kt b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImInvokeCommand.kt index f66c0d061343ce..adec2e8ede0da9 100644 --- a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImInvokeCommand.kt +++ b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImInvokeCommand.kt @@ -18,17 +18,11 @@ package com.matter.controller.commands.pairing import com.matter.controller.commands.common.CredentialsIssuer -import java.time.Duration import java.util.logging.Level import java.util.logging.Logger import kotlinx.coroutines.runBlocking -import matter.controller.InvokeRequest -import matter.controller.InvokeResponse import matter.controller.MatterController -import matter.controller.model.CommandPath -import matter.tlv.AnonymousTag -import matter.tlv.ContextSpecificTag -import matter.tlv.TlvWriter +import matter.devicecontroller.cluster.clusters.IdentifyCluster class PairOnNetworkLongImInvokeCommand( controller: MatterController, @@ -43,19 +37,6 @@ class PairOnNetworkLongImInvokeCommand( DiscoveryFilterType.LONG_DISCRIMINATOR ) { override fun runCommand() { - val IdentifyTime: UShort = 1u - val tlvWriter1 = TlvWriter() - tlvWriter1.startStructure(AnonymousTag) - tlvWriter1.put(ContextSpecificTag(0), IdentifyTime) - tlvWriter1.endStructure() - - val element1: InvokeRequest = - InvokeRequest( - CommandPath(endpointId = 0u, clusterId = CLUSTER_ID_IDENTIFY, commandId = IDENTIFY_COMMAND), - tlvPayload = tlvWriter1.getEncoded(), - timedRequest = Duration.ZERO - ) - currentCommissioner() .pairDevice( getNodeId(), @@ -69,11 +50,10 @@ class PairOnNetworkLongImInvokeCommand( runBlocking { try { - val response: InvokeResponse = currentCommissioner().invoke(element1) + val identifyTime: UShort = 1u + val identifyCluster = IdentifyCluster(controller = currentCommissioner(), endpointId = 0u) + identifyCluster.identify(identifyTime) logger.log(Level.INFO, "Invoke command succeeded") - if (response.payload.isNotEmpty()) { - // TODO:Handle TLV data response - } } catch (ex: Exception) { setFailure("invoke failure: ${ex.message}") } finally { @@ -86,11 +66,6 @@ class PairOnNetworkLongImInvokeCommand( companion object { private val logger = Logger.getLogger(PairOnNetworkLongImInvokeCommand::class.java.name) - private const val MATTER_PORT = 5540 - private const val CLUSTER_ID_IDENTIFY = 0x0003u - private const val IDENTIFY_COMMAND = 0u - private const val CLUSTER_ID_TEST = 0xFFF1FC05u - private const val TEST_ADD_ARGUMENT_COMMAND = 0X04u } } diff --git a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt index 15cf62ed504067..73aff84ff6aac8 100644 --- a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt +++ b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt @@ -5,11 +5,7 @@ import java.util.logging.Level import java.util.logging.Logger import kotlinx.coroutines.runBlocking import matter.controller.MatterController -import matter.controller.ReadData -import matter.controller.ReadRequest -import matter.controller.ReadResponse -import matter.controller.model.AttributePath -import matter.controller.model.EventPath +import matter.devicecontroller.cluster.clusters.BasicInformationCluster class PairOnNetworkLongImReadCommand(controller: MatterController, credsIssue: CredentialsIssuer?) : PairingCommand( @@ -21,31 +17,6 @@ class PairOnNetworkLongImReadCommand(controller: MatterController, credsIssue: C DiscoveryFilterType.LONG_DISCRIMINATOR ) { override fun runCommand() { - val attributePaths = - listOf( - AttributePath( - endpointId = DEFAULT_ENDPOINT, - clusterId = CLUSTER_ID_BASIC, - attributeId = ATTR_ID_LOCAL_CONFIG_DISABLED, - ), - AttributePath( - endpointId = DEFAULT_ENDPOINT, - clusterId = CLUSTER_ID_BASIC, - attributeId = GLOBAL_ATTRIBUTE_LIST, - ) - ) - - val eventPaths = - listOf( - EventPath( - endpointId = WILDCARD_ENDPOINT_ID, - clusterId = WILDCARD_CLUSTER_ID, - eventId = WILDCARD_EVENT_ID - ) - ) - - val readRequest: ReadRequest = ReadRequest(eventPaths, attributePaths) - currentCommissioner() .pairDevice( getNodeId(), @@ -59,9 +30,11 @@ class PairOnNetworkLongImReadCommand(controller: MatterController, credsIssue: C runBlocking { try { - val response: ReadResponse = currentCommissioner().read(readRequest) - logger.log(Level.INFO, "Read command succeeded") - validateResponse(response) + val basicInformationCluster = + BasicInformationCluster(controller = currentCommissioner(), endpointId = DEFAULT_ENDPOINT) + val vendorName = basicInformationCluster.readVendorNameAttribute() + val vendorId = basicInformationCluster.readVendorIDAttribute() + logger.log(Level.INFO, "Read command succeeded, Verdor Name:${vendorName} (ID:${vendorId})") } catch (ex: Exception) { logger.log(Level.WARNING, "General read failure occurred with error ${ex.message}") setFailure("read failure") @@ -73,37 +46,9 @@ class PairOnNetworkLongImReadCommand(controller: MatterController, credsIssue: C setSuccess() } - private fun findAttributeById(successes: List, id: UInt): ReadData.Attribute? { - return successes.filterIsInstance().find { it.path.attributeId == id } - } - - private fun findEventById(successes: List, id: UInt): ReadData.Event? { - return successes.filterIsInstance().find { it.path.eventId == id } - } - - private fun validateResponse(response: ReadResponse) { - require(response.successes.isNotEmpty()) { "Unexpected: response.successes is empty" } - require(response.failures.isEmpty()) { "Unexpected: response.failures is not empty" } - - val localConfigDisabledAttribute = - findAttributeById(response.successes, ATTR_ID_LOCAL_CONFIG_DISABLED) - requireNotNull(localConfigDisabledAttribute) { "No local config disabled attribute found." } - - // TODO: Add more validation rules as needed - } - companion object { private val logger = Logger.getLogger(PairOnNetworkLongImReadCommand::class.java.name) - private const val MATTER_PORT = 5540 private const val DEFAULT_ENDPOINT: UShort = 0u - private const val WILDCARD_ENDPOINT_ID: UShort = 0xffffu - private const val WILDCARD_CLUSTER_ID: UInt = 0xffffffffu - private const val WILDCARD_ATTRIBUTE_ID: UInt = 0xffffffffu - private const val WILDCARD_EVENT_ID: UInt = 0xffffffffu - private const val CLUSTER_ID_BASIC: UInt = 0x0028u - private const val ATTR_ID_LOCAL_CONFIG_DISABLED: UInt = 16u - private const val EVENT_ID_START_UP: UInt = 0u - private const val GLOBAL_ATTRIBUTE_LIST: UInt = 65531u } } diff --git a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt index 04195a041adc22..bfe017339c09a1 100644 --- a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt +++ b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt @@ -18,17 +18,11 @@ package com.matter.controller.commands.pairing import com.matter.controller.commands.common.CredentialsIssuer -import java.time.Duration import java.util.logging.Level import java.util.logging.Logger import kotlinx.coroutines.runBlocking import matter.controller.MatterController -import matter.controller.WriteRequest -import matter.controller.WriteRequests -import matter.controller.WriteResponse -import matter.controller.model.AttributePath -import matter.tlv.AnonymousTag -import matter.tlv.TlvWriter +import matter.devicecontroller.cluster.clusters.BasicInformationCluster class PairOnNetworkLongImWriteCommand( controller: MatterController, @@ -43,25 +37,6 @@ class PairOnNetworkLongImWriteCommand( DiscoveryFilterType.LONG_DISCRIMINATOR ) { override fun runCommand() { - val tlvWriter1 = TlvWriter() - tlvWriter1.put(AnonymousTag, true) - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath( - endpointId = 0u, - clusterId = CLUSTER_ID_BASIC, - attributeId = ATTR_ID_LOCAL_CONFIG_DISABLED - ), - tlvPayload = tlvWriter1.getEncoded() - ) - ), - timedRequest = Duration.ZERO - ) - currentCommissioner() .pairDevice( getNodeId(), @@ -75,24 +50,13 @@ class PairOnNetworkLongImWriteCommand( runBlocking { try { - val response: WriteResponse = currentCommissioner().write(writeRequests) - - if (response is WriteResponse.Success) { - logger.log(Level.INFO, "Write command succeeded") - } else if (response is WriteResponse.PartialWriteFailure) { - logger.log( - Level.WARNING, - "Partial write failure occurred with ${response.failures.size} errors" - ) + val basicInformationCluster = + BasicInformationCluster(controller = currentCommissioner(), endpointId = DEFAULT_ENDPOINT) + basicInformationCluster.writeNodeLabelAttribute("Test Node Label") + logger.log(Level.INFO, "Write command succeeded") - for ((index, error) in response.failures.withIndex()) { - logger.log(Level.WARNING, "Error ${index + 1}:") - logger.log(Level.WARNING, "Attribute Path: ${error.attributePath}") - logger.log(Level.WARNING, "Exception Message: ${error.ex.message}") - } - - setFailure("invoke failure") - } + val nodeLabel = basicInformationCluster.readNodeLabelAttribute() + logger.log(Level.INFO, "Read command succeeded, NodeLabel:${nodeLabel}") } catch (ex: Exception) { setFailure("invoke failure: ${ex.message}") } catch (ex: Exception) { @@ -108,9 +72,7 @@ class PairOnNetworkLongImWriteCommand( companion object { private val logger = Logger.getLogger(PairOnNetworkLongImWriteCommand::class.java.name) - private const val MATTER_PORT = 5540 - private const val CLUSTER_ID_BASIC = 0x0028u - private const val ATTR_ID_LOCAL_CONFIG_DISABLED = 16u + private const val DEFAULT_ENDPOINT: UShort = 0u } } diff --git a/kotlin-detect-config.yaml b/kotlin-detect-config.yaml index 3ca00b718ca139..5dcc9f99a6b3cd 100644 --- a/kotlin-detect-config.yaml +++ b/kotlin-detect-config.yaml @@ -233,6 +233,9 @@ exceptions: - "**/src/controller/java/generated/java/**/*" naming: + VariableNaming: + excludes: + - "**/src/controller/java/generated/java/**/*" FunctionNaming: excludes: - "**/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt" diff --git a/scripts/py_matter_idl/matter_idl/generators/kotlin/MatterClusters.jinja b/scripts/py_matter_idl/matter_idl/generators/kotlin/MatterClusters.jinja index 29b3b9c5f26788..7d1b0d1f53f4b6 100644 --- a/scripts/py_matter_idl/matter_idl/generators/kotlin/MatterClusters.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/kotlin/MatterClusters.jinja @@ -39,6 +39,71 @@ {%- endif -%} {%- endmacro -%} +{%- macro encode_tlv(encodable, tag, name, depth) %} + {%- if encodable.is_optional and encodable.is_nullable -%} + {{name}}?.let { + {{encode_tlv(encodable.without_optional().without_nullable(), tag, name, depth + 1)}} + } + {%- elif encodable.is_optional -%} + {{name}}?.let { + {{encode_tlv(encodable.without_optional(), tag, name, depth + 1)}} + } + {%- elif encodable.is_nullable -%} + {{name}}?.let { + {{encode_tlv(encodable.without_nullable(), tag, name, depth + 1)}} + } + {%- elif encodable.is_list -%} + tlvWriter.startArray({{tag}}) + for (item in {{name}}.iterator()) { + {{encode_tlv(encodable.without_list(), "AnonymousTag", "item", depth + 1)}} + } + tlvWriter.endArray() + {%- elif encodable.is_struct -%} + {{name}}.toTlv({{tag}}, tlvWriter) + {%- else -%} + tlvWriter.put({{tag}}, {{name}}) + {%- endif -%} +{%- endmacro -%} + +{%- macro decode_tlv(source, encodable, tag, depth) %} + {%- if encodable.is_nullable -%} + if (!tlvReader.isNull()) { + {{decode_tlv(source, encodable.without_nullable(), tag, depth + 1)}} + } else { + tlvReader.getNull({{tag}}) + null + } + {%- elif encodable.is_optional -%} + if (tlvReader.isNextTag({{tag}})) { + {{decode_tlv(source, encodable.without_optional(), tag, depth + 1)}} + } else { + null + } + {%- elif encodable.is_list -%} + {%- set encodablewithoutlist = encodable.without_list() -%} + buildList<{{encode_value(source, encodablewithoutlist, depth + 1)}}> { + tlvReader.enterArray({{tag}}) + while(!tlvReader.isEndOfContainer()) { + add({{decode_tlv(source, encodablewithoutlist, "AnonymousTag", depth + 1)}}) + } + tlvReader.exitContainer() + } + {%- elif encodable.is_struct -%} + {%- set struct = encodable.get_underlying_struct() -%} + {{source.name}}Cluster{{struct.name}}.fromTlv({{tag}}, tlvReader) + {%- else -%} + tlvReader.get{{encodable.kotlin_type}}({{tag}}) + {%- endif -%} +{%- endmacro -%} + +{%- macro contextSpecificTag(field) -%} + ContextSpecificTag(TAG_{{field.name | constcase}}) +{%- endmacro -%} + +{%- macro contextSpecificTag1(tag_value) -%} + ContextSpecificTag({{tag_value}}) +{%- endmacro -%} + /* * * Copyright (c) 2023 Project CHIP Authors @@ -58,8 +123,19 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import java.time.Duration +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvParsingException +import matter.tlv.TlvReader +import matter.tlv.TlvWriter {% set typeLookup = idl | createLookupContext(cluster) %} class {{cluster.name}}Cluster(private val controller: MatterController, private val endpointId: UShort) { @@ -118,64 +194,214 @@ class {{cluster.name}}Cluster(private val controller: MatterController, private : {{callbackName}} { {%- else %} { {%- endif %} - val commandId = {{command.code}}L -{% if command.is_timed_invoke %} - // Implementation needs to be added here -{%- else %} - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } -{%- endif %} + val commandId: UInt = {{command.code}}u +{% if command.is_timed_invoke -%} + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) +{%- else -%} + val timeoutMs: Duration = timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO +{%- endif %} + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + {%- if command.input_param -%} + {% for field in (cluster.structs | named(command.input_param)).fields %} + {%- set encodable = field | asEncodable(typeLookup) %} + + val TAG_{{field.name | constcase}}_REQ: Int = {{field.code}} + {{encode_tlv(encodable, "ContextSpecificTag(TAG_" + field.name | constcase + "_REQ)", field.name | lowfirst_except_acronym, 0)}} + {%- endfor -%} + {%- endif %} + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + {%- if command | hasResponse %} + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + {%- set struct = cluster.structs | named(command.output_param) -%} + {%- for field in struct.fields %} + val TAG_{{field.name | constcase}}: Int = {{field.code}} + {% set encodable = field | asEncodable(typeLookup) -%} + {%- if encodable.is_optional or encodable.is_nullable-%} + var {{field.name | lowfirst_except_acronym}}_decoded: {{encode_value(cluster, field | asEncodable(typeLookup), 0)}} = null + {%- else -%} + var {{field.name | lowfirst_except_acronym}}_decoded: {{encode_value(cluster, field | asEncodable(typeLookup), 0)}}? = null + {%- endif %} + {% endfor %} + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + {% for field in struct.fields %} + if (tag == ContextSpecificTag(TAG_{{field.name | constcase}})) { + {%- set encodable = field | asEncodable(typeLookup) -%} + {%- if encodable.is_optional or encodable.is_nullable -%} + {{field.name | lowfirst_except_acronym}}_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + {{decode_tlv(cluster, encodable, "tag", 0)}} + } + {%- else -%} + {{field.name | lowfirst_except_acronym}}_decoded = {{decode_tlv(cluster, encodable, "tag", 0)}} + {%- endif -%} + } + {% endfor %} + + else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + {% for field in struct.fields %} + {% set encodable = field | asEncodable(typeLookup) -%} + {% if not encodable.is_optional and not encodable.is_nullable %} + if ({{field.name | lowfirst_except_acronym}}_decoded == null) { + throw IllegalStateException("{{field.name | lowfirst_except_acronym}} not found in TLV") + } + {%- endif %} + {% endfor %} + + tlvReader.exitContainer() + + return {{callbackName}}( + {%- for field in (cluster.structs | named(command.output_param)).fields %} + {{field.name | lowfirst_except_acronym}}_decoded{% if not loop.last %},{% endif %} + {%- endfor %} + ) + {%- endif %} } {% endfor -%} {% for attribute in cluster.attributes | sort(attribute='code') %} {%- set interfaceName = attribute | javaAttributeCallbackName(typeLookup) %} +{%- set attribute_id = "ATTRIBUTE_ID_" + attribute.definition.name | upper %} +{%- set encodable = attribute.definition | asEncodable(typeLookup) %} +{%- if attribute.definition is is_field_global_name(typeLookup) and encodable.is_optional -%} + suspend fun read{{ attribute.definition.name | upfirst }}Attribute(): {{interfaceName}}? { +{%- else -%} suspend fun read{{ attribute.definition.name | upfirst }}Attribute(): {{interfaceName}} { - // Implementation needs to be added here - } -{% if attribute | isFabricScopedList(typeLookup) %} - suspend fun read{{ attribute.definition.name | upfirst }}AttributeWithFabricFilter( - isFabricFiltered: Boolean - ): {{interfaceName}} { - // Implementation needs to be added here - } +{%- endif -%} + val ATTRIBUTE_ID: UInt = {{attribute.definition.code}}u + + val attributePath = AttributePath( + endpointId = endpointId, + clusterId = CLUSTER_ID, + attributeId = ATTRIBUTE_ID + ) + + val readRequest = ReadRequest( + eventPaths = emptyList(), + attributePaths = listOf(attributePath) + ) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "{{ attribute.definition.name | capitalize }} attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: {{encode_value(cluster, encodable, 0)}} = {{decode_tlv(cluster, attribute.definition | asEncodable(typeLookup), "AnonymousTag", 0)}} -{% endif -%} -{%- if attribute.is_writable %} +{% if attribute.definition is is_field_global_name(typeLookup) %} + return decodedValue +{%- else %} + return {{interfaceName}}(decodedValue) +{%- endif %} + } +{% if attribute.is_writable %} {%- set encodable = attribute.definition | asEncodable(typeLookup) -%} -{%- set encodable2 = attribute.definition | asEncodable(typeLookup) %} +{%- set attribute_id = "ATTRIBUTE_ID_" + attribute.definition.name | upper %} suspend fun write{{ attribute.definition.name | upfirst }}Attribute( - value: {{ encode_value_without_optional_nullable(cluster, encodable2, 0) }}, + value: {{ encode_value_without_optional_nullable(cluster, encodable, 0) }}, {%- if attribute.requires_timed_write -%} timedWriteTimeoutMs: Int {%- else %} timedWriteTimeoutMs: Int? = null -{%- endif %} +{%- endif %} ) { -{%- if attribute.requires_timed_write %} - // Implementation needs to be added here -{%- else %} - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } + val ATTRIBUTE_ID: UInt = {{attribute.definition.code}}u +{% if attribute.requires_timed_write -%} + val timeoutMs: Duration = Duration.ofMillis(timedWriteTimeoutMs.toLong()) +{%- else -%} + val timeoutMs: Duration = timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO {%- endif %} + + val tlvWriter = TlvWriter() + {%- set encodable = attribute.definition | asEncodable(typeLookup) %} + {%- if encodable.is_optional -%} + {%- set encodable = encodable.without_optional() %} + {%- endif %} + {%- if encodable.is_nullable -%} + {%- set encodable = encodable.without_nullable() %} + {%- endif %} + {%- set tag = contextSpecificTag(attribute) %} + {{encode_tlv(encodable, "AnonymousTag", "value", 0)}} + + val writeRequests: WriteRequests = + WriteRequests( + requests = listOf( + WriteRequest( + attributePath = AttributePath( + endpointId, + clusterId = CLUSTER_ID, + attributeId = ATTRIBUTE_ID + ), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } {% endif %} -{%- if attribute.is_subscribable %} - suspend fun subscribe{{ attribute.definition.name | upfirst }}Attribute( - minInterval: Int, - maxInterval: Int - ): {{interfaceName}} { - // Implementation needs to be added here - } -{% endif -%} {%- endfor %} companion object { + private val logger = Logger.getLogger({{cluster.name}}Cluster::class.java.name) const val CLUSTER_ID: UInt = {{cluster.code}}u } } diff --git a/scripts/py_matter_idl/matter_idl/generators/kotlin/__init__.py b/scripts/py_matter_idl/matter_idl/generators/kotlin/__init__.py index b671532df6682e..7f770783ae37b0 100644 --- a/scripts/py_matter_idl/matter_idl/generators/kotlin/__init__.py +++ b/scripts/py_matter_idl/matter_idl/generators/kotlin/__init__.py @@ -65,9 +65,9 @@ def _UnderlyingType(field: Field, context: TypeLookupContext) -> Optional[str]: if isinstance(actual, BasicString): if actual.is_binary: - return 'OctetString' + return 'ByteArray' else: - return 'CharString' + return 'String' elif isinstance(actual, BasicInteger): if actual.is_signed: return "Int{}s".format(actual.power_of_two_bits) @@ -350,6 +350,11 @@ def __init__(self, context: TypeLookupContext, data_type: DataType, attrs: Set[E self.data_type = data_type self.attrs = attrs + @property + def is_basic_type(self): + """Returns True if this type is a basic type in Kotlin""" + return self.kotlin_type != "Any" + @property def is_nullable(self): return EncodableValueAttr.NULLABLE in self.attrs @@ -452,15 +457,23 @@ def kotlin_type(self): else: return "String" elif isinstance(t, IdlEnumType): - if t.base_type.byte_count >= 3: - return "ULong" - else: + if t.base_type.byte_count <= 1: + return "UByte" + elif t.base_type.byte_count <= 2: + return "UShort" + elif t.base_type.byte_count <= 4: return "UInt" - elif isinstance(t, IdlBitmapType): - if t.base_type.byte_count >= 3: - return "ULong" else: + return "ULong" + elif isinstance(t, IdlBitmapType): + if t.base_type.byte_count <= 1: + return "UByte" + elif t.base_type.byte_count <= 2: + return "UShort" + elif t.base_type.byte_count <= 4: return "UInt" + else: + return "ULong" else: return "Any" diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 31116c55a79d6c..114d82e8f7413f 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -377,6 +377,7 @@ kotlin_library("kotlin_matter_controller") { sources += matter_structs_sources sources += matter_eventstructs_sources + sources += matter_clusters_sources if (matter_enable_java_compilation) { deps += [ diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccessControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccessControlCluster.kt index 78ee6725bb7646..28d3f95ef13b74 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccessControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccessControlCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class AccessControlCluster( private val controller: MatterController, @@ -37,144 +44,496 @@ class AccessControlCluster( class AttributeListAttribute(val value: List) suspend fun readAclAttribute(): AclAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readAclAttributeWithFabricFilter(isFabricFiltered: Boolean): AclAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acl attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessControlEntryStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return AclAttribute(decodedValue) } suspend fun writeAclAttribute( value: List, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } - } - - suspend fun subscribeAclAttribute(minInterval: Int, maxInterval: Int): AclAttribute { - // Implementation needs to be added here } suspend fun readExtensionAttribute(): ExtensionAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readExtensionAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): ExtensionAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Extension attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessControlExtensionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ExtensionAttribute(decodedValue) } suspend fun writeExtensionAttribute( value: List, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 1u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } - } - - suspend fun subscribeExtensionAttribute(minInterval: Int, maxInterval: Int): ExtensionAttribute { - // Implementation needs to be added here } suspend fun readSubjectsPerAccessControlEntryAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeSubjectsPerAccessControlEntryAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Subjectsperaccesscontrolentry attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readTargetsPerAccessControlEntryAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Targetsperaccesscontrolentry attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeTargetsPerAccessControlEntryAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + return decodedValue } suspend fun readAccessControlEntriesPerFabricAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAccessControlEntriesPerFabricAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Accesscontrolentriesperfabric attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(AccessControlCluster::class.java.name) const val CLUSTER_ID: UInt = 31u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccountLoginCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccountLoginCluster.kt index e11860c0ea53d2..3c2d77f7497cdc 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccountLoginCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AccountLoginCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class AccountLoginCluster( private val controller: MatterController, @@ -38,9 +47,49 @@ class AccountLoginCluster( tempAccountIdentifier: String, timedInvokeTimeoutMs: Int ): GetSetupPINResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TEMP_ACCOUNT_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TEMP_ACCOUNT_IDENTIFIER_REQ), tempAccountIdentifier) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_SETUP_P_I_N: Int = 0 + var setupPIN_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_SETUP_P_I_N)) { + setupPIN_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (setupPIN_decoded == null) { + throw IllegalStateException("setupPIN not found in TLV") + } + + tlvReader.exitContainer() + + return GetSetupPINResponse(setupPIN_decoded) } suspend fun login( @@ -49,75 +98,271 @@ class AccountLoginCluster( node: ULong?, timedInvokeTimeoutMs: Int ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TEMP_ACCOUNT_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TEMP_ACCOUNT_IDENTIFIER_REQ), tempAccountIdentifier) + + val TAG_SETUP_P_I_N_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SETUP_P_I_N_REQ), setupPIN) + + val TAG_NODE_REQ: Int = 2 + node?.let { tlvWriter.put(ContextSpecificTag(TAG_NODE_REQ), node) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun logout(node: ULong?, timedInvokeTimeoutMs: Int) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NODE_REQ: Int = 0 + node?.let { tlvWriter.put(ContextSpecificTag(TAG_NODE_REQ), node) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(AccountLoginCluster::class.java.name) const val CLUSTER_ID: UInt = 1294u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActionsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActionsCluster.kt index 264bde16fae360..176c2708d1a725 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActionsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActionsCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ActionsCluster(private val controller: MatterController, private val endpointId: UShort) { class ActionListAttribute(val value: List) @@ -34,13 +43,29 @@ class ActionsCluster(private val controller: MatterController, private val endpo class AttributeListAttribute(val value: List) suspend fun instantAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun instantActionWithTransition( @@ -49,23 +74,58 @@ class ActionsCluster(private val controller: MatterController, private val endpo transitionTime: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun startAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun startActionWithDuration( @@ -74,33 +134,84 @@ class ActionsCluster(private val controller: MatterController, private val endpo duration: UInt, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + + val TAG_DURATION_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stopAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun pauseAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun pauseActionWithDuration( @@ -109,33 +220,84 @@ class ActionsCluster(private val controller: MatterController, private val endpo duration: UInt, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + + val TAG_DURATION_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun resumeAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enableAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enableActionWithDuration( @@ -144,23 +306,58 @@ class ActionsCluster(private val controller: MatterController, private val endpo duration: UInt, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + + val TAG_DURATION_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun disableAction(actionID: UShort, invokeID: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 10L + val commandId: UInt = 10u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun disableActionWithDuration( @@ -169,103 +366,362 @@ class ActionsCluster(private val controller: MatterController, private val endpo duration: UInt, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 11L + val commandId: UInt = 11u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ACTION_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_I_D_REQ), actionID) + + val TAG_INVOKE_I_D_REQ: Int = 1 + invokeID?.let { tlvWriter.put(ContextSpecificTag(TAG_INVOKE_I_D_REQ), invokeID) } + + val TAG_DURATION_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readActionListAttribute(): ActionListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeActionListAttribute( - minInterval: Int, - maxInterval: Int - ): ActionListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Actionlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ActionsClusterActionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return ActionListAttribute(decodedValue) } suspend fun readEndpointListsAttribute(): EndpointListsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeEndpointListsAttribute( - minInterval: Int, - maxInterval: Int - ): EndpointListsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readSetupURLAttribute(): CharString { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Endpointlists attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ActionsClusterEndpointListStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return EndpointListsAttribute(decodedValue) } - suspend fun subscribeSetupURLAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readSetupURLAttribute(): String? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Setupurl attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ActionsCluster::class.java.name) const val CLUSTER_ID: UInt = 37u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActivatedCarbonFilterMonitoringCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActivatedCarbonFilterMonitoringCluster.kt index 9b128e71667096..2467100060ef22 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActivatedCarbonFilterMonitoringCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ActivatedCarbonFilterMonitoringCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ActivatedCarbonFilterMonitoringCluster( private val controller: MatterController, @@ -39,135 +47,510 @@ class ActivatedCarbonFilterMonitoringCluster( class AttributeListAttribute(val value: List) suspend fun resetCondition(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun readConditionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun readConditionAttribute(): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeConditionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readDegradationDirectionAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Condition attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeDegradationDirectionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readDegradationDirectionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Degradationdirection attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readChangeIndicationAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeChangeIndicationAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Changeindication attribute not found in response" } - suspend fun readInPlaceIndicatorAttribute(): Boolean { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeInPlaceIndicatorAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readInPlaceIndicatorAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Inplaceindicator attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readLastChangedTimeAttribute(): LastChangedTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun writeLastChangedTimeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lastchangedtime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LastChangedTimeAttribute(decodedValue) } - suspend fun subscribeLastChangedTimeAttribute( - minInterval: Int, - maxInterval: Int - ): LastChangedTimeAttribute { - // Implementation needs to be added here + suspend fun writeLastChangedTimeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readReplacementProductListAttribute(): ReplacementProductListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeReplacementProductListAttribute( - minInterval: Int, - maxInterval: Int - ): ReplacementProductListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Replacementproductlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.fromTlv( + AnonymousTag, + tlvReader + ) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ReplacementProductListAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ActivatedCarbonFilterMonitoringCluster::class.java.name) const val CLUSTER_ID: UInt = 114u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AdministratorCommissioningCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AdministratorCommissioningCluster.kt index fa3698f95ac7e6..8fe66e1557990c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AdministratorCommissioningCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AdministratorCommissioningCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class AdministratorCommissioningCluster( private val controller: MatterController, @@ -44,114 +53,404 @@ class AdministratorCommissioningCluster( salt: ByteArray, timedInvokeTimeoutMs: Int ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COMMISSIONING_TIMEOUT_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_COMMISSIONING_TIMEOUT_REQ), commissioningTimeout) + + val TAG_P_A_K_E_PASSCODE_VERIFIER_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_P_A_K_E_PASSCODE_VERIFIER_REQ), PAKEPasscodeVerifier) + + val TAG_DISCRIMINATOR_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DISCRIMINATOR_REQ), discriminator) + + val TAG_ITERATIONS_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_ITERATIONS_REQ), iterations) + + val TAG_SALT_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_SALT_REQ), salt) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun openBasicCommissioningWindow( commissioningTimeout: UShort, timedInvokeTimeoutMs: Int ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COMMISSIONING_TIMEOUT_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_COMMISSIONING_TIMEOUT_REQ), commissioningTimeout) + tlvWriter.endStructure() - // Implementation needs to be added here + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun revokeCommissioning(timedInvokeTimeoutMs: Int) { - val commandId = 2L - - // Implementation needs to be added here + val commandId: UInt = 2u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readWindowStatusAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeWindowStatusAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Windowstatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readAdminFabricIndexAttribute(): AdminFabricIndexAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAdminFabricIndexAttribute( - minInterval: Int, - maxInterval: Int - ): AdminFabricIndexAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Adminfabricindex attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return AdminFabricIndexAttribute(decodedValue) } suspend fun readAdminVendorIdAttribute(): AdminVendorIdAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAdminVendorIdAttribute( - minInterval: Int, - maxInterval: Int - ): AdminVendorIdAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Adminvendorid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return AdminVendorIdAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(AdministratorCommissioningCluster::class.java.name) const val CLUSTER_ID: UInt = 60u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AirQualityCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AirQualityCluster.kt index 6355856efbd286..206b757a37e2eb 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AirQualityCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AirQualityCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class AirQualityCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -30,71 +35,252 @@ class AirQualityCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun readAirQualityAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Airquality attribute not found in response" } - suspend fun subscribeAirQualityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(AirQualityCluster::class.java.name) const val CLUSTER_ID: UInt = 91u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationBasicCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationBasicCluster.kt index 58b400775a3fea..8a83da648cde09 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationBasicCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationBasicCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class ApplicationBasicCluster( private val controller: MatterController, @@ -36,134 +41,493 @@ class ApplicationBasicCluster( class AttributeListAttribute(val value: List) - suspend fun readVendorNameAttribute(): CharString { - // Implementation needs to be added here - } + suspend fun readVendorNameAttribute(): String? { + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeVendorNameAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readVendorIDAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeVendorIDAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorname attribute not found in response" } - suspend fun readApplicationNameAttribute(): CharString { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeApplicationNameAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readVendorIDAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readProductIDAttribute(): UShort { - // Implementation needs to be added here + suspend fun readApplicationNameAttribute(): String { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Applicationname attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } - suspend fun subscribeProductIDAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readProductIDAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readApplicationAttribute(): ApplicationAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeApplicationAttribute( - minInterval: Int, - maxInterval: Int - ): ApplicationAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Application attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ApplicationBasicClusterApplicationStruct = + ApplicationBasicClusterApplicationStruct.fromTlv(AnonymousTag, tlvReader) + + return ApplicationAttribute(decodedValue) } suspend fun readStatusAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeStatusAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readApplicationVersionAttribute(): CharString { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Status attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeApplicationVersionAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readApplicationVersionAttribute(): String { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Applicationversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun readAllowedVendorListAttribute(): AllowedVendorListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Allowedvendorlist attribute not found in response" } - suspend fun subscribeAllowedVendorListAttribute( - minInterval: Int, - maxInterval: Int - ): AllowedVendorListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AllowedVendorListAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ApplicationBasicCluster::class.java.name) const val CLUSTER_ID: UInt = 1293u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt index cd1fb69aa46af3..3393c6db7ffa49 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ApplicationLauncherCluster( private val controller: MatterController, private val endpointId: UShort ) { - class LauncherResponse(val status: UInt, val data: ByteArray?) + class LauncherResponse(val status: UByte, val data: ByteArray?) class CatalogListAttribute(val value: List?) @@ -43,121 +52,505 @@ class ApplicationLauncherCluster( data: ByteArray?, timedInvokeTimeoutMs: Int? = null ): LauncherResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_APPLICATION_REQ: Int = 0 + application?.let { application.toTlv(ContextSpecificTag(TAG_APPLICATION_REQ), tlvWriter) } + + val TAG_DATA_REQ: Int = 1 + data?.let { tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return LauncherResponse(status_decoded, data_decoded) } suspend fun stopApp( application: ApplicationLauncherClusterApplicationStruct?, timedInvokeTimeoutMs: Int? = null ): LauncherResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_APPLICATION_REQ: Int = 0 + application?.let { application.toTlv(ContextSpecificTag(TAG_APPLICATION_REQ), tlvWriter) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return LauncherResponse(status_decoded, data_decoded) } suspend fun hideApp( application: ApplicationLauncherClusterApplicationStruct?, timedInvokeTimeoutMs: Int? = null ): LauncherResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_APPLICATION_REQ: Int = 0 + application?.let { application.toTlv(ContextSpecificTag(TAG_APPLICATION_REQ), tlvWriter) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return LauncherResponse(status_decoded, data_decoded) } suspend fun readCatalogListAttribute(): CatalogListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeCatalogListAttribute( - minInterval: Int, - maxInterval: Int - ): CatalogListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Cataloglist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return CatalogListAttribute(decodedValue) } suspend fun readCurrentAppAttribute(): CurrentAppAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentAppAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentAppAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentapp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ApplicationLauncherClusterApplicationEPStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + ApplicationLauncherClusterApplicationEPStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentAppAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ApplicationLauncherCluster::class.java.name) const val CLUSTER_ID: UInt = 1292u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AudioOutputCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AudioOutputCluster.kt index e90ee1bd52ce00..7313b92c20659e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AudioOutputCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/AudioOutputCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class AudioOutputCluster(private val controller: MatterController, private val endpointId: UShort) { class OutputListAttribute(val value: List) @@ -32,102 +41,339 @@ class AudioOutputCluster(private val controller: MatterController, private val e class AttributeListAttribute(val value: List) suspend fun selectOutput(index: UByte, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_INDEX_REQ), index) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun renameOutput(index: UByte, name: String, timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_INDEX_REQ), index) + + val TAG_NAME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_NAME_REQ), name) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readOutputListAttribute(): OutputListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeOutputListAttribute( - minInterval: Int, - maxInterval: Int - ): OutputListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Outputlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(AudioOutputClusterOutputInfoStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return OutputListAttribute(decodedValue) } suspend fun readCurrentOutputAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeCurrentOutputAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentoutput attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(AudioOutputCluster::class.java.name) const val CLUSTER_ID: UInt = 1291u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BallastConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BallastConfigurationCluster.kt index c3a9d6c78807eb..49eb761bbabdf1 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BallastConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BallastConfigurationCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BallastConfigurationCluster( private val controller: MatterController, @@ -43,273 +50,1148 @@ class BallastConfigurationCluster( class AttributeListAttribute(val value: List) suspend fun readPhysicalMinLevelAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Physicalminlevel attribute not found in response" } - suspend fun subscribePhysicalMinLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readPhysicalMaxLevelAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribePhysicalMaxLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readBallastStatusAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Physicalmaxlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeBallastStatusAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readBallastStatusAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ballaststatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readMinLevelAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16u - suspend fun writeMinLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeMinLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeMinLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readMaxLevelAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 17u - suspend fun writeMaxLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeMaxLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeMaxLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 17u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readIntrinsicBallastFactorAttribute(): IntrinsicBallastFactorAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 20u - suspend fun writeIntrinsicBallastFactorAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Intrinsicballastfactor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return IntrinsicBallastFactorAttribute(decodedValue) } - suspend fun subscribeIntrinsicBallastFactorAttribute( - minInterval: Int, - maxInterval: Int - ): IntrinsicBallastFactorAttribute { - // Implementation needs to be added here + suspend fun writeIntrinsicBallastFactorAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 20u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBallastFactorAdjustmentAttribute(): BallastFactorAdjustmentAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 21u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ballastfactoradjustment attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BallastFactorAdjustmentAttribute(decodedValue) } suspend fun writeBallastFactorAdjustmentAttribute( value: UByte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val ATTRIBUTE_ID: UInt = 21u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) - suspend fun subscribeBallastFactorAdjustmentAttribute( - minInterval: Int, - maxInterval: Int - ): BallastFactorAdjustmentAttribute { - // Implementation needs to be added here + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readLampQuantityAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 32u - suspend fun subscribeLampQuantityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lampquantity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readLampTypeAttribute(): CharString { - // Implementation needs to be added here + suspend fun readLampTypeAttribute(): String? { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lamptype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeLampTypeAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 48u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeLampTypeAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readLampManufacturerAttribute(): String? { + val ATTRIBUTE_ID: UInt = 49u - suspend fun readLampManufacturerAttribute(): CharString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeLampManufacturerAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lampmanufacturer attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLampManufacturerAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun writeLampManufacturerAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 49u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readLampRatedHoursAttribute(): LampRatedHoursAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 50u - suspend fun writeLampRatedHoursAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lampratedhours attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LampRatedHoursAttribute(decodedValue) } - suspend fun subscribeLampRatedHoursAttribute( - minInterval: Int, - maxInterval: Int - ): LampRatedHoursAttribute { - // Implementation needs to be added here + suspend fun writeLampRatedHoursAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 50u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readLampBurnHoursAttribute(): LampBurnHoursAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 51u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lampburnhours attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LampBurnHoursAttribute(decodedValue) } suspend fun writeLampBurnHoursAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 51u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeLampBurnHoursAttribute( - minInterval: Int, - maxInterval: Int - ): LampBurnHoursAttribute { - // Implementation needs to be added here - } + suspend fun readLampAlarmModeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 52u - suspend fun readLampAlarmModeAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeLampAlarmModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lampalarmmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLampAlarmModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeLampAlarmModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 52u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readLampBurnHoursTripPointAttribute(): LampBurnHoursTripPointAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 53u - suspend fun writeLampBurnHoursTripPointAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lampburnhourstrippoint attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LampBurnHoursTripPointAttribute(decodedValue) } - suspend fun subscribeLampBurnHoursTripPointAttribute( - minInterval: Int, - maxInterval: Int - ): LampBurnHoursTripPointAttribute { - // Implementation needs to be added here + suspend fun writeLampBurnHoursTripPointAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 53u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BallastConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 769u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BarrierControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BarrierControlCluster.kt index e3446f20394a8e..e1376cd307d300 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BarrierControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BarrierControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BarrierControlCluster( private val controller: MatterController, @@ -33,223 +42,862 @@ class BarrierControlCluster( class AttributeListAttribute(val value: List) suspend fun barrierControlGoToPercent(percentOpen: UByte, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_PERCENT_OPEN_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_PERCENT_OPEN_REQ), percentOpen) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun barrierControlStop(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readBarrierMovingStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeBarrierMovingStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barriermovingstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readBarrierSafetyStatusAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeBarrierSafetyStatusAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barriersafetystatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readBarrierCapabilitiesAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeBarrierCapabilitiesAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barriercapabilities attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readBarrierOpenEventsAttribute(): UShort { - // Implementation needs to be added here + suspend fun readBarrierOpenEventsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barrieropenevents attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeBarrierOpenEventsAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeBarrierOpenEventsAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readBarrierCloseEventsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readBarrierCloseEventsAttribute(): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barriercloseevents attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeBarrierCloseEventsAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeBarrierCloseEventsAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readBarrierCommandOpenEventsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readBarrierCommandOpenEventsAttribute(): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barriercommandopenevents attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeBarrierCommandOpenEventsAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 6u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeBarrierCommandOpenEventsAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readBarrierCommandCloseEventsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readBarrierCommandCloseEventsAttribute(): UShort { - // Implementation needs to be added here + requireNotNull(attributeData) { "Barriercommandcloseevents attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeBarrierCommandCloseEventsAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 7u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeBarrierCommandCloseEventsAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readBarrierOpenPeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readBarrierOpenPeriodAttribute(): UShort { - // Implementation needs to be added here + requireNotNull(attributeData) { "Barrieropenperiod attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeBarrierOpenPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 8u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeBarrierOpenPeriodAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readBarrierClosePeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 9u - suspend fun readBarrierClosePeriodAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeBarrierClosePeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barriercloseperiod attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBarrierClosePeriodAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun writeBarrierClosePeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 9u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBarrierPositionAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeBarrierPositionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Barrierposition attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BarrierControlCluster::class.java.name) const val CLUSTER_ID: UInt = 259u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BasicInformationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BasicInformationCluster.kt index 9cfb4657ad3cc0..40903375df1efb 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BasicInformationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BasicInformationCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BasicInformationCluster( private val controller: MatterController, @@ -37,293 +45,1126 @@ class BasicInformationCluster( class AttributeListAttribute(val value: List) suspend fun mfgSpecificPing(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readDataModelRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeDataModelRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readVendorNameAttribute(): CharString { - // Implementation needs to be added here + requireNotNull(attributeData) { "Datamodelrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } - suspend fun subscribeVendorNameAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readVendorNameAttribute(): String { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorname attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun readVendorIDAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeVendorIDAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readProductNameAttribute(): CharString { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } - suspend fun subscribeProductNameAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readProductNameAttribute(): String { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productname attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun readProductIDAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeProductIDAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } - suspend fun readNodeLabelAttribute(): CharString { - // Implementation needs to be added here + suspend fun readNodeLabelAttribute(): String { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nodelabel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun writeNodeLabelAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNodeLabelAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readLocationAttribute(): String { + val ATTRIBUTE_ID: UInt = 6u - suspend fun readLocationAttribute(): CharString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeLocationAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Location attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } - suspend fun subscribeLocationAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun writeLocationAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 6u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readHardwareVersionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeHardwareVersionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Hardwareversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun readHardwareVersionStringAttribute(): CharString { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeHardwareVersionStringAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here + suspend fun readHardwareVersionStringAttribute(): String { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Hardwareversionstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun readSoftwareVersionAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 9u - suspend fun subscribeSoftwareVersionAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readSoftwareVersionStringAttribute(): CharString { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeSoftwareVersionStringAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readManufacturingDateAttribute(): CharString { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeManufacturingDateAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readPartNumberAttribute(): CharString { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribePartNumberAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + requireNotNull(attributeData) { "Softwareversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } - suspend fun readProductURLAttribute(): CharString { - // Implementation needs to be added here + suspend fun readSoftwareVersionStringAttribute(): String { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Softwareversionstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } - suspend fun subscribeProductURLAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readManufacturingDateAttribute(): String? { + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Manufacturingdate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readProductLabelAttribute(): CharString { - // Implementation needs to be added here + suspend fun readPartNumberAttribute(): String? { + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Partnumber attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeProductLabelAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readProductURLAttribute(): String? { + val ATTRIBUTE_ID: UInt = 13u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Producturl attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readSerialNumberAttribute(): CharString { - // Implementation needs to be added here + suspend fun readProductLabelAttribute(): String? { + val ATTRIBUTE_ID: UInt = 14u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productlabel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeSerialNumberAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readSerialNumberAttribute(): String? { + val ATTRIBUTE_ID: UInt = 15u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Serialnumber attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLocalConfigDisabledAttribute(): Boolean { - // Implementation needs to be added here + suspend fun readLocalConfigDisabledAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Localconfigdisabled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeLocalConfigDisabledAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeLocalConfigDisabledAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + suspend fun readReachableAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 17u - suspend fun readReachableAttribute(): Boolean { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeReachableAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reachable attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } - suspend fun readUniqueIDAttribute(): CharString { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeUniqueIDAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readUniqueIDAttribute(): String? { + val ATTRIBUTE_ID: UInt = 18u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uniqueid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readCapabilityMinimaAttribute(): CapabilityMinimaAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 19u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Capabilityminima attribute not found in response" } - suspend fun subscribeCapabilityMinimaAttribute( - minInterval: Int, - maxInterval: Int - ): CapabilityMinimaAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: BasicInformationClusterCapabilityMinimaStruct = + BasicInformationClusterCapabilityMinimaStruct.fromTlv(AnonymousTag, tlvReader) + + return CapabilityMinimaAttribute(decodedValue) } suspend fun readProductAppearanceAttribute(): ProductAppearanceAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 20u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeProductAppearanceAttribute( - minInterval: Int, - maxInterval: Int - ): ProductAppearanceAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Productappearance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: BasicInformationClusterProductAppearanceStruct? = + if (tlvReader.isNextTag(AnonymousTag)) { + BasicInformationClusterProductAppearanceStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + + return ProductAppearanceAttribute(decodedValue) } suspend fun readSpecificationVersionAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 21u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeSpecificationVersionAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Specificationversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readMaxPathsPerInvokeAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMaxPathsPerInvokeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxpathsperinvoke attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BasicInformationCluster::class.java.name) const val CLUSTER_ID: UInt = 40u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BinaryInputBasicCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BinaryInputBasicCluster.kt index a8da4754e7748f..a5745f50c40845 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BinaryInputBasicCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BinaryInputBasicCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BinaryInputBasicCluster( private val controller: MatterController, @@ -32,184 +39,783 @@ class BinaryInputBasicCluster( class AttributeListAttribute(val value: List) - suspend fun readActiveTextAttribute(): CharString { - // Implementation needs to be added here + suspend fun readActiveTextAttribute(): String? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activetext attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeActiveTextAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeActiveTextAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readDescriptionAttribute(): String? { + val ATTRIBUTE_ID: UInt = 28u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Description attribute not found in response" } - suspend fun readDescriptionAttribute(): CharString { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeDescriptionAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 28u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeDescriptionAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readInactiveTextAttribute(): String? { + val ATTRIBUTE_ID: UInt = 46u - suspend fun readInactiveTextAttribute(): CharString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeInactiveTextAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Inactivetext attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeInactiveTextAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun writeInactiveTextAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 46u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOutOfServiceAttribute(): Boolean { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 81u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Outofservice attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun writeOutOfServiceAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 81u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeOutOfServiceAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + suspend fun readPolarityAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 84u - suspend fun readPolarityAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePolarityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Polarity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readPresentValueAttribute(): Boolean { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 85u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Presentvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun writePresentValueAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 85u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribePresentValueAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + suspend fun readReliabilityAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 103u - suspend fun readReliabilityAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeReliabilityAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeReliabilityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reliability attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeReliabilityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 103u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readStatusFlagsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 111u - suspend fun subscribeStatusFlagsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readApplicationTypeAttribute(): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Statusflags attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeApplicationTypeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readApplicationTypeAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 256u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Applicationtype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BinaryInputBasicCluster::class.java.name) const val CLUSTER_ID: UInt = 15u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BindingCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BindingCluster.kt index 824522c0a95f7d..bcfbfdfd7eef29 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BindingCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BindingCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BindingCluster(private val controller: MatterController, private val endpointId: UShort) { class BindingAttribute(val value: List) @@ -32,86 +39,308 @@ class BindingCluster(private val controller: MatterController, private val endpo class AttributeListAttribute(val value: List) suspend fun readBindingAttribute(): BindingAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Binding attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(BindingClusterTargetStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } - suspend fun readBindingAttributeWithFabricFilter(isFabricFiltered: Boolean): BindingAttribute { - // Implementation needs to be added here + return BindingAttribute(decodedValue) } suspend fun writeBindingAttribute( value: List, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } - } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } - suspend fun subscribeBindingAttribute(minInterval: Int, maxInterval: Int): BindingAttribute { - // Implementation needs to be added here + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BindingCluster::class.java.name) const val CLUSTER_ID: UInt = 30u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanSensorConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanSensorConfigurationCluster.kt index 068aa709815206..9894a459f38722 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanSensorConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanSensorConfigurationCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BooleanSensorConfigurationCluster( private val controller: MatterController, @@ -32,122 +41,473 @@ class BooleanSensorConfigurationCluster( class AttributeListAttribute(val value: List) - suspend fun suppressRequest(alarmsToSuppress: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + suspend fun suppressRequest(alarmsToSuppress: UByte, timedInvokeTimeoutMs: Int? = null) { + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ALARMS_TO_SUPPRESS_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ALARMS_TO_SUPPRESS_REQ), alarmsToSuppress) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) - suspend fun readSensitivityLevelAttribute(): UByte { - // Implementation needs to be added here + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun writeSensitivityLevelAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readSensitivityLevelAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeSensitivityLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readAlarmsActiveAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sensitivitylevel attribute not found in response" } - suspend fun subscribeAlarmsActiveAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readAlarmsSuppressedAttribute(): UByte { - // Implementation needs to be added here + suspend fun writeSensitivityLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeAlarmsSuppressedAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAlarmsActiveAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Alarmsactive attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readAlarmsEnabledAttribute(): UByte { - // Implementation needs to be added here + suspend fun readAlarmsSuppressedAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Alarmssuppressed attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeAlarmsEnabledAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readAlarmsEnabledAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Alarmsenabled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeAlarmsEnabledAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeAlarmsEnabledAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BooleanSensorConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 128u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanStateCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanStateCluster.kt index f8b8fa301c2ee1..4c53219de45572 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanStateCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BooleanStateCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class BooleanStateCluster( private val controller: MatterController, @@ -33,71 +38,252 @@ class BooleanStateCluster( class AttributeListAttribute(val value: List) suspend fun readStateValueAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Statevalue attribute not found in response" } - suspend fun subscribeStateValueAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BooleanStateCluster::class.java.name) const val CLUSTER_ID: UInt = 69u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt index 6f16251fb84c31..9f1e8dc4aeb7e4 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class BridgedDeviceBasicInformationCluster( private val controller: MatterController, @@ -36,209 +43,835 @@ class BridgedDeviceBasicInformationCluster( class AttributeListAttribute(val value: List) - suspend fun readVendorNameAttribute(): CharString { - // Implementation needs to be added here - } + suspend fun readVendorNameAttribute(): String? { + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeVendorNameAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readVendorIDAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeVendorIDAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorname attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readProductNameAttribute(): CharString { - // Implementation needs to be added here + suspend fun readVendorIDAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeProductNameAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readProductNameAttribute(): String? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productname attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readNodeLabelAttribute(): CharString { - // Implementation needs to be added here + suspend fun readNodeLabelAttribute(): String? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nodelabel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeNodeLabelAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNodeLabelAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readHardwareVersionAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 7u - suspend fun readHardwareVersionAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeHardwareVersionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readHardwareVersionStringAttribute(): CharString { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeHardwareVersionStringAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readSoftwareVersionAttribute(): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeSoftwareVersionAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readSoftwareVersionStringAttribute(): CharString { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Hardwareversion attribute not found in response" } - suspend fun subscribeSoftwareVersionStringAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readManufacturingDateAttribute(): CharString { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeManufacturingDateAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readHardwareVersionStringAttribute(): String? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Hardwareversionstring attribute not found in response" } - suspend fun readPartNumberAttribute(): CharString { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribePartNumberAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readSoftwareVersionAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Softwareversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readProductURLAttribute(): CharString { - // Implementation needs to be added here + suspend fun readSoftwareVersionStringAttribute(): String? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Softwareversionstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeProductURLAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readManufacturingDateAttribute(): String? { + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Manufacturingdate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readProductLabelAttribute(): CharString { - // Implementation needs to be added here + suspend fun readPartNumberAttribute(): String? { + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Partnumber attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeProductLabelAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readProductURLAttribute(): String? { + val ATTRIBUTE_ID: UInt = 13u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Producturl attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readSerialNumberAttribute(): CharString { - // Implementation needs to be added here + suspend fun readProductLabelAttribute(): String? { + val ATTRIBUTE_ID: UInt = 14u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productlabel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeSerialNumberAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readSerialNumberAttribute(): String? { + val ATTRIBUTE_ID: UInt = 15u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Serialnumber attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readReachableAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 17u - suspend fun subscribeReachableAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readUniqueIDAttribute(): CharString { - // Implementation needs to be added here + requireNotNull(attributeData) { "Reachable attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } - suspend fun subscribeUniqueIDAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readUniqueIDAttribute(): String? { + val ATTRIBUTE_ID: UInt = 18u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uniqueid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readProductAppearanceAttribute(): ProductAppearanceAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 20u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeProductAppearanceAttribute( - minInterval: Int, - maxInterval: Int - ): ProductAppearanceAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productappearance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: BridgedDeviceBasicInformationClusterProductAppearanceStruct? = + if (tlvReader.isNextTag(AnonymousTag)) { + BridgedDeviceBasicInformationClusterProductAppearanceStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + + return ProductAppearanceAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(BridgedDeviceBasicInformationCluster::class.java.name) const val CLUSTER_ID: UInt = 57u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonDioxideConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonDioxideConcentrationMeasurementCluster.kt index 9586beac02dbcc..c85c8ef14a14ae 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonDioxideConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonDioxideConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class CarbonDioxideConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,643 @@ class CarbonDioxideConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger(CarbonDioxideConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1037u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonMonoxideConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonMonoxideConcentrationMeasurementCluster.kt index fdb299760ce83a..9d3e2e18235efd 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonMonoxideConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/CarbonMonoxideConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class CarbonMonoxideConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,643 @@ class CarbonMonoxideConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger(CarbonMonoxideConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1036u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ChannelCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ChannelCluster.kt index 5396dd327550bd..fe007b68dfd299 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ChannelCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ChannelCluster.kt @@ -17,11 +17,20 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ChannelCluster(private val controller: MatterController, private val endpointId: UShort) { - class ChangeChannelResponse(val status: UInt, val data: String?) + class ChangeChannelResponse(val status: UByte, val data: String?) class ProgramGuideResponse( val channelPagingStruct: Short, @@ -46,13 +55,67 @@ class ChannelCluster(private val controller: MatterController, private val endpo match: String, timedInvokeTimeoutMs: Int? = null ): ChangeChannelResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MATCH_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MATCH_REQ), match) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeChannelResponse(status_decoded, data_decoded) } suspend fun changeChannelByNumber( @@ -60,23 +123,52 @@ class ChannelCluster(private val controller: MatterController, private val endpo minorNumber: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MAJOR_NUMBER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MAJOR_NUMBER_REQ), majorNumber) + + val TAG_MINOR_NUMBER_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_MINOR_NUMBER_REQ), minorNumber) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun skipChannel(count: Short, timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COUNT_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_COUNT_REQ), count) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getProgramGuide( @@ -84,18 +176,103 @@ class ChannelCluster(private val controller: MatterController, private val endpo endTime: UInt?, channelList: List?, pageToken: ChannelClusterPageTokenStruct?, - recordingFlag: ULong?, + recordingFlag: UInt?, externalIDList: List?, data: ByteArray?, timedInvokeTimeoutMs: Int? = null ): ProgramGuideResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_START_TIME_REQ: Int = 0 + startTime?.let { tlvWriter.put(ContextSpecificTag(TAG_START_TIME_REQ), startTime) } + + val TAG_END_TIME_REQ: Int = 1 + endTime?.let { tlvWriter.put(ContextSpecificTag(TAG_END_TIME_REQ), endTime) } + + val TAG_CHANNEL_LIST_REQ: Int = 2 + channelList?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_CHANNEL_LIST_REQ)) + for (item in channelList.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + } + + val TAG_PAGE_TOKEN_REQ: Int = 3 + pageToken?.let { pageToken.toTlv(ContextSpecificTag(TAG_PAGE_TOKEN_REQ), tlvWriter) } + + val TAG_RECORDING_FLAG_REQ: Int = 4 + recordingFlag?.let { tlvWriter.put(ContextSpecificTag(TAG_RECORDING_FLAG_REQ), recordingFlag) } + + val TAG_EXTERNAL_I_D_LIST_REQ: Int = 5 + externalIDList?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_EXTERNAL_I_D_LIST_REQ)) + for (item in externalIDList.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + } + + val TAG_DATA_REQ: Int = 6 + data?.let { tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_CHANNEL_PAGING_STRUCT: Int = 0 + var channelPagingStruct_decoded: Short? = null + + val TAG_PROGRAM_LIST: Int = 1 + var programList_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_CHANNEL_PAGING_STRUCT)) { + channelPagingStruct_decoded = tlvReader.getShort(tag) + } + + if (tag == ContextSpecificTag(TAG_PROGRAM_LIST)) { + programList_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(ChannelClusterProgramStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (channelPagingStruct_decoded == null) { + throw IllegalStateException("channelPagingStruct not found in TLV") } + + if (programList_decoded == null) { + throw IllegalStateException("programList not found in TLV") + } + + tlvReader.exitContainer() + + return ProgramGuideResponse(channelPagingStruct_decoded, programList_decoded) } suspend fun recordProgram( @@ -105,13 +282,39 @@ class ChannelCluster(private val controller: MatterController, private val endpo data: ByteArray, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_PROGRAM_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_PROGRAM_IDENTIFIER_REQ), programIdentifier) + + val TAG_SHOULD_RECORD_SERIES_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SHOULD_RECORD_SERIES_REQ), shouldRecordSeries) + + val TAG_EXTERNAL_I_D_LIST_REQ: Int = 2 + tlvWriter.startArray(ContextSpecificTag(TAG_EXTERNAL_I_D_LIST_REQ)) + for (item in externalIDList.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } + tlvWriter.endArray() + + val TAG_DATA_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun cancelRecordProgram( @@ -121,103 +324,381 @@ class ChannelCluster(private val controller: MatterController, private val endpo data: ByteArray, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_PROGRAM_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_PROGRAM_IDENTIFIER_REQ), programIdentifier) + + val TAG_SHOULD_RECORD_SERIES_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SHOULD_RECORD_SERIES_REQ), shouldRecordSeries) + + val TAG_EXTERNAL_I_D_LIST_REQ: Int = 2 + tlvWriter.startArray(ContextSpecificTag(TAG_EXTERNAL_I_D_LIST_REQ)) + for (item in externalIDList.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } + tlvWriter.endArray() + + val TAG_DATA_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readChannelListAttribute(): ChannelListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeChannelListAttribute( - minInterval: Int, - maxInterval: Int - ): ChannelListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Channellist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ChannelClusterChannelInfoStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ChannelListAttribute(decodedValue) } suspend fun readLineupAttribute(): LineupAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeLineupAttribute(minInterval: Int, maxInterval: Int): LineupAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lineup attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ChannelClusterLineupInfoStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + ChannelClusterLineupInfoStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LineupAttribute(decodedValue) } suspend fun readCurrentChannelAttribute(): CurrentChannelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeCurrentChannelAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentChannelAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentchannel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ChannelClusterChannelInfoStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + ChannelClusterChannelInfoStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentChannelAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ChannelCluster::class.java.name) const val CLUSTER_ID: UInt = 1284u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ColorControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ColorControlCluster.kt index 1f30a7e219f96f..00ae08a92a2f34 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ColorControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ColorControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ColorControlCluster( private val controller: MatterController, @@ -56,952 +65,3470 @@ class ColorControlCluster( suspend fun moveToHue( hue: UByte, - direction: UInt, + direction: UByte, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_HUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_HUE_REQ), hue) + + val TAG_DIRECTION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_DIRECTION_REQ), direction) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveHue( - moveMode: UInt, + moveMode: UByte, rate: UByte, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MOVE_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MOVE_MODE_REQ), moveMode) + + val TAG_RATE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RATE_REQ), rate) + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stepHue( - stepMode: UInt, + stepMode: UByte, stepSize: UByte, transitionTime: UByte, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_STEP_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_MODE_REQ), stepMode) + + val TAG_STEP_SIZE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_SIZE_REQ), stepSize) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveToSaturation( saturation: UByte, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_SATURATION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_SATURATION_REQ), saturation) + + val TAG_TRANSITION_TIME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveSaturation( - moveMode: UInt, + moveMode: UByte, rate: UByte, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MOVE_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MOVE_MODE_REQ), moveMode) + + val TAG_RATE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RATE_REQ), rate) + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stepSaturation( - stepMode: UInt, + stepMode: UByte, stepSize: UByte, transitionTime: UByte, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_STEP_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_MODE_REQ), stepMode) + + val TAG_STEP_SIZE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_SIZE_REQ), stepSize) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveToHueAndSaturation( hue: UByte, saturation: UByte, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_HUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_HUE_REQ), hue) + + val TAG_SATURATION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SATURATION_REQ), saturation) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveToColor( colorX: UShort, colorY: UShort, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COLOR_X_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_COLOR_X_REQ), colorX) + + val TAG_COLOR_Y_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_COLOR_Y_REQ), colorY) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveColor( rateX: Short, rateY: Short, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_RATE_X_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_RATE_X_REQ), rateX) + + val TAG_RATE_Y_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RATE_Y_REQ), rateY) + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stepColor( stepX: Short, stepY: Short, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_STEP_X_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_X_REQ), stepX) + + val TAG_STEP_Y_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_Y_REQ), stepY) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveToColorTemperature( colorTemperatureMireds: UShort, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 10L + val commandId: UInt = 10u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COLOR_TEMPERATURE_MIREDS_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_COLOR_TEMPERATURE_MIREDS_REQ), colorTemperatureMireds) + + val TAG_TRANSITION_TIME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enhancedMoveToHue( enhancedHue: UShort, - direction: UInt, + direction: UByte, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 64L + val commandId: UInt = 64u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ENHANCED_HUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ENHANCED_HUE_REQ), enhancedHue) + + val TAG_DIRECTION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_DIRECTION_REQ), direction) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enhancedMoveHue( - moveMode: UInt, + moveMode: UByte, rate: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 65L + val commandId: UInt = 65u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MOVE_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MOVE_MODE_REQ), moveMode) + + val TAG_RATE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RATE_REQ), rate) + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enhancedStepHue( - stepMode: UInt, + stepMode: UByte, stepSize: UShort, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 66L + val commandId: UInt = 66u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_STEP_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_MODE_REQ), stepMode) + + val TAG_STEP_SIZE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_SIZE_REQ), stepSize) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enhancedMoveToHueAndSaturation( enhancedHue: UShort, saturation: UByte, transitionTime: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 67L + val commandId: UInt = 67u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ENHANCED_HUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ENHANCED_HUE_REQ), enhancedHue) + + val TAG_SATURATION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SATURATION_REQ), saturation) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun colorLoopSet( - updateFlags: UInt, - action: UInt, - direction: UInt, + updateFlags: UByte, + action: UByte, + direction: UByte, time: UShort, startHue: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 68L + val commandId: UInt = 68u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_UPDATE_FLAGS_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_UPDATE_FLAGS_REQ), updateFlags) + + val TAG_ACTION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ACTION_REQ), action) + + val TAG_DIRECTION_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DIRECTION_REQ), direction) + + val TAG_TIME_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_TIME_REQ), time) + + val TAG_START_HUE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_START_HUE_REQ), startHue) + + val TAG_OPTIONS_MASK_REQ: Int = 5 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 6 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stopMoveStep( - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 71L + val commandId: UInt = 71u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPTIONS_MASK_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveColorTemperature( - moveMode: UInt, + moveMode: UByte, rate: UShort, colorTemperatureMinimumMireds: UShort, colorTemperatureMaximumMireds: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 75L + val commandId: UInt = 75u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MOVE_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MOVE_MODE_REQ), moveMode) + + val TAG_RATE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_RATE_REQ), rate) + + val TAG_COLOR_TEMPERATURE_MINIMUM_MIREDS_REQ: Int = 2 + tlvWriter.put( + ContextSpecificTag(TAG_COLOR_TEMPERATURE_MINIMUM_MIREDS_REQ), + colorTemperatureMinimumMireds + ) + + val TAG_COLOR_TEMPERATURE_MAXIMUM_MIREDS_REQ: Int = 3 + tlvWriter.put( + ContextSpecificTag(TAG_COLOR_TEMPERATURE_MAXIMUM_MIREDS_REQ), + colorTemperatureMaximumMireds + ) + + val TAG_OPTIONS_MASK_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 5 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stepColorTemperature( - stepMode: UInt, + stepMode: UByte, stepSize: UShort, transitionTime: UShort, colorTemperatureMinimumMireds: UShort, colorTemperatureMaximumMireds: UShort, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 76L + val commandId: UInt = 76u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - suspend fun readCurrentHueAttribute(): UByte { - // Implementation needs to be added here - } + val TAG_STEP_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_MODE_REQ), stepMode) - suspend fun subscribeCurrentHueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val TAG_STEP_SIZE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_SIZE_REQ), stepSize) - suspend fun readCurrentSaturationAttribute(): UByte { - // Implementation needs to be added here - } + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) - suspend fun subscribeCurrentSaturationAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val TAG_COLOR_TEMPERATURE_MINIMUM_MIREDS_REQ: Int = 3 + tlvWriter.put( + ContextSpecificTag(TAG_COLOR_TEMPERATURE_MINIMUM_MIREDS_REQ), + colorTemperatureMinimumMireds + ) - suspend fun readRemainingTimeAttribute(): UShort { - // Implementation needs to be added here - } + val TAG_COLOR_TEMPERATURE_MAXIMUM_MIREDS_REQ: Int = 4 + tlvWriter.put( + ContextSpecificTag(TAG_COLOR_TEMPERATURE_MAXIMUM_MIREDS_REQ), + colorTemperatureMaximumMireds + ) - suspend fun subscribeRemainingTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val TAG_OPTIONS_MASK_REQ: Int = 5 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) - suspend fun readCurrentXAttribute(): UShort { - // Implementation needs to be added here - } + val TAG_OPTIONS_OVERRIDE_REQ: Int = 6 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() - suspend fun subscribeCurrentXAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) - suspend fun readCurrentYAttribute(): UShort { - // Implementation needs to be added here + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun subscribeCurrentYAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readCurrentHueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 0u - suspend fun readDriftCompensationAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeDriftCompensationAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readCompensationTextAttribute(): CharString { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeCompensationTextAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readColorTemperatureMiredsAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeColorTemperatureMiredsAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readColorModeAttribute(): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Currenthue attribute not found in response" } - suspend fun subscribeColorModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun readOptionsAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun writeOptionsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readCurrentSaturationAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeOptionsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readNumberOfPrimariesAttribute(): NumberOfPrimariesAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeNumberOfPrimariesAttribute( - minInterval: Int, - maxInterval: Int - ): NumberOfPrimariesAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readPrimary1XAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePrimary1XAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readPrimary1YAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribePrimary1YAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Currentsaturation attribute not found in response" } - suspend fun readPrimary1IntensityAttribute(): Primary1IntensityAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun subscribePrimary1IntensityAttribute( - minInterval: Int, - maxInterval: Int - ): Primary1IntensityAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readPrimary2XAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readRemainingTimeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribePrimary2XAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPrimary2YAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePrimary2YAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readPrimary2IntensityAttribute(): Primary2IntensityAttribute { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePrimary2IntensityAttribute( - minInterval: Int, - maxInterval: Int - ): Primary2IntensityAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readPrimary3XAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribePrimary3XAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Remainingtime attribute not found in response" } - suspend fun readPrimary3YAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribePrimary3YAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readPrimary3IntensityAttribute(): Primary3IntensityAttribute { - // Implementation needs to be added here - } + suspend fun readCurrentXAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePrimary3IntensityAttribute( - minInterval: Int, - maxInterval: Int - ): Primary3IntensityAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPrimary4XAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePrimary4XAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readPrimary4YAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePrimary4YAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readPrimary4IntensityAttribute(): Primary4IntensityAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribePrimary4IntensityAttribute( - minInterval: Int, - maxInterval: Int - ): Primary4IntensityAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Currentx attribute not found in response" } - suspend fun readPrimary5XAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribePrimary5XAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readPrimary5YAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readCurrentYAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 4u - suspend fun subscribePrimary5YAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPrimary5IntensityAttribute(): Primary5IntensityAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePrimary5IntensityAttribute( - minInterval: Int, - maxInterval: Int - ): Primary5IntensityAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readPrimary6XAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePrimary6XAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readPrimary6YAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribePrimary6YAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Currenty attribute not found in response" } - suspend fun readPrimary6IntensityAttribute(): Primary6IntensityAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribePrimary6IntensityAttribute( - minInterval: Int, - maxInterval: Int - ): Primary6IntensityAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readWhitePointXAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readDriftCompensationAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 5u - suspend fun writeWhitePointXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeWhitePointXAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readWhitePointYAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeWhitePointYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeWhitePointYAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readColorPointRXAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeColorPointRXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Driftcompensation attribute not found in response" } - suspend fun subscribeColorPointRXAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun readColorPointRYAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeColorPointRYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readCompensationTextAttribute(): String? { + val ATTRIBUTE_ID: UInt = 6u - suspend fun subscribeColorPointRYAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readColorPointRIntensityAttribute(): ColorPointRIntensityAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeColorPointRIntensityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeColorPointRIntensityAttribute( - minInterval: Int, - maxInterval: Int - ): ColorPointRIntensityAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readColorPointGXAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeColorPointGXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Compensationtext attribute not found in response" } - suspend fun subscribeColorPointGXAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } - suspend fun readColorPointGYAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeColorPointGYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readColorTemperatureMiredsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeColorPointGYAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readColorPointGIntensityAttribute(): ColorPointGIntensityAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeColorPointGIntensityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeColorPointGIntensityAttribute( - minInterval: Int, - maxInterval: Int - ): ColorPointGIntensityAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readColorPointBXAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeColorPointBXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Colortemperaturemireds attribute not found in response" } - suspend fun subscribeColorPointBXAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readColorPointBYAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeColorPointBYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readColorModeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 8u - suspend fun subscribeColorPointBYAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colormode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun readOptionsAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 15u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Options attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeOptionsAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 15u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNumberOfPrimariesAttribute(): NumberOfPrimariesAttribute { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofprimaries attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NumberOfPrimariesAttribute(decodedValue) + } + + suspend fun readPrimary1XAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 17u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary1x attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary1YAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 18u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary1y attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary1IntensityAttribute(): Primary1IntensityAttribute { + val ATTRIBUTE_ID: UInt = 19u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary1intensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return Primary1IntensityAttribute(decodedValue) + } + + suspend fun readPrimary2XAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 21u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary2x attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary2YAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary2y attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary2IntensityAttribute(): Primary2IntensityAttribute { + val ATTRIBUTE_ID: UInt = 23u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary2intensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return Primary2IntensityAttribute(decodedValue) + } + + suspend fun readPrimary3XAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 25u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary3x attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary3YAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary3y attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary3IntensityAttribute(): Primary3IntensityAttribute { + val ATTRIBUTE_ID: UInt = 27u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary3intensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return Primary3IntensityAttribute(decodedValue) + } + + suspend fun readPrimary4XAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 32u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary4x attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary4YAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary4y attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary4IntensityAttribute(): Primary4IntensityAttribute { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary4intensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return Primary4IntensityAttribute(decodedValue) + } + + suspend fun readPrimary5XAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 36u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary5x attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary5YAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 37u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary5y attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary5IntensityAttribute(): Primary5IntensityAttribute { + val ATTRIBUTE_ID: UInt = 38u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary5intensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return Primary5IntensityAttribute(decodedValue) + } + + suspend fun readPrimary6XAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 40u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary6x attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorPointBIntensityAttribute(): ColorPointBIntensityAttribute { - // Implementation needs to be added here + suspend fun readPrimary6YAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 41u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary6y attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPrimary6IntensityAttribute(): Primary6IntensityAttribute { + val ATTRIBUTE_ID: UInt = 42u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Primary6intensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return Primary6IntensityAttribute(decodedValue) + } + + suspend fun readWhitePointXAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Whitepointx attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeWhitePointXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 48u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readWhitePointYAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Whitepointy attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeWhitePointYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 49u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readColorPointRXAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointrx attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeColorPointRXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 50u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readColorPointRYAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 51u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointry attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeColorPointRYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 51u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readColorPointRIntensityAttribute(): ColorPointRIntensityAttribute { + val ATTRIBUTE_ID: UInt = 52u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointrintensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ColorPointRIntensityAttribute(decodedValue) + } + + suspend fun writeColorPointRIntensityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 52u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readColorPointGXAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 54u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointgx attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeColorPointBIntensityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeColorPointGXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 54u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeColorPointBIntensityAttribute( - minInterval: Int, - maxInterval: Int - ): ColorPointBIntensityAttribute { - // Implementation needs to be added here - } + suspend fun readColorPointGYAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 55u - suspend fun readEnhancedCurrentHueAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointgy attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeEnhancedCurrentHueAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readEnhancedColorModeAttribute(): UByte { - // Implementation needs to be added here + suspend fun writeColorPointGYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 55u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeEnhancedColorModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readColorPointGIntensityAttribute(): ColorPointGIntensityAttribute { + val ATTRIBUTE_ID: UInt = 56u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointgintensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ColorPointGIntensityAttribute(decodedValue) } - suspend fun readColorLoopActiveAttribute(): UByte { - // Implementation needs to be added here + suspend fun writeColorPointGIntensityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 56u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeColorLoopActiveAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readColorPointBXAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 58u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointbx attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorLoopDirectionAttribute(): UByte { - // Implementation needs to be added here + suspend fun writeColorPointBXAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 58u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeColorLoopDirectionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readColorPointBYAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 59u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointby attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorLoopTimeAttribute(): UShort { - // Implementation needs to be added here + suspend fun writeColorPointBYAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 59u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeColorLoopTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readColorPointBIntensityAttribute(): ColorPointBIntensityAttribute { + val ATTRIBUTE_ID: UInt = 60u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorpointbintensity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ColorPointBIntensityAttribute(decodedValue) } - suspend fun readColorLoopStartEnhancedHueAttribute(): UShort { - // Implementation needs to be added here + suspend fun writeColorPointBIntensityAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 60u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeColorLoopStartEnhancedHueAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readEnhancedCurrentHueAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16384u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enhancedcurrenthue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorLoopStoredEnhancedHueAttribute(): UShort { - // Implementation needs to be added here + suspend fun readEnhancedColorModeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 16385u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enhancedcolormode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeColorLoopStoredEnhancedHueAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readColorLoopActiveAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 16386u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorloopactive attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorCapabilitiesAttribute(): UShort { - // Implementation needs to be added here + suspend fun readColorLoopDirectionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 16387u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorloopdirection attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeColorCapabilitiesAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readColorLoopTimeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16388u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorlooptime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorTempPhysicalMinMiredsAttribute(): UShort { - // Implementation needs to be added here + suspend fun readColorLoopStartEnhancedHueAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16389u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorloopstartenhancedhue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeColorTempPhysicalMinMiredsAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readColorLoopStoredEnhancedHueAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16390u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorloopstoredenhancedhue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readColorTempPhysicalMaxMiredsAttribute(): UShort { - // Implementation needs to be added here + suspend fun readColorCapabilitiesAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 16394u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colorcapabilities attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } - suspend fun subscribeColorTempPhysicalMaxMiredsAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readColorTempPhysicalMinMiredsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16395u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colortempphysicalminmireds attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readCoupleColorTempToLevelMinMiredsAttribute(): UShort { - // Implementation needs to be added here + suspend fun readColorTempPhysicalMaxMiredsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16396u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Colortempphysicalmaxmireds attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeCoupleColorTempToLevelMinMiredsAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readCoupleColorTempToLevelMinMiredsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16397u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Couplecolortemptolevelminmireds attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readStartUpColorTemperatureMiredsAttribute(): StartUpColorTemperatureMiredsAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16400u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Startupcolortemperaturemireds attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpColorTemperatureMiredsAttribute(decodedValue) } suspend fun writeStartUpColorTemperatureMiredsAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16400u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeStartUpColorTemperatureMiredsAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpColorTemperatureMiredsAttribute { - // Implementation needs to be added here - } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ColorControlCluster::class.java.name) const val CLUSTER_ID: UInt = 768u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentAppObserverCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentAppObserverCluster.kt index 8c7f94fb3b3d99..36945d64c4a47f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentAppObserverCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentAppObserverCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ContentAppObserverCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ContentAppMessageResponse(val status: UInt?, val data: String, val encodingHint: String) + class ContentAppMessageResponse(val status: UByte?, val data: String, val encodingHint: String) class GeneratedCommandListAttribute(val value: List) @@ -39,73 +48,299 @@ class ContentAppObserverCluster( encodingHint: String, timedInvokeTimeoutMs: Int? = null ): ContentAppMessageResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DATA_REQ: Int = 0 + data?.let { tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) } + + val TAG_ENCODING_HINT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ENCODING_HINT_REQ), encodingHint) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + val TAG_ENCODING_HINT: Int = 2 + var encodingHint_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = tlvReader.getString(tag) + } + + if (tag == ContextSpecificTag(TAG_ENCODING_HINT)) { + encodingHint_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (data_decoded == null) { + throw IllegalStateException("data not found in TLV") + } + + if (encodingHint_decoded == null) { + throw IllegalStateException("encodingHint not found in TLV") } + + tlvReader.exitContainer() + + return ContentAppMessageResponse(status_decoded, data_decoded, encodingHint_decoded) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ContentAppObserverCluster::class.java.name) const val CLUSTER_ID: UInt = 1296u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentControlCluster.kt index 16a9d6dfbfa009..e68bffe835fc12 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ContentControlCluster( private val controller: MatterController, @@ -39,242 +48,761 @@ class ContentControlCluster( class AttributeListAttribute(val value: List) suspend fun updatePIN(oldPIN: String?, newPIN: String, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OLD_P_I_N_REQ: Int = 0 + oldPIN?.let { tlvWriter.put(ContextSpecificTag(TAG_OLD_P_I_N_REQ), oldPIN) } + + val TAG_NEW_P_I_N_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_NEW_P_I_N_REQ), newPIN) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun resetPIN(timedInvokeTimeoutMs: Int? = null): ResetPINResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_P_I_N_CODE: Int = 0 + var PINCode_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_P_I_N_CODE)) { + PINCode_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (PINCode_decoded == null) { + throw IllegalStateException("PINCode not found in TLV") } + + tlvReader.exitContainer() + + return ResetPINResponse(PINCode_decoded) } suspend fun enable(timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun disable(timedInvokeTimeoutMs: Int? = null) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun addBonusTime(PINCode: String?, bonusTime: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_P_I_N_CODE_REQ: Int = 0 + PINCode?.let { tlvWriter.put(ContextSpecificTag(TAG_P_I_N_CODE_REQ), PINCode) } + + val TAG_BONUS_TIME_REQ: Int = 1 + bonusTime?.let { tlvWriter.put(ContextSpecificTag(TAG_BONUS_TIME_REQ), bonusTime) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setScreenDailyTime(screenTime: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_SCREEN_TIME_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_SCREEN_TIME_REQ), screenTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun blockUnratedContent(timedInvokeTimeoutMs: Int? = null) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun unblockUnratedContent(timedInvokeTimeoutMs: Int? = null) { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setOnDemandRatingThreshold(rating: String, timedInvokeTimeoutMs: Int? = null) { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_RATING_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_RATING_REQ), rating) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setScheduledContentRatingThreshold( rating: String, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 10L + val commandId: UInt = 10u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_RATING_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_RATING_REQ), rating) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readEnabledAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEnabledAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + requireNotNull(attributeData) { "Enabled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readOnDemandRatingsAttribute(): OnDemandRatingsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeOnDemandRatingsAttribute( - minInterval: Int, - maxInterval: Int - ): OnDemandRatingsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ondemandratings attribute not found in response" } - suspend fun readOnDemandRatingThresholdAttribute(): CharString { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ContentControlClusterRatingNameStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return OnDemandRatingsAttribute(decodedValue) } - suspend fun subscribeOnDemandRatingThresholdAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here + suspend fun readOnDemandRatingThresholdAttribute(): String? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ondemandratingthreshold attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readScheduledContentRatingsAttribute(): ScheduledContentRatingsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeScheduledContentRatingsAttribute( - minInterval: Int, - maxInterval: Int - ): ScheduledContentRatingsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readScheduledContentRatingThresholdAttribute(): CharString { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeScheduledContentRatingThresholdAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here - } + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readScreenDailyTimeAttribute(): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scheduledcontentratings attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ContentControlClusterRatingNameStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ScheduledContentRatingsAttribute(decodedValue) } - suspend fun subscribeScreenDailyTimeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readScheduledContentRatingThresholdAttribute(): String? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Scheduledcontentratingthreshold attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readRemainingScreenTimeAttribute(): UInt { - // Implementation needs to be added here + suspend fun readScreenDailyTimeAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Screendailytime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeRemainingScreenTimeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readRemainingScreenTimeAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Remainingscreentime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readBlockUnratedAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeBlockUnratedAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Blockunrated attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ContentControlCluster::class.java.name) const val CLUSTER_ID: UInt = 1295u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentLauncherCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentLauncherCluster.kt index 5db8509ec6034d..54d72199cbd4ee 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentLauncherCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ContentLauncherCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ContentLauncherCluster( private val controller: MatterController, private val endpointId: UShort ) { - class LauncherResponse(val status: UInt, val data: String?) + class LauncherResponse(val status: UByte, val data: String?) class AcceptHeaderAttribute(val value: List?) @@ -44,13 +53,83 @@ class ContentLauncherCluster( useCurrentContext: Boolean?, timedInvokeTimeoutMs: Int? = null ): LauncherResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_SEARCH_REQ: Int = 0 + search.toTlv(ContextSpecificTag(TAG_SEARCH_REQ), tlvWriter) + + val TAG_AUTO_PLAY_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_AUTO_PLAY_REQ), autoPlay) + + val TAG_DATA_REQ: Int = 2 + data?.let { tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) } + + val TAG_PLAYBACK_PREFERENCES_REQ: Int = 3 + playbackPreferences?.let { + playbackPreferences.toTlv(ContextSpecificTag(TAG_PLAYBACK_PREFERENCES_REQ), tlvWriter) } + + val TAG_USE_CURRENT_CONTEXT_REQ: Int = 4 + useCurrentContext?.let { + tlvWriter.put(ContextSpecificTag(TAG_USE_CURRENT_CONTEXT_REQ), useCurrentContext) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return LauncherResponse(status_decoded, data_decoded) } suspend fun launchURL( @@ -59,95 +138,371 @@ class ContentLauncherCluster( brandingInformation: ContentLauncherClusterBrandingInformationStruct?, timedInvokeTimeoutMs: Int? = null ): LauncherResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_CONTENT_U_R_L_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_CONTENT_U_R_L_REQ), contentURL) + + val TAG_DISPLAY_STRING_REQ: Int = 1 + displayString?.let { tlvWriter.put(ContextSpecificTag(TAG_DISPLAY_STRING_REQ), displayString) } + + val TAG_BRANDING_INFORMATION_REQ: Int = 2 + brandingInformation?.let { + brandingInformation.toTlv(ContextSpecificTag(TAG_BRANDING_INFORMATION_REQ), tlvWriter) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return LauncherResponse(status_decoded, data_decoded) } suspend fun readAcceptHeaderAttribute(): AcceptHeaderAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeAcceptHeaderAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptHeaderAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptheader attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } - suspend fun readSupportedStreamingProtocolsAttribute(): UInt { - // Implementation needs to be added here + return AcceptHeaderAttribute(decodedValue) } - suspend fun subscribeSupportedStreamingProtocolsAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here + suspend fun readSupportedStreamingProtocolsAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedstreamingprotocols attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ContentLauncherCluster::class.java.name) const val CLUSTER_ID: UInt = 1290u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DemandResponseLoadControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DemandResponseLoadControlCluster.kt index 2f61d6f7b0c5db..5d203e3d2f3425 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DemandResponseLoadControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DemandResponseLoadControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class DemandResponseLoadControlCluster( private val controller: MatterController, @@ -46,215 +55,708 @@ class DemandResponseLoadControlCluster( loadControlProgram: DemandResponseLoadControlClusterLoadControlProgramStruct, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LOAD_CONTROL_PROGRAM_REQ: Int = 0 + loadControlProgram.toTlv(ContextSpecificTag(TAG_LOAD_CONTROL_PROGRAM_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun unregisterLoadControlProgramRequest( loadControlProgramID: ByteArray, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LOAD_CONTROL_PROGRAM_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LOAD_CONTROL_PROGRAM_I_D_REQ), loadControlProgramID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun addLoadControlEventRequest( event: DemandResponseLoadControlClusterLoadControlEventStruct, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EVENT_REQ: Int = 0 + event.toTlv(ContextSpecificTag(TAG_EVENT_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun removeLoadControlEventRequest( eventID: ByteArray, - cancelControl: UInt, + cancelControl: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EVENT_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_EVENT_I_D_REQ), eventID) + + val TAG_CANCEL_CONTROL_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_CANCEL_CONTROL_REQ), cancelControl) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun clearLoadControlEventsRequest(timedInvokeTimeoutMs: Int? = null) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readLoadControlProgramsAttribute(): LoadControlProgramsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeLoadControlProgramsAttribute( - minInterval: Int, - maxInterval: Int - ): LoadControlProgramsAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Loadcontrolprograms attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + DemandResponseLoadControlClusterLoadControlProgramStruct.fromTlv( + AnonymousTag, + tlvReader + ) + ) + } + tlvReader.exitContainer() + } + + return LoadControlProgramsAttribute(decodedValue) } suspend fun readNumberOfLoadControlProgramsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeNumberOfLoadControlProgramsAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofloadcontrolprograms attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readEventsAttribute(): EventsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeEventsAttribute(minInterval: Int, maxInterval: Int): EventsAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Events attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + DemandResponseLoadControlClusterLoadControlEventStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + return EventsAttribute(decodedValue) } suspend fun readActiveEventsAttribute(): ActiveEventsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeActiveEventsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveEventsAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activeevents attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + DemandResponseLoadControlClusterLoadControlEventStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + return ActiveEventsAttribute(decodedValue) } suspend fun readNumberOfEventsPerProgramAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeNumberOfEventsPerProgramAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofeventsperprogram attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readNumberOfTransitionsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeNumberOfTransitionsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberoftransitions attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readDefaultRandomStartAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u - suspend fun writeDefaultRandomStartAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Defaultrandomstart attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeDefaultRandomStartAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeDefaultRandomStartAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 6u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readDefaultRandomDurationAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun writeDefaultRandomDurationAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Defaultrandomduration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeDefaultRandomDurationAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeDefaultRandomDurationAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 7u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(DemandResponseLoadControlCluster::class.java.name) const val CLUSTER_ID: UInt = 150u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DescriptorCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DescriptorCluster.kt index 109cefa90c030a..a80aa5d9e56ae7 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DescriptorCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DescriptorCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class DescriptorCluster(private val controller: MatterController, private val endpointId: UShort) { class DeviceTypeListAttribute(val value: List) @@ -40,112 +45,415 @@ class DescriptorCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun readDeviceTypeListAttribute(): DeviceTypeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeDeviceTypeListAttribute( - minInterval: Int, - maxInterval: Int - ): DeviceTypeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Devicetypelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(DescriptorClusterDeviceTypeStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return DeviceTypeListAttribute(decodedValue) } suspend fun readServerListAttribute(): ServerListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeServerListAttribute( - minInterval: Int, - maxInterval: Int - ): ServerListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Serverlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return ServerListAttribute(decodedValue) } suspend fun readClientListAttribute(): ClientListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeClientListAttribute( - minInterval: Int, - maxInterval: Int - ): ClientListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Clientlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return ClientListAttribute(decodedValue) } suspend fun readPartsListAttribute(): PartsListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePartsListAttribute(minInterval: Int, maxInterval: Int): PartsListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Partslist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return PartsListAttribute(decodedValue) } suspend fun readTagListAttribute(): TagListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeTagListAttribute(minInterval: Int, maxInterval: Int): TagListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Taglist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(DescriptorClusterSemanticTagStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return TagListAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(DescriptorCluster::class.java.name) const val CLUSTER_ID: UInt = 29u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DeviceEnergyManagementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DeviceEnergyManagementCluster.kt index 76705026383d83..4e61a1b75d5cf4 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DeviceEnergyManagementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DeviceEnergyManagementCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class DeviceEnergyManagementCluster( private val controller: MatterController, @@ -39,53 +48,115 @@ class DeviceEnergyManagementCluster( class AttributeListAttribute(val value: List) suspend fun powerAdjustRequest(power: Long, duration: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_POWER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_POWER_REQ), power) + + val TAG_DURATION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun cancelPowerAdjustRequest(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun startTimeAdjustRequest(requestedStartTime: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_REQUESTED_START_TIME_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_REQUESTED_START_TIME_REQ), requestedStartTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun pauseRequest(duration: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DURATION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_DURATION_REQ), duration) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun resumeRequest(timedInvokeTimeoutMs: Int? = null) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun modifyForecastRequest( @@ -93,145 +164,524 @@ class DeviceEnergyManagementCluster( slotAdjustments: List, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_FORECAST_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_FORECAST_ID_REQ), forecastId) + + val TAG_SLOT_ADJUSTMENTS_REQ: Int = 1 + tlvWriter.startArray(ContextSpecificTag(TAG_SLOT_ADJUSTMENTS_REQ)) + for (item in slotAdjustments.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun requestConstraintBasedForecast( constraints: List, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_CONSTRAINTS_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_CONSTRAINTS_REQ)) + for (item in constraints.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readESATypeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeESATypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Esatype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readESACanGenerateAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeESACanGenerateAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Esacangenerate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readESAStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeESAStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Esastate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readAbsMinPowerAttribute(): Long { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeAbsMinPowerAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Absminpower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) + + return decodedValue } suspend fun readAbsMaxPowerAttribute(): Long { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Absmaxpower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun subscribeAbsMaxPowerAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here + return decodedValue } suspend fun readPowerAdjustmentCapabilityAttribute(): PowerAdjustmentCapabilityAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePowerAdjustmentCapabilityAttribute( - minInterval: Int, - maxInterval: Int - ): PowerAdjustmentCapabilityAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Poweradjustmentcapability attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(DeviceEnergyManagementClusterPowerAdjustStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PowerAdjustmentCapabilityAttribute(decodedValue) } suspend fun readForecastAttribute(): ForecastAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeForecastAttribute(minInterval: Int, maxInterval: Int): ForecastAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Forecast attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: DeviceEnergyManagementClusterForecastStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + DeviceEnergyManagementClusterForecastStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ForecastAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(DeviceEnergyManagementCluster::class.java.name) const val CLUSTER_ID: UInt = 152u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DiagnosticLogsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DiagnosticLogsCluster.kt index 13b9d53a1f6740..4f86b9bab6555d 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DiagnosticLogsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DiagnosticLogsCluster.kt @@ -17,15 +17,24 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class DiagnosticLogsCluster( private val controller: MatterController, private val endpointId: UShort ) { class RetrieveLogsResponse( - val status: UInt, + val status: UByte, val logContent: ByteArray, val UTCTimeStamp: ULong?, val timeSinceBoot: ULong? @@ -40,78 +49,331 @@ class DiagnosticLogsCluster( class AttributeListAttribute(val value: List) suspend fun retrieveLogsRequest( - intent: UInt, - requestedProtocol: UInt, + intent: UByte, + requestedProtocol: UByte, transferFileDesignator: String?, timedInvokeTimeoutMs: Int? = null ): RetrieveLogsResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_INTENT_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_INTENT_REQ), intent) + + val TAG_REQUESTED_PROTOCOL_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_REQUESTED_PROTOCOL_REQ), requestedProtocol) + + val TAG_TRANSFER_FILE_DESIGNATOR_REQ: Int = 2 + transferFileDesignator?.let { + tlvWriter.put(ContextSpecificTag(TAG_TRANSFER_FILE_DESIGNATOR_REQ), transferFileDesignator) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_LOG_CONTENT: Int = 1 + var logContent_decoded: ByteArray? = null + + val TAG_U_T_C_TIME_STAMP: Int = 2 + var UTCTimeStamp_decoded: ULong? = null + + val TAG_TIME_SINCE_BOOT: Int = 3 + var timeSinceBoot_decoded: ULong? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_LOG_CONTENT)) { + logContent_decoded = tlvReader.getByteArray(tag) + } + + if (tag == ContextSpecificTag(TAG_U_T_C_TIME_STAMP)) { + UTCTimeStamp_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getULong(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_TIME_SINCE_BOOT)) { + timeSinceBoot_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getULong(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + if (logContent_decoded == null) { + throw IllegalStateException("logContent not found in TLV") + } + + tlvReader.exitContainer() + + return RetrieveLogsResponse( + status_decoded, + logContent_decoded, + UTCTimeStamp_decoded, + timeSinceBoot_decoded + ) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(DiagnosticLogsCluster::class.java.name) const val CLUSTER_ID: UInt = 50u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherAlarmCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherAlarmCluster.kt index e0d986f2c59042..c6296d352c8597 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherAlarmCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherAlarmCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class DishwasherAlarmCluster( private val controller: MatterController, @@ -32,116 +41,397 @@ class DishwasherAlarmCluster( class AttributeListAttribute(val value: List) - suspend fun reset(alarms: ULong, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + suspend fun reset(alarms: UInt, timedInvokeTimeoutMs: Int? = null) { + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ALARMS_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ALARMS_REQ), alarms) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun modifyEnabledAlarms(mask: ULong, timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + suspend fun modifyEnabledAlarms(mask: UInt, timedInvokeTimeoutMs: Int? = null) { + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MASK_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MASK_REQ), mask) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readMaskAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeMaskAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readLatchAttribute(): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Mask attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } - suspend fun subscribeLatchAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readLatchAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Latch attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readStateAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeStateAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "State attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readSupportedAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeSupportedAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supported attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(DishwasherAlarmCluster::class.java.name) const val CLUSTER_ID: UInt = 93u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherModeCluster.kt index 5352d16f02443c..4f1e67c163e840 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DishwasherModeCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class DishwasherModeCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ChangeToModeResponse(val status: UInt, val statusText: String?) + class ChangeToModeResponse(val status: UByte, val statusText: String?) class SupportedModesAttribute(val value: List) @@ -44,127 +53,520 @@ class DishwasherModeCluster( newMode: UByte, timedInvokeTimeoutMs: Int? = null ): ChangeToModeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(DishwasherModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) } - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpModeAttribute { - // Implementation needs to be added here + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(DishwasherModeCluster::class.java.name) const val CLUSTER_ID: UInt = 89u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DoorLockCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DoorLockCluster.kt index efe90d407177d7..21a67cf8af9d01 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DoorLockCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/DoorLockCluster.kt @@ -17,15 +17,24 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class DoorLockCluster(private val controller: MatterController, private val endpointId: UShort) { class GetWeekDayScheduleResponse( val weekDayIndex: UByte, val userIndex: UShort, - val status: UInt, - val daysMask: UInt?, + val status: UByte, + val daysMask: UByte?, val startHour: UByte?, val startMinute: UByte?, val endHour: UByte?, @@ -35,26 +44,26 @@ class DoorLockCluster(private val controller: MatterController, private val endp class GetYearDayScheduleResponse( val yearDayIndex: UByte, val userIndex: UShort, - val status: UInt, + val status: UByte, val localStartTime: UInt?, val localEndTime: UInt? ) class GetHolidayScheduleResponse( val holidayIndex: UByte, - val status: UInt, + val status: UByte, val localStartTime: UInt?, val localEndTime: UInt?, - val operatingMode: UInt? + val operatingMode: UByte? ) class GetUserResponse( val userIndex: UShort, val userName: String?, val userUniqueID: UInt?, - val userStatus: UInt?, - val userType: UInt?, - val credentialRule: UInt?, + val userStatus: UByte?, + val userType: UByte?, + val credentialRule: UByte?, val credentials: List?, val creatorFabricIndex: UByte?, val lastModifiedFabricIndex: UByte?, @@ -62,7 +71,7 @@ class DoorLockCluster(private val controller: MatterController, private val endp ) class SetCredentialResponse( - val status: UInt, + val status: UByte, val userIndex: UShort?, val nextCredentialIndex: UShort? ) @@ -75,9 +84,9 @@ class DoorLockCluster(private val controller: MatterController, private val endp val nextCredentialIndex: UShort? ) - class LockStateAttribute(val value: UInt?) + class LockStateAttribute(val value: UByte?) - class DoorStateAttribute(val value: UInt?) + class DoorStateAttribute(val value: UByte?) class GeneratedCommandListAttribute(val value: List) @@ -88,40 +97,122 @@ class DoorLockCluster(private val controller: MatterController, private val endp class AttributeListAttribute(val value: List) suspend fun lockDoor(PINCode: ByteArray?, timedInvokeTimeoutMs: Int) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_P_I_N_CODE_REQ: Int = 0 + PINCode?.let { tlvWriter.put(ContextSpecificTag(TAG_P_I_N_CODE_REQ), PINCode) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun unlockDoor(PINCode: ByteArray?, timedInvokeTimeoutMs: Int) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - // Implementation needs to be added here + val TAG_P_I_N_CODE_REQ: Int = 0 + PINCode?.let { tlvWriter.put(ContextSpecificTag(TAG_P_I_N_CODE_REQ), PINCode) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun unlockWithTimeout(timeout: UShort, PINCode: ByteArray?, timedInvokeTimeoutMs: Int) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TIMEOUT_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TIMEOUT_REQ), timeout) - // Implementation needs to be added here + val TAG_P_I_N_CODE_REQ: Int = 1 + PINCode?.let { tlvWriter.put(ContextSpecificTag(TAG_P_I_N_CODE_REQ), PINCode) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setWeekDaySchedule( weekDayIndex: UByte, userIndex: UShort, - daysMask: UInt, + daysMask: UByte, startHour: UByte, startMinute: UByte, endHour: UByte, endMinute: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 11L + val commandId: UInt = 11u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEEK_DAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_WEEK_DAY_INDEX_REQ), weekDayIndex) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + + val TAG_DAYS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_DAYS_MASK_REQ), daysMask) + + val TAG_START_HOUR_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_START_HOUR_REQ), startHour) + + val TAG_START_MINUTE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_START_MINUTE_REQ), startMinute) + + val TAG_END_HOUR_REQ: Int = 5 + tlvWriter.put(ContextSpecificTag(TAG_END_HOUR_REQ), endHour) + + val TAG_END_MINUTE_REQ: Int = 6 + tlvWriter.put(ContextSpecificTag(TAG_END_MINUTE_REQ), endMinute) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getWeekDaySchedule( @@ -129,13 +220,169 @@ class DoorLockCluster(private val controller: MatterController, private val endp userIndex: UShort, timedInvokeTimeoutMs: Int? = null ): GetWeekDayScheduleResponse { - val commandId = 12L + val commandId: UInt = 12u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEEK_DAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_WEEK_DAY_INDEX_REQ), weekDayIndex) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_WEEK_DAY_INDEX: Int = 0 + var weekDayIndex_decoded: UByte? = null + + val TAG_USER_INDEX: Int = 1 + var userIndex_decoded: UShort? = null + + val TAG_STATUS: Int = 2 + var status_decoded: UByte? = null + + val TAG_DAYS_MASK: Int = 3 + var daysMask_decoded: UByte? = null + + val TAG_START_HOUR: Int = 4 + var startHour_decoded: UByte? = null + + val TAG_START_MINUTE: Int = 5 + var startMinute_decoded: UByte? = null + + val TAG_END_HOUR: Int = 6 + var endHour_decoded: UByte? = null + + val TAG_END_MINUTE: Int = 7 + var endMinute_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_WEEK_DAY_INDEX)) { + weekDayIndex_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_USER_INDEX)) { + userIndex_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DAYS_MASK)) { + daysMask_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_START_HOUR)) { + startHour_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_START_MINUTE)) { + startMinute_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_END_HOUR)) { + endHour_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_END_MINUTE)) { + endMinute_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (weekDayIndex_decoded == null) { + throw IllegalStateException("weekDayIndex not found in TLV") + } + + if (userIndex_decoded == null) { + throw IllegalStateException("userIndex not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return GetWeekDayScheduleResponse( + weekDayIndex_decoded, + userIndex_decoded, + status_decoded, + daysMask_decoded, + startHour_decoded, + startMinute_decoded, + endHour_decoded, + endMinute_decoded + ) } suspend fun clearWeekDaySchedule( @@ -143,13 +390,29 @@ class DoorLockCluster(private val controller: MatterController, private val endp userIndex: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 13L + val commandId: UInt = 13u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEEK_DAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_WEEK_DAY_INDEX_REQ), weekDayIndex) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setYearDaySchedule( @@ -159,13 +422,35 @@ class DoorLockCluster(private val controller: MatterController, private val endp localEndTime: UInt, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 14L + val commandId: UInt = 14u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_YEAR_DAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_YEAR_DAY_INDEX_REQ), yearDayIndex) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + + val TAG_LOCAL_START_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_LOCAL_START_TIME_REQ), localStartTime) + + val TAG_LOCAL_END_TIME_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_LOCAL_END_TIME_REQ), localEndTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getYearDaySchedule( @@ -173,13 +458,115 @@ class DoorLockCluster(private val controller: MatterController, private val endp userIndex: UShort, timedInvokeTimeoutMs: Int? = null ): GetYearDayScheduleResponse { - val commandId = 15L + val commandId: UInt = 15u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_YEAR_DAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_YEAR_DAY_INDEX_REQ), yearDayIndex) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_YEAR_DAY_INDEX: Int = 0 + var yearDayIndex_decoded: UByte? = null + + val TAG_USER_INDEX: Int = 1 + var userIndex_decoded: UShort? = null + + val TAG_STATUS: Int = 2 + var status_decoded: UByte? = null + + val TAG_LOCAL_START_TIME: Int = 3 + var localStartTime_decoded: UInt? = null + + val TAG_LOCAL_END_TIME: Int = 4 + var localEndTime_decoded: UInt? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_YEAR_DAY_INDEX)) { + yearDayIndex_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_USER_INDEX)) { + userIndex_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_LOCAL_START_TIME)) { + localStartTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUInt(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_LOCAL_END_TIME)) { + localEndTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUInt(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (yearDayIndex_decoded == null) { + throw IllegalStateException("yearDayIndex not found in TLV") } + + if (userIndex_decoded == null) { + throw IllegalStateException("userIndex not found in TLV") + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return GetYearDayScheduleResponse( + yearDayIndex_decoded, + userIndex_decoded, + status_decoded, + localStartTime_decoded, + localEndTime_decoded + ) } suspend fun clearYearDaySchedule( @@ -187,680 +574,3067 @@ class DoorLockCluster(private val controller: MatterController, private val endp userIndex: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 16L + val commandId: UInt = 16u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_YEAR_DAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_YEAR_DAY_INDEX_REQ), yearDayIndex) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setHolidaySchedule( holidayIndex: UByte, localStartTime: UInt, localEndTime: UInt, - operatingMode: UInt, + operatingMode: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 17L + val commandId: UInt = 17u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_HOLIDAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_HOLIDAY_INDEX_REQ), holidayIndex) + + val TAG_LOCAL_START_TIME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_LOCAL_START_TIME_REQ), localStartTime) + + val TAG_LOCAL_END_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_LOCAL_END_TIME_REQ), localEndTime) + + val TAG_OPERATING_MODE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPERATING_MODE_REQ), operatingMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getHolidaySchedule( holidayIndex: UByte, timedInvokeTimeoutMs: Int? = null ): GetHolidayScheduleResponse { - val commandId = 18L + val commandId: UInt = 18u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_HOLIDAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_HOLIDAY_INDEX_REQ), holidayIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_HOLIDAY_INDEX: Int = 0 + var holidayIndex_decoded: UByte? = null + + val TAG_STATUS: Int = 1 + var status_decoded: UByte? = null + + val TAG_LOCAL_START_TIME: Int = 2 + var localStartTime_decoded: UInt? = null + + val TAG_LOCAL_END_TIME: Int = 3 + var localEndTime_decoded: UInt? = null + + val TAG_OPERATING_MODE: Int = 4 + var operatingMode_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_HOLIDAY_INDEX)) { + holidayIndex_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_LOCAL_START_TIME)) { + localStartTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUInt(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_LOCAL_END_TIME)) { + localEndTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUInt(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_OPERATING_MODE)) { + operatingMode_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (holidayIndex_decoded == null) { + throw IllegalStateException("holidayIndex not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return GetHolidayScheduleResponse( + holidayIndex_decoded, + status_decoded, + localStartTime_decoded, + localEndTime_decoded, + operatingMode_decoded + ) } suspend fun clearHolidaySchedule(holidayIndex: UByte, timedInvokeTimeoutMs: Int? = null) { - val commandId = 19L + val commandId: UInt = 19u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_HOLIDAY_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_HOLIDAY_INDEX_REQ), holidayIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setUser( - operationType: UInt, + operationType: UByte, userIndex: UShort, userName: String?, userUniqueID: UInt?, - userStatus: UInt?, - userType: UInt?, - credentialRule: UInt?, + userStatus: UByte?, + userType: UByte?, + credentialRule: UByte?, timedInvokeTimeoutMs: Int ) { - val commandId = 26L + val commandId: UInt = 26u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPERATION_TYPE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPERATION_TYPE_REQ), operationType) + + val TAG_USER_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + + val TAG_USER_NAME_REQ: Int = 2 + userName?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_NAME_REQ), userName) } + + val TAG_USER_UNIQUE_I_D_REQ: Int = 3 + userUniqueID?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_UNIQUE_I_D_REQ), userUniqueID) } - // Implementation needs to be added here + val TAG_USER_STATUS_REQ: Int = 4 + userStatus?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_STATUS_REQ), userStatus) } + + val TAG_USER_TYPE_REQ: Int = 5 + userType?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_TYPE_REQ), userType) } + + val TAG_CREDENTIAL_RULE_REQ: Int = 6 + credentialRule?.let { + tlvWriter.put(ContextSpecificTag(TAG_CREDENTIAL_RULE_REQ), credentialRule) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getUser(userIndex: UShort, timedInvokeTimeoutMs: Int? = null): GetUserResponse { - val commandId = 27L + val commandId: UInt = 27u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_USER_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_USER_INDEX: Int = 0 + var userIndex_decoded: UShort? = null + + val TAG_USER_NAME: Int = 1 + var userName_decoded: String? = null + + val TAG_USER_UNIQUE_I_D: Int = 2 + var userUniqueID_decoded: UInt? = null + + val TAG_USER_STATUS: Int = 3 + var userStatus_decoded: UByte? = null + + val TAG_USER_TYPE: Int = 4 + var userType_decoded: UByte? = null + + val TAG_CREDENTIAL_RULE: Int = 5 + var credentialRule_decoded: UByte? = null + + val TAG_CREDENTIALS: Int = 6 + var credentials_decoded: List? = null + + val TAG_CREATOR_FABRIC_INDEX: Int = 7 + var creatorFabricIndex_decoded: UByte? = null + + val TAG_LAST_MODIFIED_FABRIC_INDEX: Int = 8 + var lastModifiedFabricIndex_decoded: UByte? = null + + val TAG_NEXT_USER_INDEX: Int = 9 + var nextUserIndex_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_USER_INDEX)) { + userIndex_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_USER_NAME)) { + userName_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getString(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_USER_UNIQUE_I_D)) { + userUniqueID_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUInt(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_USER_STATUS)) { + userStatus_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_USER_TYPE)) { + userType_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CREDENTIAL_RULE)) { + credentialRule_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CREDENTIALS)) { + credentials_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(DoorLockClusterCredentialStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CREATOR_FABRIC_INDEX)) { + creatorFabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_LAST_MODIFIED_FABRIC_INDEX)) { + lastModifiedFabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NEXT_USER_INDEX)) { + nextUserIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUShort(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (userIndex_decoded == null) { + throw IllegalStateException("userIndex not found in TLV") } + + tlvReader.exitContainer() + + return GetUserResponse( + userIndex_decoded, + userName_decoded, + userUniqueID_decoded, + userStatus_decoded, + userType_decoded, + credentialRule_decoded, + credentials_decoded, + creatorFabricIndex_decoded, + lastModifiedFabricIndex_decoded, + nextUserIndex_decoded + ) } suspend fun clearUser(userIndex: UShort, timedInvokeTimeoutMs: Int) { - val commandId = 29L + val commandId: UInt = 29u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_USER_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setCredential( - operationType: UInt, + operationType: UByte, credential: DoorLockClusterCredentialStruct, credentialData: ByteArray, userIndex: UShort?, - userStatus: UInt?, - userType: UInt?, + userStatus: UByte?, + userType: UByte?, timedInvokeTimeoutMs: Int ): SetCredentialResponse { - val commandId = 34L + val commandId: UInt = 34u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPERATION_TYPE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPERATION_TYPE_REQ), operationType) + + val TAG_CREDENTIAL_REQ: Int = 1 + credential.toTlv(ContextSpecificTag(TAG_CREDENTIAL_REQ), tlvWriter) + + val TAG_CREDENTIAL_DATA_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_CREDENTIAL_DATA_REQ), credentialData) + + val TAG_USER_INDEX_REQ: Int = 3 + userIndex?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_INDEX_REQ), userIndex) } + + val TAG_USER_STATUS_REQ: Int = 4 + userStatus?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_STATUS_REQ), userStatus) } + + val TAG_USER_TYPE_REQ: Int = 5 + userType?.let { tlvWriter.put(ContextSpecificTag(TAG_USER_TYPE_REQ), userType) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_USER_INDEX: Int = 1 + var userIndex_decoded: UShort? = null + + val TAG_NEXT_CREDENTIAL_INDEX: Int = 2 + var nextCredentialIndex_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_USER_INDEX)) { + userIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUShort(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NEXT_CREDENTIAL_INDEX)) { + nextCredentialIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUShort(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - // Implementation needs to be added here + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return SetCredentialResponse(status_decoded, userIndex_decoded, nextCredentialIndex_decoded) } suspend fun getCredentialStatus( credential: DoorLockClusterCredentialStruct, timedInvokeTimeoutMs: Int? = null ): GetCredentialStatusResponse { - val commandId = 36L + val commandId: UInt = 36u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_CREDENTIAL_REQ: Int = 0 + credential.toTlv(ContextSpecificTag(TAG_CREDENTIAL_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_CREDENTIAL_EXISTS: Int = 0 + var credentialExists_decoded: Boolean? = null + + val TAG_USER_INDEX: Int = 1 + var userIndex_decoded: UShort? = null + + val TAG_CREATOR_FABRIC_INDEX: Int = 2 + var creatorFabricIndex_decoded: UByte? = null + + val TAG_LAST_MODIFIED_FABRIC_INDEX: Int = 3 + var lastModifiedFabricIndex_decoded: UByte? = null + + val TAG_NEXT_CREDENTIAL_INDEX: Int = 4 + var nextCredentialIndex_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_CREDENTIAL_EXISTS)) { + credentialExists_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_USER_INDEX)) { + userIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUShort(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CREATOR_FABRIC_INDEX)) { + creatorFabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_LAST_MODIFIED_FABRIC_INDEX)) { + lastModifiedFabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NEXT_CREDENTIAL_INDEX)) { + nextCredentialIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUShort(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (credentialExists_decoded == null) { + throw IllegalStateException("credentialExists not found in TLV") } + + tlvReader.exitContainer() + + return GetCredentialStatusResponse( + credentialExists_decoded, + userIndex_decoded, + creatorFabricIndex_decoded, + lastModifiedFabricIndex_decoded, + nextCredentialIndex_decoded + ) } suspend fun clearCredential( credential: DoorLockClusterCredentialStruct?, timedInvokeTimeoutMs: Int ) { - val commandId = 38L + val commandId: UInt = 38u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_CREDENTIAL_REQ: Int = 0 + credential?.let { credential.toTlv(ContextSpecificTag(TAG_CREDENTIAL_REQ), tlvWriter) } + tlvWriter.endStructure() - // Implementation needs to be added here + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun unboltDoor(PINCode: ByteArray?, timedInvokeTimeoutMs: Int) { - val commandId = 39L + val commandId: UInt = 39u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_P_I_N_CODE_REQ: Int = 0 + PINCode?.let { tlvWriter.put(ContextSpecificTag(TAG_P_I_N_CODE_REQ), PINCode) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) - // Implementation needs to be added here + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readLockStateAttribute(): LockStateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeLockStateAttribute(minInterval: Int, maxInterval: Int): LockStateAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readLockTypeAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeLockTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readActuatorEnabledAttribute(): Boolean { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeActuatorEnabledAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readDoorStateAttribute(): DoorStateAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeDoorStateAttribute(minInterval: Int, maxInterval: Int): DoorStateAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Lockstate attribute not found in response" } - suspend fun readDoorOpenEventsAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun writeDoorOpenEventsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } + return LockStateAttribute(decodedValue) } - suspend fun subscribeDoorOpenEventsAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + suspend fun readLockTypeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 1u - suspend fun readDoorClosedEventsAttribute(): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeDoorClosedEventsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeDoorClosedEventsAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readOpenPeriodAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeOpenPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Locktype attribute not found in response" } - suspend fun subscribeOpenPeriodAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun readNumberOfTotalUsersSupportedAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeNumberOfTotalUsersSupportedAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readActuatorEnabledAttribute(): Boolean { + val ATTRIBUTE_ID: UInt = 2u - suspend fun readNumberOfPINUsersSupportedAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeNumberOfPINUsersSupportedAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readNumberOfRFIDUsersSupportedAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeNumberOfRFIDUsersSupportedAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readNumberOfWeekDaySchedulesSupportedPerUserAttribute(): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeNumberOfWeekDaySchedulesSupportedPerUserAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readNumberOfYearDaySchedulesSupportedPerUserAttribute(): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Actuatorenabled attribute not found in response" } - suspend fun subscribeNumberOfYearDaySchedulesSupportedPerUserAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) - suspend fun readNumberOfHolidaySchedulesSupportedAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeNumberOfHolidaySchedulesSupportedAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + suspend fun readDoorStateAttribute(): DoorStateAttribute { + val ATTRIBUTE_ID: UInt = 3u - suspend fun readMaxPINCodeLengthAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxPINCodeLengthAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readMinPINCodeLengthAttribute(): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeMinPINCodeLengthAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readMaxRFIDCodeLengthAttribute(): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMaxRFIDCodeLengthAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readMinRFIDCodeLengthAttribute(): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Doorstate attribute not found in response" } - suspend fun subscribeMinRFIDCodeLengthAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readCredentialRulesSupportAttribute(): UByte { - // Implementation needs to be added here + return DoorStateAttribute(decodedValue) } - suspend fun subscribeCredentialRulesSupportAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + suspend fun readDoorOpenEventsAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u - suspend fun readNumberOfCredentialsSupportedPerUserAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeNumberOfCredentialsSupportedPerUserAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readLanguageAttribute(): CharString { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeLanguageAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeLanguageAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readLEDSettingsAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeLEDSettingsAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Dooropenevents attribute not found in response" } - suspend fun subscribeLEDSettingsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } - suspend fun readAutoRelockTimeAttribute(): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun writeAutoRelockTimeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeDoorOpenEventsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeAutoRelockTimeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + suspend fun readDoorClosedEventsAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 5u - suspend fun readSoundVolumeAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeSoundVolumeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeSoundVolumeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readOperatingModeAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeOperatingModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Doorclosedevents attribute not found in response" } - suspend fun subscribeOperatingModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } - suspend fun readSupportedOperatingModesAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeSupportedOperatingModesAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun writeDoorClosedEventsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun readDefaultConfigurationRegisterAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readOpenPeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 6u - suspend fun subscribeDefaultConfigurationRegisterAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readEnableLocalProgrammingAttribute(): Boolean { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeEnableLocalProgrammingAttribute( - value: Boolean, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeEnableLocalProgrammingAttribute( - minInterval: Int, - maxInterval: Int - ): Boolean { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readEnableOneTouchLockingAttribute(): Boolean { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeEnableOneTouchLockingAttribute( - value: Boolean, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Openperiod attribute not found in response" } - suspend fun subscribeEnableOneTouchLockingAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readEnableInsideStatusLEDAttribute(): Boolean { - // Implementation needs to be added here + return decodedValue } - suspend fun writeEnableInsideStatusLEDAttribute( - value: Boolean, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeOpenPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 6u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeEnableInsideStatusLEDAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + suspend fun readNumberOfTotalUsersSupportedAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 17u - suspend fun readEnablePrivacyModeButtonAttribute(): Boolean { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeEnablePrivacyModeButtonAttribute( - value: Boolean, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeEnablePrivacyModeButtonAttribute( - minInterval: Int, - maxInterval: Int - ): Boolean { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readLocalProgrammingFeaturesAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeLocalProgrammingFeaturesAttribute( - value: UInt, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Numberoftotaluserssupported attribute not found in response" } - suspend fun subscribeLocalProgrammingFeaturesAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readWrongCodeEntryLimitAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun writeWrongCodeEntryLimitAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readNumberOfPINUsersSupportedAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 18u - suspend fun subscribeWrongCodeEntryLimitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readUserCodeTemporaryDisableTimeAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeUserCodeTemporaryDisableTimeAttribute( - value: UByte, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeUserCodeTemporaryDisableTimeAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readSendPINOverTheAirAttribute(): Boolean { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeSendPINOverTheAirAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Numberofpinuserssupported attribute not found in response" } - suspend fun subscribeSendPINOverTheAirAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readRequirePINforRemoteOperationAttribute(): Boolean { - // Implementation needs to be added here + return decodedValue } - suspend fun writeRequirePINforRemoteOperationAttribute( - value: Boolean, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readNumberOfRFIDUsersSupportedAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 19u - suspend fun subscribeRequirePINforRemoteOperationAttribute( - minInterval: Int, - maxInterval: Int - ): Boolean { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readExpiringUserTimeoutAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeExpiringUserTimeoutAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeExpiringUserTimeoutAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Numberofrfiduserssupported attribute not found in response" } - suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + suspend fun readNumberOfWeekDaySchedulesSupportedPerUserAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 20u - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Numberofweekdayschedulessupportedperuser attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readNumberOfYearDaySchedulesSupportedPerUserAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 21u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Numberofyeardayschedulessupportedperuser attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here + suspend fun readNumberOfHolidaySchedulesSupportedAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Numberofholidayschedulessupported attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMaxPINCodeLengthAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 23u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxpincodelength attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMinPINCodeLengthAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 24u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minpincodelength attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMaxRFIDCodeLengthAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 25u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxrfidcodelength attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMinRFIDCodeLengthAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minrfidcodelength attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readCredentialRulesSupportAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 27u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Credentialrulessupport attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readNumberOfCredentialsSupportedPerUserAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 28u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Numberofcredentialssupportedperuser attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readLanguageAttribute(): String? { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Language attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun writeLanguageAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 33u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readLEDSettingsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ledsettings attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeLEDSettingsAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 34u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readAutoRelockTimeAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 35u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Autorelocktime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun writeAutoRelockTimeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 35u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readSoundVolumeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 36u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Soundvolume attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeSoundVolumeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 36u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readOperatingModeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 37u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operatingmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeOperatingModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 37u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readSupportedOperatingModesAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 38u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedoperatingmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun readDefaultConfigurationRegisterAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 39u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Defaultconfigurationregister attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readEnableLocalProgrammingAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 40u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enablelocalprogramming attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeEnableLocalProgrammingAttribute( + value: Boolean, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 40u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readEnableOneTouchLockingAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 41u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enableonetouchlocking attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeEnableOneTouchLockingAttribute( + value: Boolean, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 41u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readEnableInsideStatusLEDAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 42u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enableinsidestatusled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeEnableInsideStatusLEDAttribute( + value: Boolean, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 42u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readEnablePrivacyModeButtonAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 43u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enableprivacymodebutton attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeEnablePrivacyModeButtonAttribute( + value: Boolean, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 43u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readLocalProgrammingFeaturesAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 44u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Localprogrammingfeatures attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeLocalProgrammingFeaturesAttribute( + value: UByte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 44u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readWrongCodeEntryLimitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wrongcodeentrylimit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeWrongCodeEntryLimitAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 48u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readUserCodeTemporaryDisableTimeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Usercodetemporarydisabletime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeUserCodeTemporaryDisableTimeAttribute( + value: UByte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 49u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readSendPINOverTheAirAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sendpinovertheair attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeSendPINOverTheAirAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 50u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRequirePINforRemoteOperationAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 51u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Requirepinforremoteoperation attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRequirePINforRemoteOperationAttribute( + value: Boolean, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 51u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readExpiringUserTimeoutAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 53u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Expiringusertimeout attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeExpiringUserTimeoutAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 53u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } companion object { + private val logger = Logger.getLogger(DoorLockCluster::class.java.name) const val CLUSTER_ID: UInt = 257u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ElectricalMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ElectricalMeasurementCluster.kt index 9e3ed080f8c3f6..d9f1b64baf42ad 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ElectricalMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ElectricalMeasurementCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ElectricalMeasurementCluster( private val controller: MatterController, @@ -33,1293 +42,5269 @@ class ElectricalMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun getProfileInfoCommand(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getMeasurementProfileCommand( attributeId: UShort, startTime: UInt, - numberOfIntervals: UInt, + numberOfIntervals: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } - } + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - suspend fun readMeasurementTypeAttribute(): UInt { - // Implementation needs to be added here - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - suspend fun subscribeMeasurementTypeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val TAG_ATTRIBUTE_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ATTRIBUTE_ID_REQ), attributeId) - suspend fun readDcVoltageAttribute(): Short { - // Implementation needs to be added here - } + val TAG_START_TIME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_START_TIME_REQ), startTime) - suspend fun subscribeDcVoltageAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val TAG_NUMBER_OF_INTERVALS_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_NUMBER_OF_INTERVALS_REQ), numberOfIntervals) + tlvWriter.endStructure() - suspend fun readDcVoltageMinAttribute(): Short { - // Implementation needs to be added here - } + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) - suspend fun subscribeDcVoltageMinAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun readDcVoltageMaxAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readMeasurementTypeAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeDcVoltageMaxAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readDcCurrentAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeDcCurrentAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readDcCurrentMinAttribute(): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeDcCurrentMinAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readDcCurrentMaxAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeDcCurrentMaxAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Measurementtype attribute not found in response" } - suspend fun readDcPowerAttribute(): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } - suspend fun subscribeDcPowerAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun readDcPowerMinAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readDcVoltageAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 256u - suspend fun subscribeDcPowerMinAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readDcPowerMaxAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeDcPowerMaxAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readDcVoltageMultiplierAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeDcVoltageMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readDcVoltageDivisorAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeDcVoltageDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcvoltage attribute not found in response" } - suspend fun readDcCurrentMultiplierAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeDcCurrentMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readDcCurrentDivisorAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readDcVoltageMinAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 257u - suspend fun subscribeDcCurrentDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readDcPowerMultiplierAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeDcPowerMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readDcPowerDivisorAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeDcPowerDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readAcFrequencyAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcFrequencyAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcvoltagemin attribute not found in response" } - suspend fun readAcFrequencyMinAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeAcFrequencyMinAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readAcFrequencyMaxAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readDcVoltageMaxAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 258u - suspend fun subscribeAcFrequencyMaxAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readNeutralCurrentAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeNeutralCurrentAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readTotalActivePowerAttribute(): Int { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeTotalActivePowerAttribute(minInterval: Int, maxInterval: Int): Int { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTotalReactivePowerAttribute(): Int { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTotalReactivePowerAttribute(minInterval: Int, maxInterval: Int): Int { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcvoltagemax attribute not found in response" } - suspend fun readTotalApparentPowerAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeTotalApparentPowerAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readMeasured1stHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readDcCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 259u - suspend fun subscribeMeasured1stHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMeasured3rdHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMeasured3rdHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readMeasured5thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasured5thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readMeasured7thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeMeasured7thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dccurrent attribute not found in response" } - suspend fun readMeasured9thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeMeasured9thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun readMeasured11thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readDcCurrentMinAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 260u - suspend fun subscribeMeasured11thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMeasuredPhase1stHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMeasuredPhase1stHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readMeasuredPhase3rdHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredPhase3rdHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readMeasuredPhase5thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeMeasuredPhase5thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dccurrentmin attribute not found in response" } - suspend fun readMeasuredPhase7thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeMeasuredPhase7thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun readMeasuredPhase9thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readDcCurrentMaxAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 261u - suspend fun subscribeMeasuredPhase9thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMeasuredPhase11thHarmonicCurrentAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMeasuredPhase11thHarmonicCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readAcFrequencyMultiplierAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcFrequencyMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readAcFrequencyDivisorAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcFrequencyDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dccurrentmax attribute not found in response" } - suspend fun readPowerMultiplierAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribePowerMultiplierAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readPowerDivisorAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readDcPowerAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 262u - suspend fun subscribePowerDivisorAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readHarmonicCurrentMultiplierAttribute(): Byte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeHarmonicCurrentMultiplierAttribute( - minInterval: Int, - maxInterval: Int - ): Byte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readPhaseHarmonicCurrentMultiplierAttribute(): Byte { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePhaseHarmonicCurrentMultiplierAttribute( - minInterval: Int, - maxInterval: Int - ): Byte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readInstantaneousVoltageAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeInstantaneousVoltageAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcpower attribute not found in response" } - suspend fun readInstantaneousLineCurrentAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeInstantaneousLineCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readInstantaneousActiveCurrentAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readDcPowerMinAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 263u - suspend fun subscribeInstantaneousActiveCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readInstantaneousReactiveCurrentAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeInstantaneousReactiveCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readInstantaneousPowerAttribute(): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeInstantaneousPowerAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRmsVoltageAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeRmsVoltageAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcpowermin attribute not found in response" } - suspend fun readRmsVoltageMinAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeRmsVoltageMinAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun readRmsVoltageMaxAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readDcPowerMaxAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 264u - suspend fun subscribeRmsVoltageMaxAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRmsCurrentAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRmsCurrentAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readRmsCurrentMinAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeRmsCurrentMinAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRmsCurrentMaxAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeRmsCurrentMaxAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcpowermax attribute not found in response" } - suspend fun readActivePowerAttribute(): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeActivePowerAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun readActivePowerMinAttribute(): Short { - // Implementation needs to be added here - } + suspend fun readDcVoltageMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 512u - suspend fun subscribeActivePowerMinAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readActivePowerMaxAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeActivePowerMaxAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readReactivePowerAttribute(): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeReactivePowerAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readApparentPowerAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeApparentPowerAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcvoltagemultiplier attribute not found in response" } - suspend fun readPowerFactorAttribute(): Byte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribePowerFactorAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here + return decodedValue } - suspend fun readAverageRmsVoltageMeasurementPeriodAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readDcVoltageDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 513u - suspend fun writeAverageRmsVoltageMeasurementPeriodAttribute( - value: UShort, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAverageRmsVoltageMeasurementPeriodAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readAverageRmsUnderVoltageCounterAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeAverageRmsUnderVoltageCounterAttribute( - value: UShort, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeAverageRmsUnderVoltageCounterAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRmsExtremeOverVoltagePeriodAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeRmsExtremeOverVoltagePeriodAttribute( - value: UShort, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Dcvoltagedivisor attribute not found in response" } - suspend fun subscribeRmsExtremeOverVoltagePeriodAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readRmsExtremeUnderVoltagePeriodAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeRmsExtremeUnderVoltagePeriodAttribute( - value: UShort, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readDcCurrentMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 514u - suspend fun subscribeRmsExtremeUnderVoltagePeriodAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRmsVoltageSagPeriodAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeRmsVoltageSagPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeRmsVoltageSagPeriodAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRmsVoltageSwellPeriodAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeRmsVoltageSwellPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Dccurrentmultiplier attribute not found in response" } - suspend fun subscribeRmsVoltageSwellPeriodAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readAcVoltageMultiplierAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeAcVoltageMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readDcCurrentDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 515u - suspend fun readAcVoltageDivisorAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcVoltageDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readAcCurrentMultiplierAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeAcCurrentMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readAcCurrentDivisorAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcCurrentDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readAcPowerMultiplierAttribute(): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dccurrentdivisor attribute not found in response" } - suspend fun subscribeAcPowerMultiplierAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readAcPowerDivisorAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeAcPowerDivisorAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readDcPowerMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 516u - suspend fun readOverloadAlarmsMaskAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeOverloadAlarmsMaskAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeOverloadAlarmsMaskAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readVoltageOverloadAttribute(): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeVoltageOverloadAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readCurrentOverloadAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeCurrentOverloadAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcpowermultiplier attribute not found in response" } - suspend fun readAcOverloadAlarmsMaskAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun writeAcOverloadAlarmsMaskAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } + return decodedValue } - suspend fun subscribeAcOverloadAlarmsMaskAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readDcPowerDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 517u - suspend fun readAcVoltageOverloadAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcVoltageOverloadAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readAcCurrentOverloadAttribute(): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeAcCurrentOverloadAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readAcActivePowerOverloadAttribute(): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcActivePowerOverloadAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readAcReactivePowerOverloadAttribute(): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Dcpowerdivisor attribute not found in response" } - suspend fun subscribeAcReactivePowerOverloadAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readAverageRmsOverVoltageAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeAverageRmsOverVoltageAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readAcFrequencyAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 768u - suspend fun readAverageRmsUnderVoltageAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAverageRmsUnderVoltageAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readRmsExtremeOverVoltageAttribute(): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeRmsExtremeOverVoltageAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readRmsExtremeUnderVoltageAttribute(): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeRmsExtremeUnderVoltageAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readRmsVoltageSagAttribute(): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Acfrequency attribute not found in response" } - suspend fun subscribeRmsVoltageSagAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readRmsVoltageSwellAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeRmsVoltageSwellAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readAcFrequencyMinAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 769u - suspend fun readLineCurrentPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeLineCurrentPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readActiveCurrentPhaseBAttribute(): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeActiveCurrentPhaseBAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readReactiveCurrentPhaseBAttribute(): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeReactiveCurrentPhaseBAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readRmsVoltagePhaseBAttribute(): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Acfrequencymin attribute not found in response" } - suspend fun subscribeRmsVoltagePhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readRmsVoltageMinPhaseBAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeRmsVoltageMinPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readAcFrequencyMaxAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 770u - suspend fun readRmsVoltageMaxPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeRmsVoltageMaxPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readRmsCurrentPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeRmsCurrentPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readRmsCurrentMinPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeRmsCurrentMinPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readRmsCurrentMaxPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Acfrequencymax attribute not found in response" } - suspend fun subscribeRmsCurrentMaxPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readActivePowerPhaseBAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeActivePowerPhaseBAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readNeutralCurrentAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 771u - suspend fun readActivePowerMinPhaseBAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeActivePowerMinPhaseBAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readActivePowerMaxPhaseBAttribute(): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeActivePowerMaxPhaseBAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readReactivePowerPhaseBAttribute(): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeReactivePowerPhaseBAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readApparentPowerPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Neutralcurrent attribute not found in response" } - suspend fun subscribeApparentPowerPhaseBAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readPowerFactorPhaseBAttribute(): Byte { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribePowerFactorPhaseBAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here - } + suspend fun readTotalActivePowerAttribute(): Int? { + val ATTRIBUTE_ID: UInt = 772u - suspend fun readAverageRmsVoltageMeasurementPeriodPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAverageRmsVoltageMeasurementPeriodPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readAverageRmsOverVoltageCounterPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeAverageRmsOverVoltageCounterPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readAverageRmsUnderVoltageCounterPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAverageRmsUnderVoltageCounterPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readRmsExtremeOverVoltagePeriodPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Totalactivepower attribute not found in response" } - suspend fun subscribeRmsExtremeOverVoltagePeriodPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getInt(AnonymousTag) + } else { + null + } - suspend fun readRmsExtremeUnderVoltagePeriodPhaseBAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeRmsExtremeUnderVoltagePeriodPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readTotalReactivePowerAttribute(): Int? { + val ATTRIBUTE_ID: UInt = 773u - suspend fun readRmsVoltageSagPeriodPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeRmsVoltageSagPeriodPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readRmsVoltageSwellPeriodPhaseBAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeRmsVoltageSwellPeriodPhaseBAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readLineCurrentPhaseCAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeLineCurrentPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readActiveCurrentPhaseCAttribute(): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Totalreactivepower attribute not found in response" } - suspend fun subscribeActiveCurrentPhaseCAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getInt(AnonymousTag) + } else { + null + } - suspend fun readReactiveCurrentPhaseCAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeReactiveCurrentPhaseCAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readTotalApparentPowerAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 774u - suspend fun readRmsVoltagePhaseCAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeRmsVoltagePhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readRmsVoltageMinPhaseCAttribute(): UShort { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Totalapparentpower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasured1stHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 775u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measured1stharmoniccurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasured3rdHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 776u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measured3rdharmoniccurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasured5thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 777u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measured5thharmoniccurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasured7thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 778u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measured7thharmoniccurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasured9thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 779u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measured9thharmoniccurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasured11thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 780u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measured11thharmoniccurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasuredPhase1stHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 781u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Measuredphase1stharmoniccurrent attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasuredPhase3rdHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 782u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Measuredphase3rdharmoniccurrent attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasuredPhase5thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 783u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Measuredphase5thharmoniccurrent attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasuredPhase7thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 784u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Measuredphase7thharmoniccurrent attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasuredPhase9thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 785u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Measuredphase9thharmoniccurrent attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readMeasuredPhase11thHarmonicCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 786u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Measuredphase11thharmoniccurrent attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcFrequencyMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1024u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acfrequencymultiplier attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcFrequencyDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1025u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acfrequencydivisor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPowerMultiplierAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 1026u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powermultiplier attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPowerDivisorAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 1027u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powerdivisor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readHarmonicCurrentMultiplierAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 1028u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Harmoniccurrentmultiplier attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPhaseHarmonicCurrentMultiplierAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 1029u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Phaseharmoniccurrentmultiplier attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readInstantaneousVoltageAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1280u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Instantaneousvoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readInstantaneousLineCurrentAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1281u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Instantaneouslinecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readInstantaneousActiveCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1282u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Instantaneousactivecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readInstantaneousReactiveCurrentAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1283u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Instantaneousreactivecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readInstantaneousPowerAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1284u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Instantaneouspower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1285u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageMinAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1286u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagemin attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageMaxAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1287u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagemax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsCurrentAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1288u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsCurrentMinAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1289u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentmin attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsCurrentMaxAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1290u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentmax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActivePowerAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1291u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActivePowerMinAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1292u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowermin attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActivePowerMaxAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1293u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowermax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readReactivePowerAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1294u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reactivepower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readApparentPowerAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1295u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Apparentpower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPowerFactorAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 1296u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powerfactor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAverageRmsVoltageMeasurementPeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1297u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsvoltagemeasurementperiod attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeAverageRmsVoltageMeasurementPeriodAttribute( + value: UShort, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 1297u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readAverageRmsUnderVoltageCounterAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1299u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsundervoltagecounter attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeAverageRmsUnderVoltageCounterAttribute( + value: UShort, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 1299u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRmsExtremeOverVoltagePeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1300u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsextremeovervoltageperiod attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRmsExtremeOverVoltagePeriodAttribute( + value: UShort, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 1300u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRmsExtremeUnderVoltagePeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1301u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsextremeundervoltageperiod attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRmsExtremeUnderVoltagePeriodAttribute( + value: UShort, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 1301u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRmsVoltageSagPeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1302u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagesagperiod attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRmsVoltageSagPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1302u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRmsVoltageSwellPeriodAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1303u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltageswellperiod attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRmsVoltageSwellPeriodAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1303u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readAcVoltageMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1536u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acvoltagemultiplier attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcVoltageDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1537u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acvoltagedivisor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcCurrentMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1538u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accurrentmultiplier attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcCurrentDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1539u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accurrentdivisor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcPowerMultiplierAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1540u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acpowermultiplier attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcPowerDivisorAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1541u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acpowerdivisor attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readOverloadAlarmsMaskAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1792u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Overloadalarmsmask attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeOverloadAlarmsMaskAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1792u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readVoltageOverloadAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1793u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Voltageoverload attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readCurrentOverloadAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1794u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentoverload attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcOverloadAlarmsMaskAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2048u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acoverloadalarmsmask attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeAcOverloadAlarmsMaskAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2048u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readAcVoltageOverloadAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2049u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acvoltageoverload attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcCurrentOverloadAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2050u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accurrentoverload attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcActivePowerOverloadAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2051u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acactivepoweroverload attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAcReactivePowerOverloadAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2052u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acreactivepoweroverload attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAverageRmsOverVoltageAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2053u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagermsovervoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAverageRmsUnderVoltageAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2054u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagermsundervoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsExtremeOverVoltageAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2055u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsextremeovervoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsExtremeUnderVoltageAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2056u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsextremeundervoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageSagAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2057u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagesag attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageSwellAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2058u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltageswell attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readLineCurrentPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2305u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Linecurrentphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActiveCurrentPhaseBAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2306u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activecurrentphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readReactiveCurrentPhaseBAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2307u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reactivecurrentphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltagePhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2309u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagephaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageMinPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2310u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltageminphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageMaxPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2311u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagemaxphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsCurrentPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2312u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsCurrentMinPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2313u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentminphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsCurrentMaxPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2314u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentmaxphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActivePowerPhaseBAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2315u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowerphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActivePowerMinPhaseBAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2316u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowerminphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActivePowerMaxPhaseBAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2317u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowermaxphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readReactivePowerPhaseBAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2318u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reactivepowerphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readApparentPowerPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2319u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Apparentpowerphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readPowerFactorPhaseBAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 2320u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powerfactorphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAverageRmsVoltageMeasurementPeriodPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2321u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsvoltagemeasurementperiodphaseb attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAverageRmsOverVoltageCounterPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2322u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsovervoltagecounterphaseb attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readAverageRmsUnderVoltageCounterPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2323u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsundervoltagecounterphaseb attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsExtremeOverVoltagePeriodPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2324u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Rmsextremeovervoltageperiodphaseb attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsExtremeUnderVoltagePeriodPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2325u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Rmsextremeundervoltageperiodphaseb attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageSagPeriodPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2326u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagesagperiodphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRmsVoltageSwellPeriodPhaseBAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2327u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltageswellperiodphaseb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readLineCurrentPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2561u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Linecurrentphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActiveCurrentPhaseCAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2562u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activecurrentphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeRmsVoltageMinPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readReactiveCurrentPhaseCAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2563u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reactivecurrentphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun readRmsVoltageMaxPhaseCAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeRmsVoltageMaxPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readRmsVoltagePhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2565u - suspend fun readRmsCurrentPhaseCAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeRmsCurrentPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readRmsCurrentMinPhaseCAttribute(): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeRmsCurrentMinPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readRmsCurrentMaxPhaseCAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeRmsCurrentMaxPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readActivePowerPhaseCAttribute(): Short { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Rmsvoltagephasec attribute not found in response" } - suspend fun subscribeActivePowerPhaseCAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readActivePowerMinPhaseCAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeActivePowerMinPhaseCAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readRmsVoltageMinPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2566u - suspend fun readActivePowerMaxPhaseCAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeActivePowerMaxPhaseCAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readReactivePowerPhaseCAttribute(): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeReactivePowerPhaseCAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltageminphasec attribute not found in response" } - suspend fun readApparentPowerPhaseCAttribute(): UShort { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeApparentPowerPhaseCAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readRmsVoltageMaxPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2567u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagemaxphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readPowerFactorPhaseCAttribute(): Byte { - // Implementation needs to be added here + suspend fun readRmsCurrentPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2568u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribePowerFactorPhaseCAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here + suspend fun readRmsCurrentMinPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2569u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentminphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readAverageRmsVoltageMeasurementPeriodPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readRmsCurrentMaxPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2570u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmscurrentmaxphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeAverageRmsVoltageMeasurementPeriodPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readActivePowerPhaseCAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2571u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowerphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readAverageRmsOverVoltageCounterPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readActivePowerMinPhaseCAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2572u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowerminphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeAverageRmsOverVoltageCounterPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readActivePowerMaxPhaseCAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2573u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activepowermaxphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readAverageRmsUnderVoltageCounterPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readReactivePowerPhaseCAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2574u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Reactivepowerphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeAverageRmsUnderVoltageCounterPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readApparentPowerPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2575u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Apparentpowerphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readRmsExtremeOverVoltagePeriodPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readPowerFactorPhaseCAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 2576u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powerfactorphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeRmsExtremeOverVoltagePeriodPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readAverageRmsVoltageMeasurementPeriodPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2577u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsvoltagemeasurementperiodphasec attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readRmsExtremeUnderVoltagePeriodPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readAverageRmsOverVoltageCounterPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2578u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsovervoltagecounterphasec attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeRmsExtremeUnderVoltagePeriodPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readAverageRmsUnderVoltageCounterPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2579u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Averagermsundervoltagecounterphasec attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readRmsVoltageSagPeriodPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readRmsExtremeOverVoltagePeriodPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2580u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Rmsextremeovervoltageperiodphasec attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeRmsVoltageSagPeriodPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readRmsExtremeUnderVoltagePeriodPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2581u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Rmsextremeundervoltageperiodphasec attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readRmsVoltageSwellPeriodPhaseCAttribute(): UShort { - // Implementation needs to be added here + suspend fun readRmsVoltageSagPeriodPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2582u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltagesagperiodphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeRmsVoltageSwellPeriodPhaseCAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readRmsVoltageSwellPeriodPhaseCAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2583u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rmsvoltageswellperiodphasec attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ElectricalMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 2820u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EnergyEvseCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EnergyEvseCluster.kt index 8e5208cee1d2b4..4372be56350bc3 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EnergyEvseCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EnergyEvseCluster.kt @@ -17,16 +17,25 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class EnergyEvseCluster(private val controller: MatterController, private val endpointId: UShort) { class GetTargetsResponse( - val dayOfWeekforSequence: UInt, + val dayOfWeekforSequence: UByte, val chargingTargets: List ) - class StateAttribute(val value: UInt?) + class StateAttribute(val value: UByte?) class ChargingEnabledUntilAttribute(val value: UInt?) @@ -59,9 +68,22 @@ class EnergyEvseCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun disable(timedInvokeTimeoutMs: Int) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enableCharging( @@ -70,9 +92,33 @@ class EnergyEvseCluster(private val controller: MatterController, private val en maximumChargeCurrent: Long, timedInvokeTimeoutMs: Int ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_CHARGING_ENABLED_UNTIL_REQ: Int = 0 + chargingEnabledUntil?.let { + tlvWriter.put(ContextSpecificTag(TAG_CHARGING_ENABLED_UNTIL_REQ), chargingEnabledUntil) + } + + val TAG_MINIMUM_CHARGE_CURRENT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_MINIMUM_CHARGE_CURRENT_REQ), minimumChargeCurrent) - // Implementation needs to be added here + val TAG_MAXIMUM_CHARGE_CURRENT_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_MAXIMUM_CHARGE_CURRENT_REQ), maximumChargeCurrent) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun enableDischarging( @@ -80,357 +126,1431 @@ class EnergyEvseCluster(private val controller: MatterController, private val en maximumDischargeCurrent: Long, timedInvokeTimeoutMs: Int ) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DISCHARGING_ENABLED_UNTIL_REQ: Int = 0 + dischargingEnabledUntil?.let { + tlvWriter.put(ContextSpecificTag(TAG_DISCHARGING_ENABLED_UNTIL_REQ), dischargingEnabledUntil) + } - // Implementation needs to be added here + val TAG_MAXIMUM_DISCHARGE_CURRENT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_MAXIMUM_DISCHARGE_CURRENT_REQ), maximumDischargeCurrent) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun startDiagnostics(timedInvokeTimeoutMs: Int) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() - // Implementation needs to be added here + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setTargets( - dayOfWeekforSequence: UInt, + dayOfWeekforSequence: UByte, chargingTargets: List, timedInvokeTimeoutMs: Int ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) - // Implementation needs to be added here - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - suspend fun getTargets(daysToReturn: UInt, timedInvokeTimeoutMs: Int): GetTargetsResponse { - val commandId = 6L + val TAG_DAY_OF_WEEKFOR_SEQUENCE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_DAY_OF_WEEKFOR_SEQUENCE_REQ), dayOfWeekforSequence) - // Implementation needs to be added here + val TAG_CHARGING_TARGETS_REQ: Int = 1 + tlvWriter.startArray(ContextSpecificTag(TAG_CHARGING_TARGETS_REQ)) + for (item in chargingTargets.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun getTargets(daysToReturn: UByte, timedInvokeTimeoutMs: Int): GetTargetsResponse { + val commandId: UInt = 6u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DAYS_TO_RETURN_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_DAYS_TO_RETURN_REQ), daysToReturn) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_DAY_OF_WEEKFOR_SEQUENCE: Int = 0 + var dayOfWeekforSequence_decoded: UByte? = null + + val TAG_CHARGING_TARGETS: Int = 1 + var chargingTargets_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_DAY_OF_WEEKFOR_SEQUENCE)) { + dayOfWeekforSequence_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_CHARGING_TARGETS)) { + chargingTargets_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(EnergyEvseClusterChargingTargetStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (dayOfWeekforSequence_decoded == null) { + throw IllegalStateException("dayOfWeekforSequence not found in TLV") + } + + if (chargingTargets_decoded == null) { + throw IllegalStateException("chargingTargets not found in TLV") + } + + tlvReader.exitContainer() + + return GetTargetsResponse(dayOfWeekforSequence_decoded, chargingTargets_decoded) } suspend fun clearTargets(timedInvokeTimeoutMs: Int) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() - // Implementation needs to be added here + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readStateAttribute(): StateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeStateAttribute(minInterval: Int, maxInterval: Int): StateAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "State attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StateAttribute(decodedValue) } suspend fun readSupplyStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeSupplyStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supplystate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readFaultStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFaultStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Faultstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readChargingEnabledUntilAttribute(): ChargingEnabledUntilAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeChargingEnabledUntilAttribute( - minInterval: Int, - maxInterval: Int - ): ChargingEnabledUntilAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Chargingenableduntil attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ChargingEnabledUntilAttribute(decodedValue) } suspend fun readDischargingEnabledUntilAttribute(): DischargingEnabledUntilAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Dischargingenableduntil attribute not found in response" } - suspend fun subscribeDischargingEnabledUntilAttribute( - minInterval: Int, - maxInterval: Int - ): DischargingEnabledUntilAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return DischargingEnabledUntilAttribute(decodedValue) } suspend fun readCircuitCapacityAttribute(): Long { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Circuitcapacity attribute not found in response" } - suspend fun subscribeCircuitCapacityAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) + + return decodedValue } suspend fun readMinimumChargeCurrentAttribute(): Long { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minimumchargecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun subscribeMinimumChargeCurrentAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here + return decodedValue } suspend fun readMaximumChargeCurrentAttribute(): Long { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeMaximumChargeCurrentAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maximumchargecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun readMaximumDischargeCurrentAttribute(): Long { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeMaximumDischargeCurrentAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here + suspend fun readMaximumDischargeCurrentAttribute(): Long? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maximumdischargecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readUserMaximumChargeCurrentAttribute(): Long { - // Implementation needs to be added here + suspend fun readUserMaximumChargeCurrentAttribute(): Long? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Usermaximumchargecurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeUserMaximumChargeCurrentAttribute( value: Long, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 9u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeUserMaximumChargeCurrentAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + suspend fun readRandomizationDelayWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 10u - suspend fun readRandomizationDelayWindowAttribute(): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Randomizationdelaywindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeRandomizationDelayWindowAttribute( value: UInt, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 10u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeRandomizationDelayWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + suspend fun readNumberOfWeeklyTargetsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 33u - suspend fun readNumberOfWeeklyTargetsAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeNumberOfWeeklyTargetsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readNumberOfDailyTargetsAttribute(): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofweeklytargets attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeNumberOfDailyTargetsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readNumberOfDailyTargetsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofdailytargets attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readNextChargeStartTimeAttribute(): NextChargeStartTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 35u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeNextChargeStartTimeAttribute( - minInterval: Int, - maxInterval: Int - ): NextChargeStartTimeAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nextchargestarttime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NextChargeStartTimeAttribute(decodedValue) } suspend fun readNextChargeTargetTimeAttribute(): NextChargeTargetTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 36u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeNextChargeTargetTimeAttribute( - minInterval: Int, - maxInterval: Int - ): NextChargeTargetTimeAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nextchargetargettime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NextChargeTargetTimeAttribute(decodedValue) } suspend fun readNextChargeRequiredEnergyAttribute(): NextChargeRequiredEnergyAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 37u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeNextChargeRequiredEnergyAttribute( - minInterval: Int, - maxInterval: Int - ): NextChargeRequiredEnergyAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nextchargerequiredenergy attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NextChargeRequiredEnergyAttribute(decodedValue) } suspend fun readNextChargeTargetSoCAttribute(): NextChargeTargetSoCAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 38u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeNextChargeTargetSoCAttribute( - minInterval: Int, - maxInterval: Int - ): NextChargeTargetSoCAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nextchargetargetsoc attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NextChargeTargetSoCAttribute(decodedValue) } suspend fun readApproximateEVEfficiencyAttribute(): ApproximateEVEfficiencyAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 39u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Approximateevefficiency attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ApproximateEVEfficiencyAttribute(decodedValue) } suspend fun writeApproximateEVEfficiencyAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 39u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeApproximateEVEfficiencyAttribute( - minInterval: Int, - maxInterval: Int - ): ApproximateEVEfficiencyAttribute { - // Implementation needs to be added here - } - suspend fun readStateOfChargeAttribute(): StateOfChargeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeStateOfChargeAttribute( - minInterval: Int, - maxInterval: Int - ): StateOfChargeAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Stateofcharge attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StateOfChargeAttribute(decodedValue) } suspend fun readBatteryCapacityAttribute(): BatteryCapacityAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeBatteryCapacityAttribute( - minInterval: Int, - maxInterval: Int - ): BatteryCapacityAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batterycapacity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BatteryCapacityAttribute(decodedValue) } suspend fun readVehicleIDAttribute(): VehicleIDAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeVehicleIDAttribute(minInterval: Int, maxInterval: Int): VehicleIDAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Vehicleid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return VehicleIDAttribute(decodedValue) } suspend fun readSessionIDAttribute(): SessionIDAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 64u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSessionIDAttribute(minInterval: Int, maxInterval: Int): SessionIDAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sessionid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SessionIDAttribute(decodedValue) } suspend fun readSessionDurationAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSessionDurationAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sessionduration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readSessionEnergyChargedAttribute(): Long { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 66u - suspend fun subscribeSessionEnergyChargedAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readSessionEnergyDischargedAttribute(): Long { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sessionenergycharged attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) + + return decodedValue } - suspend fun subscribeSessionEnergyDischargedAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here + suspend fun readSessionEnergyDischargedAttribute(): Long? { + val ATTRIBUTE_ID: UInt = 67u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sessionenergydischarged attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getLong(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(EnergyEvseCluster::class.java.name) const val CLUSTER_ID: UInt = 153u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EthernetNetworkDiagnosticsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EthernetNetworkDiagnosticsCluster.kt index d7fc8fa494c838..782a2df8f9e222 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EthernetNetworkDiagnosticsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/EthernetNetworkDiagnosticsCluster.kt @@ -17,14 +17,22 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class EthernetNetworkDiagnosticsCluster( private val controller: MatterController, private val endpointId: UShort ) { - class PHYRateAttribute(val value: UInt?) + class PHYRateAttribute(val value: UByte?) class FullDuplexAttribute(val value: Boolean?) @@ -39,151 +47,580 @@ class EthernetNetworkDiagnosticsCluster( class AttributeListAttribute(val value: List) suspend fun resetCounts(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readPHYRateAttribute(): PHYRateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribePHYRateAttribute(minInterval: Int, maxInterval: Int): PHYRateAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Phyrate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PHYRateAttribute(decodedValue) } suspend fun readFullDuplexAttribute(): FullDuplexAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeFullDuplexAttribute( - minInterval: Int, - maxInterval: Int - ): FullDuplexAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPacketRxCountAttribute(): ULong { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePacketRxCountAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readPacketTxCountAttribute(): ULong { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePacketTxCountAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTxErrCountAttribute(): ULong { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Fullduplex attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return FullDuplexAttribute(decodedValue) } - suspend fun subscribeTxErrCountAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun readPacketRxCountAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Packetrxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readCollisionCountAttribute(): ULong { - // Implementation needs to be added here + suspend fun readPacketTxCountAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Packettxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeCollisionCountAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun readTxErrCountAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txerrcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readOverrunCountAttribute(): ULong { - // Implementation needs to be added here + suspend fun readCollisionCountAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Collisioncount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeOverrunCountAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun readOverrunCountAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Overruncount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readCarrierDetectAttribute(): CarrierDetectAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeCarrierDetectAttribute( - minInterval: Int, - maxInterval: Int - ): CarrierDetectAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun readTimeSinceResetAttribute(): ULong { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Carrierdetect attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CarrierDetectAttribute(decodedValue) } - suspend fun subscribeTimeSinceResetAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun readTimeSinceResetAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timesincereset attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(EthernetNetworkDiagnosticsCluster::class.java.name) const val CLUSTER_ID: UInt = 55u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FanControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FanControlCluster.kt index 178dde9600faad..094a5f3168e232 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FanControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FanControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class FanControlCluster(private val controller: MatterController, private val endpointId: UShort) { class PercentSettingAttribute(val value: UByte?) @@ -34,228 +43,930 @@ class FanControlCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun step( - direction: UInt, + direction: UByte, wrap: Boolean?, lowestOff: Boolean?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DIRECTION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_DIRECTION_REQ), direction) + + val TAG_WRAP_REQ: Int = 1 + wrap?.let { tlvWriter.put(ContextSpecificTag(TAG_WRAP_REQ), wrap) } + + val TAG_LOWEST_OFF_REQ: Int = 2 + lowestOff?.let { tlvWriter.put(ContextSpecificTag(TAG_LOWEST_OFF_REQ), lowestOff) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readFanModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeFanModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeFanModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Fanmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeFanModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readFanModeSequenceAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Fanmodesequence attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun subscribeFanModeSequenceAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return decodedValue } suspend fun readPercentSettingAttribute(): PercentSettingAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun writePercentSettingAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Percentsetting attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PercentSettingAttribute(decodedValue) } - suspend fun subscribePercentSettingAttribute( - minInterval: Int, - maxInterval: Int - ): PercentSettingAttribute { - // Implementation needs to be added here + suspend fun writePercentSettingAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readPercentCurrentAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePercentCurrentAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Percentcurrent attribute not found in response" } - suspend fun readSpeedMaxAttribute(): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeSpeedMaxAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readSpeedMaxAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Speedmax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readSpeedSettingAttribute(): SpeedSettingAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Speedsetting attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SpeedSettingAttribute(decodedValue) } suspend fun writeSpeedSettingAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeSpeedSettingAttribute( - minInterval: Int, - maxInterval: Int - ): SpeedSettingAttribute { - // Implementation needs to be added here - } + suspend fun readSpeedCurrentAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 6u - suspend fun readSpeedCurrentAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeSpeedCurrentAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readRockSupportAttribute(): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeRockSupportAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRockSettingAttribute(): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Speedcurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeRockSettingAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readRockSupportAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeRockSettingAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readWindSupportAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeWindSupportAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Rocksupport attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun readWindSettingAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun writeWindSettingAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readRockSettingAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeWindSettingAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rocksetting attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRockSettingAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 8u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun readAirflowDirectionAttribute(): UByte { - // Implementation needs to be added here + suspend fun readWindSupportAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Windsupport attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeAirflowDirectionAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readWindSettingAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Windsetting attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeWindSettingAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 10u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeAirflowDirectionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAirflowDirectionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Airflowdirection attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeAirflowDirectionAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 11u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(FanControlCluster::class.java.name) const val CLUSTER_ID: UInt = 514u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FaultInjectionCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FaultInjectionCluster.kt index 8580869b08b912..dd4a9126c4c37c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FaultInjectionCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FaultInjectionCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class FaultInjectionCluster( private val controller: MatterController, @@ -33,95 +42,297 @@ class FaultInjectionCluster( class AttributeListAttribute(val value: List) suspend fun failAtFault( - type: UInt, + type: UByte, id: UInt, numCallsToSkip: UInt, numCallsToFail: UInt, takeMutex: Boolean, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TYPE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TYPE_REQ), type) + + val TAG_ID_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ID_REQ), id) + + val TAG_NUM_CALLS_TO_SKIP_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_NUM_CALLS_TO_SKIP_REQ), numCallsToSkip) + + val TAG_NUM_CALLS_TO_FAIL_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_NUM_CALLS_TO_FAIL_REQ), numCallsToFail) + + val TAG_TAKE_MUTEX_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_TAKE_MUTEX_REQ), takeMutex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun failRandomlyAtFault( - type: UInt, + type: UByte, id: UInt, percentage: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TYPE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TYPE_REQ), type) + + val TAG_ID_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ID_REQ), id) + + val TAG_PERCENTAGE_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_PERCENTAGE_REQ), percentage) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(FaultInjectionCluster::class.java.name) const val CLUSTER_ID: UInt = 4294048774u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FixedLabelCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FixedLabelCluster.kt index 6d9458b0610c05..7b889f0bd66969 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FixedLabelCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FixedLabelCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class FixedLabelCluster(private val controller: MatterController, private val endpointId: UShort) { class LabelListAttribute(val value: List) @@ -32,71 +37,259 @@ class FixedLabelCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun readLabelListAttribute(): LabelListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Labellist attribute not found in response" } - suspend fun subscribeLabelListAttribute(minInterval: Int, maxInterval: Int): LabelListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(FixedLabelClusterLabelStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return LabelListAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(FixedLabelCluster::class.java.name) const val CLUSTER_ID: UInt = 64u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FlowMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FlowMeasurementCluster.kt index 69a553ee21ae62..cfc1ec245718de 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FlowMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FlowMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class FlowMeasurementCluster( private val controller: MatterController, @@ -39,104 +44,368 @@ class FlowMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readToleranceAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } - suspend fun subscribeToleranceAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readToleranceAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tolerance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(FlowMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1028u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FormaldehydeConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FormaldehydeConcentrationMeasurementCluster.kt index 12195781103ef8..c946b2d04ab3ef 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FormaldehydeConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/FormaldehydeConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class FormaldehydeConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,643 @@ class FormaldehydeConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger(FormaldehydeConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1067u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralCommissioningCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralCommissioningCluster.kt index b00a893fde74f8..5d7d4182e10d0a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralCommissioningCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralCommissioningCluster.kt @@ -17,18 +17,27 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class GeneralCommissioningCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ArmFailSafeResponse(val errorCode: UInt, val debugText: String) + class ArmFailSafeResponse(val errorCode: UByte, val debugText: String) - class SetRegulatoryConfigResponse(val errorCode: UInt, val debugText: String) + class SetRegulatoryConfigResponse(val errorCode: UByte, val debugText: String) - class CommissioningCompleteResponse(val errorCode: UInt, val debugText: String) + class CommissioningCompleteResponse(val errorCode: UByte, val debugText: String) class BasicCommissioningInfoAttribute( val value: GeneralCommissioningClusterBasicCommissioningInfo @@ -47,154 +56,606 @@ class GeneralCommissioningCluster( breadcrumb: ULong, timedInvokeTimeoutMs: Int? = null ): ArmFailSafeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EXPIRY_LENGTH_SECONDS_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_EXPIRY_LENGTH_SECONDS_REQ), expiryLengthSeconds) + + val TAG_BREADCRUMB_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ERROR_CODE: Int = 0 + var errorCode_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ERROR_CODE)) { + errorCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (errorCode_decoded == null) { + throw IllegalStateException("errorCode not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (debugText_decoded == null) { + throw IllegalStateException("debugText not found in TLV") } + + tlvReader.exitContainer() + + return ArmFailSafeResponse(errorCode_decoded, debugText_decoded) } suspend fun setRegulatoryConfig( - newRegulatoryConfig: UInt, + newRegulatoryConfig: UByte, countryCode: String, breadcrumb: ULong, timedInvokeTimeoutMs: Int? = null ): SetRegulatoryConfigResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_REGULATORY_CONFIG_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_REGULATORY_CONFIG_REQ), newRegulatoryConfig) + + val TAG_COUNTRY_CODE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_COUNTRY_CODE_REQ), countryCode) + + val TAG_BREADCRUMB_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ERROR_CODE: Int = 0 + var errorCode_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ERROR_CODE)) { + errorCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (errorCode_decoded == null) { + throw IllegalStateException("errorCode not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (debugText_decoded == null) { + throw IllegalStateException("debugText not found in TLV") } + + tlvReader.exitContainer() + + return SetRegulatoryConfigResponse(errorCode_decoded, debugText_decoded) } suspend fun commissioningComplete( timedInvokeTimeoutMs: Int? = null ): CommissioningCompleteResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ERROR_CODE: Int = 0 + var errorCode_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ERROR_CODE)) { + errorCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (errorCode_decoded == null) { + throw IllegalStateException("errorCode not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (debugText_decoded == null) { + throw IllegalStateException("debugText not found in TLV") } + + tlvReader.exitContainer() + + return CommissioningCompleteResponse(errorCode_decoded, debugText_decoded) } suspend fun readBreadcrumbAttribute(): ULong { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun writeBreadcrumbAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Breadcrumb attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) + + return decodedValue } - suspend fun subscribeBreadcrumbAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun writeBreadcrumbAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBasicCommissioningInfoAttribute(): BasicCommissioningInfoAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Basiccommissioninginfo attribute not found in response" } - suspend fun subscribeBasicCommissioningInfoAttribute( - minInterval: Int, - maxInterval: Int - ): BasicCommissioningInfoAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: GeneralCommissioningClusterBasicCommissioningInfo = + GeneralCommissioningClusterBasicCommissioningInfo.fromTlv(AnonymousTag, tlvReader) + + return BasicCommissioningInfoAttribute(decodedValue) } suspend fun readRegulatoryConfigAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRegulatoryConfigAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Regulatoryconfig attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readLocationCapabilityAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeLocationCapabilityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Locationcapability attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readSupportsConcurrentConnectionAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeSupportsConcurrentConnectionAttribute( - minInterval: Int, - maxInterval: Int - ): Boolean { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportsconcurrentconnection attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(GeneralCommissioningCluster::class.java.name) const val CLUSTER_ID: UInt = 48u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt index 543a9bcb638158..4b77e41dd48d86 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class GeneralDiagnosticsCluster( private val controller: MatterController, @@ -28,11 +37,11 @@ class GeneralDiagnosticsCluster( class NetworkInterfacesAttribute(val value: List) - class ActiveHardwareFaultsAttribute(val value: List?) + class ActiveHardwareFaultsAttribute(val value: List?) - class ActiveRadioFaultsAttribute(val value: List?) + class ActiveRadioFaultsAttribute(val value: List?) - class ActiveNetworkFaultsAttribute(val value: List?) + class ActiveNetworkFaultsAttribute(val value: List?) class GeneratedCommandListAttribute(val value: List) @@ -47,170 +56,643 @@ class GeneralDiagnosticsCluster( eventTrigger: ULong, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ENABLE_KEY_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ENABLE_KEY_REQ), enableKey) + + val TAG_EVENT_TRIGGER_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_EVENT_TRIGGER_REQ), eventTrigger) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun timeSnapshot(timedInvokeTimeoutMs: Int? = null): TimeSnapshotResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_SYSTEM_TIME_US: Int = 0 + var systemTimeUs_decoded: ULong? = null + + val TAG_U_T_C_TIME_US: Int = 1 + var UTCTimeUs_decoded: ULong? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_SYSTEM_TIME_US)) { + systemTimeUs_decoded = tlvReader.getULong(tag) + } + + if (tag == ContextSpecificTag(TAG_U_T_C_TIME_US)) { + UTCTimeUs_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getULong(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (systemTimeUs_decoded == null) { + throw IllegalStateException("systemTimeUs not found in TLV") } + + tlvReader.exitContainer() + + return TimeSnapshotResponse(systemTimeUs_decoded, UTCTimeUs_decoded) } suspend fun readNetworkInterfacesAttribute(): NetworkInterfacesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeNetworkInterfacesAttribute( - minInterval: Int, - maxInterval: Int - ): NetworkInterfacesAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Networkinterfaces attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(GeneralDiagnosticsClusterNetworkInterface.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return NetworkInterfacesAttribute(decodedValue) } suspend fun readRebootCountAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeRebootCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readUpTimeAttribute(): ULong { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeUpTimeAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTotalOperationalHoursAttribute(): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rebootcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } - suspend fun subscribeTotalOperationalHoursAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readUpTimeAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uptime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readBootReasonAttribute(): UByte { - // Implementation needs to be added here + suspend fun readTotalOperationalHoursAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Totaloperationalhours attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBootReasonAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readBootReasonAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Bootreason attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readActiveHardwareFaultsAttribute(): ActiveHardwareFaultsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeActiveHardwareFaultsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveHardwareFaultsAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activehardwarefaults attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ActiveHardwareFaultsAttribute(decodedValue) } suspend fun readActiveRadioFaultsAttribute(): ActiveRadioFaultsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeActiveRadioFaultsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveRadioFaultsAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activeradiofaults attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ActiveRadioFaultsAttribute(decodedValue) } suspend fun readActiveNetworkFaultsAttribute(): ActiveNetworkFaultsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeActiveNetworkFaultsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveNetworkFaultsAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activenetworkfaults attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ActiveNetworkFaultsAttribute(decodedValue) } suspend fun readTestEventTriggersEnabledAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u - suspend fun subscribeTestEventTriggersEnabledAttribute( - minInterval: Int, - maxInterval: Int - ): Boolean { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Testeventtriggersenabled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(GeneralDiagnosticsCluster::class.java.name) const val CLUSTER_ID: UInt = 51u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupKeyManagementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupKeyManagementCluster.kt index 254d6a4bf63803..a934a8e3bb3c59 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupKeyManagementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupKeyManagementCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class GroupKeyManagementCluster( private val controller: MatterController, @@ -44,169 +53,557 @@ class GroupKeyManagementCluster( groupKeySet: GroupKeyManagementClusterGroupKeySetStruct, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_KEY_SET_REQ: Int = 0 + groupKeySet.toTlv(ContextSpecificTag(TAG_GROUP_KEY_SET_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun keySetRead( groupKeySetID: UShort, timedInvokeTimeoutMs: Int? = null ): KeySetReadResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_KEY_SET_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_KEY_SET_I_D_REQ), groupKeySetID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_GROUP_KEY_SET: Int = 0 + var groupKeySet_decoded: GroupKeyManagementClusterGroupKeySetStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_GROUP_KEY_SET)) { + groupKeySet_decoded = GroupKeyManagementClusterGroupKeySetStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (groupKeySet_decoded == null) { + throw IllegalStateException("groupKeySet not found in TLV") } + + tlvReader.exitContainer() + + return KeySetReadResponse(groupKeySet_decoded) } suspend fun keySetRemove(groupKeySetID: UShort, timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_KEY_SET_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_KEY_SET_I_D_REQ), groupKeySetID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun keySetReadAllIndices( timedInvokeTimeoutMs: Int? = null ): KeySetReadAllIndicesResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_GROUP_KEY_SET_I_DS: Int = 0 + var groupKeySetIDs_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_GROUP_KEY_SET_I_DS)) { + groupKeySetIDs_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (groupKeySetIDs_decoded == null) { + throw IllegalStateException("groupKeySetIDs not found in TLV") } + + tlvReader.exitContainer() + + return KeySetReadAllIndicesResponse(groupKeySetIDs_decoded) } suspend fun readGroupKeyMapAttribute(): GroupKeyMapAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readGroupKeyMapAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): GroupKeyMapAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Groupkeymap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(GroupKeyManagementClusterGroupKeyMapStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return GroupKeyMapAttribute(decodedValue) } suspend fun writeGroupKeyMapAttribute( value: List, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } - } - - suspend fun subscribeGroupKeyMapAttribute( - minInterval: Int, - maxInterval: Int - ): GroupKeyMapAttribute { - // Implementation needs to be added here } suspend fun readGroupTableAttribute(): GroupTableAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun readGroupTableAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): GroupTableAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGroupTableAttribute( - minInterval: Int, - maxInterval: Int - ): GroupTableAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Grouptable attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(GroupKeyManagementClusterGroupInfoMapStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return GroupTableAttribute(decodedValue) } suspend fun readMaxGroupsPerFabricAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxgroupsperfabric attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeMaxGroupsPerFabricAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } suspend fun readMaxGroupKeysPerFabricAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMaxGroupKeysPerFabricAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxgroupkeysperfabric attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(GroupKeyManagementCluster::class.java.name) const val CLUSTER_ID: UInt = 63u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupsCluster.kt index 4858d7a68b38db..c6be6194873502 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GroupsCluster.kt @@ -17,17 +17,26 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class GroupsCluster(private val controller: MatterController, private val endpointId: UShort) { - class AddGroupResponse(val status: UInt, val groupID: UShort) + class AddGroupResponse(val status: UByte, val groupID: UShort) - class ViewGroupResponse(val status: UInt, val groupID: UShort, val groupName: String) + class ViewGroupResponse(val status: UByte, val groupID: UShort, val groupName: String) class GetGroupMembershipResponse(val capacity: UByte?, val groupList: List) - class RemoveGroupResponse(val status: UInt, val groupID: UShort) + class RemoveGroupResponse(val status: UByte, val groupID: UShort) class GeneratedCommandListAttribute(val value: List) @@ -42,56 +51,290 @@ class GroupsCluster(private val controller: MatterController, private val endpoi groupName: String, timedInvokeTimeoutMs: Int? = null ): AddGroupResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_GROUP_NAME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_NAME_REQ), groupName) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") } + + tlvReader.exitContainer() + + return AddGroupResponse(status_decoded, groupID_decoded) } suspend fun viewGroup(groupID: UShort, timedInvokeTimeoutMs: Int? = null): ViewGroupResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_GROUP_NAME: Int = 2 + var groupName_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_NAME)) { + groupName_decoded = tlvReader.getString(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + if (groupName_decoded == null) { + throw IllegalStateException("groupName not found in TLV") + } + + tlvReader.exitContainer() + + return ViewGroupResponse(status_decoded, groupID_decoded, groupName_decoded) } suspend fun getGroupMembership( groupList: List, timedInvokeTimeoutMs: Int? = null ): GetGroupMembershipResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_GROUP_LIST_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_GROUP_LIST_REQ)) + for (item in groupList.iterator()) { + tlvWriter.put(AnonymousTag, item) } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_CAPACITY: Int = 0 + var capacity_decoded: UByte? = null + + val TAG_GROUP_LIST: Int = 1 + var groupList_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_CAPACITY)) { + capacity_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_GROUP_LIST)) { + groupList_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (groupList_decoded == null) { + throw IllegalStateException("groupList not found in TLV") + } + + tlvReader.exitContainer() + + return GetGroupMembershipResponse(capacity_decoded, groupList_decoded) } suspend fun removeGroup(groupID: UShort, timedInvokeTimeoutMs: Int? = null): RemoveGroupResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + tlvReader.exitContainer() + + return RemoveGroupResponse(status_decoded, groupID_decoded) } suspend fun removeAllGroups(timedInvokeTimeoutMs: Int? = null) { - val commandId = 4L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun addGroupIfIdentifying( @@ -99,81 +342,278 @@ class GroupsCluster(private val controller: MatterController, private val endpoi groupName: String, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_GROUP_NAME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_NAME_REQ), groupName) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readNameSupportAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeNameSupportAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Namesupport attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(GroupsCluster::class.java.name) const val CLUSTER_ID: UInt = 4u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/HepaFilterMonitoringCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/HepaFilterMonitoringCluster.kt index 465dd38a9397a5..2d0a5404618c3f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/HepaFilterMonitoringCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/HepaFilterMonitoringCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class HepaFilterMonitoringCluster( private val controller: MatterController, @@ -39,135 +47,507 @@ class HepaFilterMonitoringCluster( class AttributeListAttribute(val value: List) suspend fun resetCondition(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun readConditionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun readConditionAttribute(): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeConditionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readDegradationDirectionAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Condition attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeDegradationDirectionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readDegradationDirectionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Degradationdirection attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readChangeIndicationAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeChangeIndicationAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Changeindication attribute not found in response" } - suspend fun readInPlaceIndicatorAttribute(): Boolean { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeInPlaceIndicatorAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readInPlaceIndicatorAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Inplaceindicator attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readLastChangedTimeAttribute(): LastChangedTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun writeLastChangedTimeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lastchangedtime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LastChangedTimeAttribute(decodedValue) } - suspend fun subscribeLastChangedTimeAttribute( - minInterval: Int, - maxInterval: Int - ): LastChangedTimeAttribute { - // Implementation needs to be added here + suspend fun writeLastChangedTimeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readReplacementProductListAttribute(): ReplacementProductListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeReplacementProductListAttribute( - minInterval: Int, - maxInterval: Int - ): ReplacementProductListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Replacementproductlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + HepaFilterMonitoringClusterReplacementProductStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ReplacementProductListAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(HepaFilterMonitoringCluster::class.java.name) const val CLUSTER_ID: UInt = 113u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IcdManagementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IcdManagementCluster.kt index c70094f9e08ec9..62504f6151ffc4 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IcdManagementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IcdManagementCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class IcdManagementCluster( private val controller: MatterController, @@ -47,13 +56,61 @@ class IcdManagementCluster( verificationKey: ByteArray?, timedInvokeTimeoutMs: Int? = null ): RegisterClientResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_CHECK_IN_NODE_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D_REQ), checkInNodeID) + + val TAG_MONITORED_SUBJECT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_MONITORED_SUBJECT_REQ), monitoredSubject) + + val TAG_KEY_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_KEY_REQ), key) + + val TAG_VERIFICATION_KEY_REQ: Int = 3 + verificationKey?.let { + tlvWriter.put(ContextSpecificTag(TAG_VERIFICATION_KEY_REQ), verificationKey) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_I_C_D_COUNTER: Int = 0 + var ICDCounter_decoded: UInt? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_I_C_D_COUNTER)) { + ICDCounter_decoded = tlvReader.getUInt(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (ICDCounter_decoded == null) { + throw IllegalStateException("ICDCounter not found in TLV") + } + + tlvReader.exitContainer() + + return RegisterClientResponse(ICDCounter_decoded) } suspend fun unregisterClient( @@ -61,165 +118,574 @@ class IcdManagementCluster( verificationKey: ByteArray?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_CHECK_IN_NODE_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_CHECK_IN_NODE_I_D_REQ), checkInNodeID) + + val TAG_VERIFICATION_KEY_REQ: Int = 1 + verificationKey?.let { + tlvWriter.put(ContextSpecificTag(TAG_VERIFICATION_KEY_REQ), verificationKey) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stayActiveRequest(timedInvokeTimeoutMs: Int? = null): StayActiveResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_PROMISED_ACTIVE_DURATION: Int = 0 + var promisedActiveDuration_decoded: UInt? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_PROMISED_ACTIVE_DURATION)) { + promisedActiveDuration_decoded = tlvReader.getUInt(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (promisedActiveDuration_decoded == null) { + throw IllegalStateException("promisedActiveDuration not found in TLV") } + + tlvReader.exitContainer() + + return StayActiveResponse(promisedActiveDuration_decoded) } suspend fun readIdleModeDurationAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeIdleModeDurationAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Idlemodeduration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readActiveModeDurationAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeActiveModeDurationAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activemodeduration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readActiveModeThresholdAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeActiveModeThresholdAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activemodethreshold attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readRegisteredClientsAttribute(): RegisteredClientsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun readRegisteredClientsAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): RegisteredClientsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeRegisteredClientsAttribute( - minInterval: Int, - maxInterval: Int - ): RegisteredClientsAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readICDCounterAttribute(): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeICDCounterAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readClientsSupportedPerFabricAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Registeredclients attribute not found in response" } - suspend fun subscribeClientsSupportedPerFabricAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(IcdManagementClusterMonitoringRegistrationStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return RegisteredClientsAttribute(decodedValue) } - suspend fun readUserActiveModeTriggerHintAttribute(): UInt { - // Implementation needs to be added here + suspend fun readICDCounterAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Icdcounter attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeUserActiveModeTriggerHintAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here + suspend fun readClientsSupportedPerFabricAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clientssupportedperfabric attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readUserActiveModeTriggerInstructionAttribute(): CharString { - // Implementation needs to be added here + suspend fun readUserActiveModeTriggerHintAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Useractivemodetriggerhint attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeUserActiveModeTriggerInstructionAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here + suspend fun readUserActiveModeTriggerInstructionAttribute(): String? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Useractivemodetriggerinstruction attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(IcdManagementCluster::class.java.name) const val CLUSTER_ID: UInt = 70u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IdentifyCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IdentifyCluster.kt index 72ec3e94ee2642..6eb21032f16ff1 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IdentifyCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IdentifyCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class IdentifyCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -30,111 +39,378 @@ class IdentifyCluster(private val controller: MatterController, private val endp class AttributeListAttribute(val value: List) suspend fun identify(identifyTime: UShort, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_IDENTIFY_TIME_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_IDENTIFY_TIME_REQ), identifyTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun triggerEffect( - effectIdentifier: UInt, - effectVariant: UInt, + effectIdentifier: UByte, + effectVariant: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 64L + val commandId: UInt = 64u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EFFECT_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_EFFECT_IDENTIFIER_REQ), effectIdentifier) + + val TAG_EFFECT_VARIANT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_EFFECT_VARIANT_REQ), effectVariant) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readIdentifyTimeAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun writeIdentifyTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Identifytime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } - suspend fun subscribeIdentifyTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun writeIdentifyTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readIdentifyTypeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Identifytype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun subscribeIdentifyTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(IdentifyCluster::class.java.name) const val CLUSTER_ID: UInt = 3u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IlluminanceMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IlluminanceMeasurementCluster.kt index d1067f466fcc0f..2869e97c2c2c52 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IlluminanceMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/IlluminanceMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class IlluminanceMeasurementCluster( private val controller: MatterController, @@ -30,7 +35,7 @@ class IlluminanceMeasurementCluster( class MaxMeasuredValueAttribute(val value: UShort?) - class LightSensorTypeAttribute(val value: UInt?) + class LightSensorTypeAttribute(val value: UByte?) class GeneratedCommandListAttribute(val value: List) @@ -41,115 +46,409 @@ class IlluminanceMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readToleranceAttribute(): UShort { - // Implementation needs to be added here + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } - suspend fun subscribeToleranceAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readToleranceAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tolerance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readLightSensorTypeAttribute(): LightSensorTypeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeLightSensorTypeAttribute( - minInterval: Int, - maxInterval: Int - ): LightSensorTypeAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lightsensortype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LightSensorTypeAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(IlluminanceMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1024u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/KeypadInputCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/KeypadInputCluster.kt index 365427acb053cc..cf9544f0313e58 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/KeypadInputCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/KeypadInputCluster.kt @@ -17,11 +17,20 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class KeypadInputCluster(private val controller: MatterController, private val endpointId: UShort) { - class SendKeyResponse(val status: UInt) + class SendKeyResponse(val status: UByte) class GeneratedCommandListAttribute(val value: List) @@ -31,74 +40,269 @@ class KeypadInputCluster(private val controller: MatterController, private val e class AttributeListAttribute(val value: List) - suspend fun sendKey(keyCode: UInt, timedInvokeTimeoutMs: Int? = null): SendKeyResponse { - val commandId = 0L + suspend fun sendKey(keyCode: UByte, timedInvokeTimeoutMs: Int? = null): SendKeyResponse { + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_KEY_CODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_KEY_CODE_REQ), keyCode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return SendKeyResponse(status_decoded) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(KeypadInputCluster::class.java.name) const val CLUSTER_ID: UInt = 1289u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryDryerControlsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryDryerControlsCluster.kt index 7b05c8dc8a4b6c..6c4cf76b269053 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryDryerControlsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryDryerControlsCluster.kt @@ -17,16 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class LaundryDryerControlsCluster( private val controller: MatterController, private val endpointId: UShort ) { - class SupportedDrynessLevelsAttribute(val value: List) + class SupportedDrynessLevelsAttribute(val value: List) - class SelectedDrynessLevelAttribute(val value: UInt?) + class SelectedDrynessLevelAttribute(val value: UByte?) class GeneratedCommandListAttribute(val value: List) @@ -37,93 +44,338 @@ class LaundryDryerControlsCluster( class AttributeListAttribute(val value: List) suspend fun readSupportedDrynessLevelsAttribute(): SupportedDrynessLevelsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSupportedDrynessLevelsAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedDrynessLevelsAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supporteddrynesslevels attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return SupportedDrynessLevelsAttribute(decodedValue) } suspend fun readSelectedDrynessLevelAttribute(): SelectedDrynessLevelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun writeSelectedDrynessLevelAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Selecteddrynesslevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SelectedDrynessLevelAttribute(decodedValue) } - suspend fun subscribeSelectedDrynessLevelAttribute( - minInterval: Int, - maxInterval: Int - ): SelectedDrynessLevelAttribute { - // Implementation needs to be added here + suspend fun writeSelectedDrynessLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(LaundryDryerControlsCluster::class.java.name) const val CLUSTER_ID: UInt = 74u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherControlsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherControlsCluster.kt index e7d246777e25c2..bf0909105c0b5a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherControlsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherControlsCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class LaundryWasherControlsCluster( private val controller: MatterController, @@ -28,7 +35,7 @@ class LaundryWasherControlsCluster( class SpinSpeedCurrentAttribute(val value: UByte?) - class SupportedRinsesAttribute(val value: List?) + class SupportedRinsesAttribute(val value: List?) class GeneratedCommandListAttribute(val value: List) @@ -39,120 +46,466 @@ class LaundryWasherControlsCluster( class AttributeListAttribute(val value: List) suspend fun readSpinSpeedsAttribute(): SpinSpeedsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSpinSpeedsAttribute( - minInterval: Int, - maxInterval: Int - ): SpinSpeedsAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Spinspeeds attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return SpinSpeedsAttribute(decodedValue) } suspend fun readSpinSpeedCurrentAttribute(): SpinSpeedCurrentAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Spinspeedcurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SpinSpeedCurrentAttribute(decodedValue) } suspend fun writeSpinSpeedCurrentAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 1u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeSpinSpeedCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): SpinSpeedCurrentAttribute { - // Implementation needs to be added here - } + suspend fun readNumberOfRinsesAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u - suspend fun readNumberOfRinsesAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNumberOfRinsesAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofrinses attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeNumberOfRinsesAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeNumberOfRinsesAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readSupportedRinsesAttribute(): SupportedRinsesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSupportedRinsesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedRinsesAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedrinses attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return SupportedRinsesAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(LaundryWasherControlsCluster::class.java.name) const val CLUSTER_ID: UInt = 83u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherModeCluster.kt index 1145e4b1d8b056..ed958b80fab730 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LaundryWasherModeCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class LaundryWasherModeCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ChangeToModeResponse(val status: UInt, val statusText: String?) + class ChangeToModeResponse(val status: UByte, val statusText: String?) class SupportedModesAttribute(val value: List) @@ -44,127 +53,520 @@ class LaundryWasherModeCluster( newMode: UByte, timedInvokeTimeoutMs: Int? = null ): ChangeToModeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(LaundryWasherModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) } - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpModeAttribute { - // Implementation needs to be added here + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(LaundryWasherModeCluster::class.java.name) const val CLUSTER_ID: UInt = 81u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LevelControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LevelControlCluster.kt index a20be7c6f73199..987db484d76e0c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LevelControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LevelControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class LevelControlCluster( private val controller: MatterController, @@ -47,376 +56,1357 @@ class LevelControlCluster( suspend fun moveToLevel( level: UByte, transitionTime: UShort?, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LEVEL_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LEVEL_REQ), level) + + val TAG_TRANSITION_TIME_REQ: Int = 1 + transitionTime?.let { + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) } + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun move( - moveMode: UInt, + moveMode: UByte, rate: UByte?, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MOVE_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MOVE_MODE_REQ), moveMode) + + val TAG_RATE_REQ: Int = 1 + rate?.let { tlvWriter.put(ContextSpecificTag(TAG_RATE_REQ), rate) } + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun step( - stepMode: UInt, + stepMode: UByte, stepSize: UByte, transitionTime: UShort?, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_STEP_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_MODE_REQ), stepMode) + + val TAG_STEP_SIZE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_SIZE_REQ), stepSize) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_TRANSITION_TIME_REQ: Int = 2 + transitionTime?.let { + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) } + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun stop(optionsMask: UInt, optionsOverride: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L + suspend fun stop(optionsMask: UByte, optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null) { + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPTIONS_MASK_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveToLevelWithOnOff( level: UByte, transitionTime: UShort?, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_LEVEL_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LEVEL_REQ), level) + + val TAG_TRANSITION_TIME_REQ: Int = 1 + transitionTime?.let { + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) } + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveWithOnOff( - moveMode: UInt, + moveMode: UByte, rate: UByte?, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MOVE_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MOVE_MODE_REQ), moveMode) + + val TAG_RATE_REQ: Int = 1 + rate?.let { tlvWriter.put(ContextSpecificTag(TAG_RATE_REQ), rate) } + + val TAG_OPTIONS_MASK_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stepWithOnOff( - stepMode: UInt, + stepMode: UByte, stepSize: UByte, transitionTime: UShort?, - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_STEP_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STEP_MODE_REQ), stepMode) + + val TAG_STEP_SIZE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_STEP_SIZE_REQ), stepSize) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + transitionTime?.let { + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) } + + val TAG_OPTIONS_MASK_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stopWithOnOff( - optionsMask: UInt, - optionsOverride: UInt, + optionsMask: UByte, + optionsOverride: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPTIONS_MASK_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_MASK_REQ), optionsMask) + + val TAG_OPTIONS_OVERRIDE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_OPTIONS_OVERRIDE_REQ), optionsOverride) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun moveToClosestFrequency(frequency: UShort, timedInvokeTimeoutMs: Int? = null) { - val commandId = 8L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_FREQUENCY_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_FREQUENCY_REQ), frequency) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readCurrentLevelAttribute(): CurrentLevelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeCurrentLevelAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentLevelAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRemainingTimeAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRemainingTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readMinLevelAttribute(): UByte { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMinLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readMaxLevelAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeMaxLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return CurrentLevelAttribute(decodedValue) } - suspend fun readCurrentFrequencyAttribute(): UShort { - // Implementation needs to be added here + suspend fun readRemainingTimeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Remainingtime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeCurrentFrequencyAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readMinLevelAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMinFrequencyAttribute(): UShort { - // Implementation needs to be added here + suspend fun readMaxLevelAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMinFrequencyAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readCurrentFrequencyAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentfrequency attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMaxFrequencyAttribute(): UShort { - // Implementation needs to be added here + suspend fun readMinFrequencyAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minfrequency attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMaxFrequencyAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readMaxFrequencyAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxfrequency attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readOptionsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 15u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeOptionsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeOptionsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Options attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readOnOffTransitionTimeAttribute(): UShort { - // Implementation needs to be added here + suspend fun writeOptionsAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 15u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun writeOnOffTransitionTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readOnOffTransitionTimeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onofftransitiontime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeOnOffTransitionTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun writeOnOffTransitionTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnLevelAttribute(): OnLevelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 17u - suspend fun writeOnLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnLevelAttribute(decodedValue) } - suspend fun subscribeOnLevelAttribute(minInterval: Int, maxInterval: Int): OnLevelAttribute { - // Implementation needs to be added here + suspend fun writeOnLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 17u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnTransitionTimeAttribute(): OnTransitionTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 18u - suspend fun writeOnTransitionTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ontransitiontime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnTransitionTimeAttribute(decodedValue) } - suspend fun subscribeOnTransitionTimeAttribute( - minInterval: Int, - maxInterval: Int - ): OnTransitionTimeAttribute { - // Implementation needs to be added here + suspend fun writeOnTransitionTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 18u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOffTransitionTimeAttribute(): OffTransitionTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 19u - suspend fun writeOffTransitionTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Offtransitiontime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OffTransitionTimeAttribute(decodedValue) } - suspend fun subscribeOffTransitionTimeAttribute( - minInterval: Int, - maxInterval: Int - ): OffTransitionTimeAttribute { - // Implementation needs to be added here + suspend fun writeOffTransitionTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 19u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readDefaultMoveRateAttribute(): DefaultMoveRateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 20u - suspend fun writeDefaultMoveRateAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Defaultmoverate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return DefaultMoveRateAttribute(decodedValue) } - suspend fun subscribeDefaultMoveRateAttribute( - minInterval: Int, - maxInterval: Int - ): DefaultMoveRateAttribute { - // Implementation needs to be added here + suspend fun writeDefaultMoveRateAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 20u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readStartUpCurrentLevelAttribute(): StartUpCurrentLevelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16384u - suspend fun writeStartUpCurrentLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupcurrentlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpCurrentLevelAttribute(decodedValue) } - suspend fun subscribeStartUpCurrentLevelAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpCurrentLevelAttribute { - // Implementation needs to be added here + suspend fun writeStartUpCurrentLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16384u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(LevelControlCluster::class.java.name) const val CLUSTER_ID: UInt = 8u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LocalizationConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LocalizationConfigurationCluster.kt index 4cd978399d01d7..bc6fd04679c72b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LocalizationConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LocalizationConfigurationCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class LocalizationConfigurationCluster( private val controller: MatterController, @@ -34,91 +41,333 @@ class LocalizationConfigurationCluster( class AttributeListAttribute(val value: List) - suspend fun readActiveLocaleAttribute(): CharString { - // Implementation needs to be added here - } + suspend fun readActiveLocaleAttribute(): String { + val ATTRIBUTE_ID: UInt = 0u - suspend fun writeActiveLocaleAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activelocale attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } - suspend fun subscribeActiveLocaleAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun writeActiveLocaleAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readSupportedLocalesAttribute(): SupportedLocalesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeSupportedLocalesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedLocalesAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedlocales attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return SupportedLocalesAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(LocalizationConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 43u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LowPowerCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LowPowerCluster.kt index 74390f3a6fb4dd..cd6de47d3fe78b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LowPowerCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/LowPowerCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class LowPowerCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -30,73 +38,241 @@ class LowPowerCluster(private val controller: MatterController, private val endp class AttributeListAttribute(val value: List) suspend fun sleep(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(LowPowerCluster::class.java.name) const val CLUSTER_ID: UInt = 1288u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaInputCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaInputCluster.kt index 97ba8c68b95619..70ee279e2f31c3 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaInputCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaInputCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class MediaInputCluster(private val controller: MatterController, private val endpointId: UShort) { class InputListAttribute(val value: List) @@ -32,119 +41,379 @@ class MediaInputCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun selectInput(index: UByte, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_INDEX_REQ), index) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun showInputStatus(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun hideInputStatus(timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun renameInput(index: UByte, name: String, timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_INDEX_REQ), index) + + val TAG_NAME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_NAME_REQ), name) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readInputListAttribute(): InputListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeInputListAttribute(minInterval: Int, maxInterval: Int): InputListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Inputlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(MediaInputClusterInputInfoStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return InputListAttribute(decodedValue) } suspend fun readCurrentInputAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeCurrentInputAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentinput attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(MediaInputCluster::class.java.name) const val CLUSTER_ID: UInt = 1287u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaPlaybackCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaPlaybackCluster.kt index 486e87eff60d06..b42bc7d2ada373 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaPlaybackCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaPlaybackCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class MediaPlaybackCluster( private val controller: MatterController, private val endpointId: UShort ) { - class PlaybackResponse(val status: UInt, val data: String?) + class PlaybackResponse(val status: UByte, val data: String?) class StartTimeAttribute(val value: ULong?) @@ -53,125 +62,711 @@ class MediaPlaybackCluster( class AttributeListAttribute(val value: List) suspend fun play(timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun pause(timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun stop(timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun startOver(timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun previous(timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun next(timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun rewind( audioAdvanceUnmuted: Boolean?, timedInvokeTimeoutMs: Int? = null ): PlaybackResponse { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_AUDIO_ADVANCE_UNMUTED_REQ: Int = 0 + audioAdvanceUnmuted?.let { + tlvWriter.put(ContextSpecificTag(TAG_AUDIO_ADVANCE_UNMUTED_REQ), audioAdvanceUnmuted) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun fastForward( audioAdvanceUnmuted: Boolean?, timedInvokeTimeoutMs: Int? = null ): PlaybackResponse { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_AUDIO_ADVANCE_UNMUTED_REQ: Int = 0 + audioAdvanceUnmuted?.let { + tlvWriter.put(ContextSpecificTag(TAG_AUDIO_ADVANCE_UNMUTED_REQ), audioAdvanceUnmuted) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun skipForward( deltaPositionMilliseconds: ULong, timedInvokeTimeoutMs: Int? = null ): PlaybackResponse { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DELTA_POSITION_MILLISECONDS_REQ: Int = 0 + tlvWriter.put( + ContextSpecificTag(TAG_DELTA_POSITION_MILLISECONDS_REQ), + deltaPositionMilliseconds + ) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun skipBackward( deltaPositionMilliseconds: ULong, timedInvokeTimeoutMs: Int? = null ): PlaybackResponse { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DELTA_POSITION_MILLISECONDS_REQ: Int = 0 + tlvWriter.put( + ContextSpecificTag(TAG_DELTA_POSITION_MILLISECONDS_REQ), + deltaPositionMilliseconds + ) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun seek(position: ULong, timedInvokeTimeoutMs: Int? = null): PlaybackResponse { - val commandId = 11L + val commandId: UInt = 11u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_POSITION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_POSITION_REQ), position) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return PlaybackResponse(status_decoded, data_decoded) } suspend fun activateAudioTrack( @@ -179,202 +774,738 @@ class MediaPlaybackCluster( audioOutputIndex: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 12L + val commandId: UInt = 12u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TRACK_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TRACK_I_D_REQ), trackID) + + val TAG_AUDIO_OUTPUT_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_AUDIO_OUTPUT_INDEX_REQ), audioOutputIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun activateTextTrack(trackID: String, timedInvokeTimeoutMs: Int? = null) { - val commandId = 13L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 13u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TRACK_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TRACK_I_D_REQ), trackID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun deactivateTextTrack(timedInvokeTimeoutMs: Int? = null) { - val commandId = 14L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 14u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readCurrentStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun subscribeCurrentStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return decodedValue } suspend fun readStartTimeAttribute(): StartTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeStartTimeAttribute(minInterval: Int, maxInterval: Int): StartTimeAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Starttime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartTimeAttribute(decodedValue) } suspend fun readDurationAttribute(): DurationAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeDurationAttribute(minInterval: Int, maxInterval: Int): DurationAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Duration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return DurationAttribute(decodedValue) } suspend fun readSampledPositionAttribute(): SampledPositionAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeSampledPositionAttribute( - minInterval: Int, - maxInterval: Int - ): SampledPositionAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPlaybackSpeedAttribute(): Float { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sampledposition attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: MediaPlaybackClusterPlaybackPositionStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + MediaPlaybackClusterPlaybackPositionStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SampledPositionAttribute(decodedValue) } - suspend fun subscribePlaybackSpeedAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here + suspend fun readPlaybackSpeedAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Playbackspeed attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readSeekRangeEndAttribute(): SeekRangeEndAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSeekRangeEndAttribute( - minInterval: Int, - maxInterval: Int - ): SeekRangeEndAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Seekrangeend attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SeekRangeEndAttribute(decodedValue) } suspend fun readSeekRangeStartAttribute(): SeekRangeStartAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSeekRangeStartAttribute( - minInterval: Int, - maxInterval: Int - ): SeekRangeStartAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Seekrangestart attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SeekRangeStartAttribute(decodedValue) } suspend fun readActiveAudioTrackAttribute(): ActiveAudioTrackAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeActiveAudioTrackAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveAudioTrackAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activeaudiotrack attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: MediaPlaybackClusterTrackStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + MediaPlaybackClusterTrackStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ActiveAudioTrackAttribute(decodedValue) } suspend fun readAvailableAudioTracksAttribute(): AvailableAudioTracksAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAvailableAudioTracksAttribute( - minInterval: Int, - maxInterval: Int - ): AvailableAudioTracksAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Availableaudiotracks attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(MediaPlaybackClusterTrackStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return AvailableAudioTracksAttribute(decodedValue) } suspend fun readActiveTextTrackAttribute(): ActiveTextTrackAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeActiveTextTrackAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveTextTrackAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activetexttrack attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: MediaPlaybackClusterTrackStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + MediaPlaybackClusterTrackStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ActiveTextTrackAttribute(decodedValue) } suspend fun readAvailableTextTracksAttribute(): AvailableTextTracksAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAvailableTextTracksAttribute( - minInterval: Int, - maxInterval: Int - ): AvailableTextTracksAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Availabletexttracks attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(MediaPlaybackClusterTrackStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return AvailableTextTracksAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(MediaPlaybackCluster::class.java.name) const val CLUSTER_ID: UInt = 1286u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenControlCluster.kt index d655422ace9ae5..8361702af32b63 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class MicrowaveOvenControlCluster( private val controller: MatterController, @@ -38,123 +47,443 @@ class MicrowaveOvenControlCluster( powerSetting: UByte?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_COOK_MODE_REQ: Int = 0 + cookMode?.let { tlvWriter.put(ContextSpecificTag(TAG_COOK_MODE_REQ), cookMode) } + + val TAG_COOK_TIME_REQ: Int = 1 + cookTime?.let { tlvWriter.put(ContextSpecificTag(TAG_COOK_TIME_REQ), cookTime) } + + val TAG_POWER_SETTING_REQ: Int = 2 + powerSetting?.let { tlvWriter.put(ContextSpecificTag(TAG_POWER_SETTING_REQ), powerSetting) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun addMoreTime(timeToAdd: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TIME_TO_ADD_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TIME_TO_ADD_REQ), timeToAdd) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readCookTimeAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeCookTimeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Cooktime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readPowerSettingAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribePowerSettingAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMinPowerAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMinPowerAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readMaxPowerAttribute(): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powersetting attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeMaxPowerAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMinPowerAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minpower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readPowerStepAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMaxPowerAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxpower attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribePowerStepAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readPowerStepAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Powerstep attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(MicrowaveOvenControlCluster::class.java.name) const val CLUSTER_ID: UInt = 95u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt index 1483cab29ac970..a3a4c0a90577c4 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class MicrowaveOvenModeCluster( private val controller: MatterController, @@ -35,82 +40,290 @@ class MicrowaveOvenModeCluster( class AttributeListAttribute(val value: List) suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(MicrowaveOvenModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(MicrowaveOvenModeCluster::class.java.name) const val CLUSTER_ID: UInt = 94u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ModeSelectCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ModeSelectCluster.kt index 22e63c94a66d54..9503b01c620d6e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ModeSelectCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ModeSelectCluster.kt @@ -17,11 +17,20 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ModeSelectCluster(private val controller: MatterController, private val endpointId: UShort) { - class StandardNamespaceAttribute(val value: UInt?) + class StandardNamespaceAttribute(val value: UShort?) class SupportedModesAttribute(val value: List) @@ -38,146 +47,547 @@ class ModeSelectCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun changeToMode(newMode: UByte, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun readDescriptionAttribute(): String { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun readDescriptionAttribute(): CharString { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeDescriptionAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + requireNotNull(attributeData) { "Description attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun readStandardNamespaceAttribute(): StandardNamespaceAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeStandardNamespaceAttribute( - minInterval: Int, - maxInterval: Int - ): StandardNamespaceAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Standardnamespace attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StandardNamespaceAttribute(decodedValue) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ModeSelectClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) } - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpModeAttribute { - // Implementation needs to be added here + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ModeSelectCluster::class.java.name) const val CLUSTER_ID: UInt = 80u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NetworkCommissioningCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NetworkCommissioningCluster.kt index 053471c8a853f7..acbbbbaf3e8d79 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NetworkCommissioningCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NetworkCommissioningCluster.kt @@ -17,22 +17,31 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class NetworkCommissioningCluster( private val controller: MatterController, private val endpointId: UShort ) { class ScanNetworksResponse( - val networkingStatus: UInt, + val networkingStatus: UByte, val debugText: String?, val wiFiScanResults: List?, val threadScanResults: List? ) class NetworkConfigResponse( - val networkingStatus: UInt, + val networkingStatus: UByte, val debugText: String?, val networkIndex: UByte?, val clientIdentity: ByteArray?, @@ -40,7 +49,7 @@ class NetworkCommissioningCluster( ) class ConnectNetworkResponse( - val networkingStatus: UInt, + val networkingStatus: UByte, val debugText: String?, val errorValue: Int? ) @@ -49,13 +58,13 @@ class NetworkCommissioningCluster( class NetworksAttribute(val value: List) - class LastNetworkingStatusAttribute(val value: UInt?) + class LastNetworkingStatusAttribute(val value: UByte?) class LastNetworkIDAttribute(val value: ByteArray?) class LastConnectErrorValueAttribute(val value: Int?) - class SupportedWiFiBandsAttribute(val value: List?) + class SupportedWiFiBandsAttribute(val value: List?) class GeneratedCommandListAttribute(val value: List) @@ -70,13 +79,134 @@ class NetworkCommissioningCluster( breadcrumb: ULong?, timedInvokeTimeoutMs: Int? = null ): ScanNetworksResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_SSID_REQ: Int = 0 + ssid?.let { tlvWriter.put(ContextSpecificTag(TAG_SSID_REQ), ssid) } + + val TAG_BREADCRUMB_REQ: Int = 1 + breadcrumb?.let { tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NETWORKING_STATUS: Int = 0 + var networkingStatus_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + val TAG_WI_FI_SCAN_RESULTS: Int = 2 + var wiFiScanResults_decoded: List? = + null + + val TAG_THREAD_SCAN_RESULTS: Int = 3 + var threadScanResults_decoded: + List? = + null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NETWORKING_STATUS)) { + networkingStatus_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_WI_FI_SCAN_RESULTS)) { + wiFiScanResults_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add( + NetworkCommissioningClusterWiFiInterfaceScanResultStruct.fromTlv( + AnonymousTag, + tlvReader + ) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_THREAD_SCAN_RESULTS)) { + threadScanResults_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add( + NetworkCommissioningClusterThreadInterfaceScanResultStruct.fromTlv( + AnonymousTag, + tlvReader + ) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (networkingStatus_decoded == null) { + throw IllegalStateException("networkingStatus not found in TLV") } + + tlvReader.exitContainer() + + return ScanNetworksResponse( + networkingStatus_decoded, + debugText_decoded, + wiFiScanResults_decoded, + threadScanResults_decoded + ) } suspend fun addOrUpdateWiFiNetwork( @@ -88,13 +218,145 @@ class NetworkCommissioningCluster( possessionNonce: ByteArray?, timedInvokeTimeoutMs: Int? = null ): NetworkConfigResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_SSID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_SSID_REQ), ssid) + + val TAG_CREDENTIALS_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_CREDENTIALS_REQ), credentials) + + val TAG_BREADCRUMB_REQ: Int = 2 + breadcrumb?.let { tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) } + + val TAG_NETWORK_IDENTITY_REQ: Int = 3 + networkIdentity?.let { + tlvWriter.put(ContextSpecificTag(TAG_NETWORK_IDENTITY_REQ), networkIdentity) + } + + val TAG_CLIENT_IDENTIFIER_REQ: Int = 4 + clientIdentifier?.let { + tlvWriter.put(ContextSpecificTag(TAG_CLIENT_IDENTIFIER_REQ), clientIdentifier) + } + + val TAG_POSSESSION_NONCE_REQ: Int = 5 + possessionNonce?.let { + tlvWriter.put(ContextSpecificTag(TAG_POSSESSION_NONCE_REQ), possessionNonce) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NETWORKING_STATUS: Int = 0 + var networkingStatus_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + val TAG_NETWORK_INDEX: Int = 2 + var networkIndex_decoded: UByte? = null + + val TAG_CLIENT_IDENTITY: Int = 3 + var clientIdentity_decoded: ByteArray? = null + + val TAG_POSSESSION_SIGNATURE: Int = 4 + var possessionSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NETWORKING_STATUS)) { + networkingStatus_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NETWORK_INDEX)) { + networkIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CLIENT_IDENTITY)) { + clientIdentity_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_POSSESSION_SIGNATURE)) { + possessionSignature_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (networkingStatus_decoded == null) { + throw IllegalStateException("networkingStatus not found in TLV") } + + tlvReader.exitContainer() + + return NetworkConfigResponse( + networkingStatus_decoded, + debugText_decoded, + networkIndex_decoded, + clientIdentity_decoded, + possessionSignature_decoded + ) } suspend fun addOrUpdateThreadNetwork( @@ -102,13 +364,127 @@ class NetworkCommissioningCluster( breadcrumb: ULong?, timedInvokeTimeoutMs: Int? = null ): NetworkConfigResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPERATIONAL_DATASET_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_OPERATIONAL_DATASET_REQ), operationalDataset) + + val TAG_BREADCRUMB_REQ: Int = 1 + breadcrumb?.let { tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NETWORKING_STATUS: Int = 0 + var networkingStatus_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + val TAG_NETWORK_INDEX: Int = 2 + var networkIndex_decoded: UByte? = null + + val TAG_CLIENT_IDENTITY: Int = 3 + var clientIdentity_decoded: ByteArray? = null + + val TAG_POSSESSION_SIGNATURE: Int = 4 + var possessionSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NETWORKING_STATUS)) { + networkingStatus_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NETWORK_INDEX)) { + networkIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CLIENT_IDENTITY)) { + clientIdentity_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_POSSESSION_SIGNATURE)) { + possessionSignature_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (networkingStatus_decoded == null) { + throw IllegalStateException("networkingStatus not found in TLV") } + + tlvReader.exitContainer() + + return NetworkConfigResponse( + networkingStatus_decoded, + debugText_decoded, + networkIndex_decoded, + clientIdentity_decoded, + possessionSignature_decoded + ) } suspend fun removeNetwork( @@ -116,13 +492,127 @@ class NetworkCommissioningCluster( breadcrumb: ULong?, timedInvokeTimeoutMs: Int? = null ): NetworkConfigResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NETWORK_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NETWORK_I_D_REQ), networkID) + + val TAG_BREADCRUMB_REQ: Int = 1 + breadcrumb?.let { tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NETWORKING_STATUS: Int = 0 + var networkingStatus_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + val TAG_NETWORK_INDEX: Int = 2 + var networkIndex_decoded: UByte? = null + + val TAG_CLIENT_IDENTITY: Int = 3 + var clientIdentity_decoded: ByteArray? = null + + val TAG_POSSESSION_SIGNATURE: Int = 4 + var possessionSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NETWORKING_STATUS)) { + networkingStatus_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NETWORK_INDEX)) { + networkIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CLIENT_IDENTITY)) { + clientIdentity_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_POSSESSION_SIGNATURE)) { + possessionSignature_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (networkingStatus_decoded == null) { + throw IllegalStateException("networkingStatus not found in TLV") } + + tlvReader.exitContainer() + + return NetworkConfigResponse( + networkingStatus_decoded, + debugText_decoded, + networkIndex_decoded, + clientIdentity_decoded, + possessionSignature_decoded + ) } suspend fun connectNetwork( @@ -130,13 +620,88 @@ class NetworkCommissioningCluster( breadcrumb: ULong?, timedInvokeTimeoutMs: Int? = null ): ConnectNetworkResponse { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NETWORK_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NETWORK_I_D_REQ), networkID) + + val TAG_BREADCRUMB_REQ: Int = 1 + breadcrumb?.let { tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NETWORKING_STATUS: Int = 0 + var networkingStatus_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + val TAG_ERROR_VALUE: Int = 2 + var errorValue_decoded: Int? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NETWORKING_STATUS)) { + networkingStatus_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_ERROR_VALUE)) { + errorValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getInt(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (networkingStatus_decoded == null) { + throw IllegalStateException("networkingStatus not found in TLV") } + + tlvReader.exitContainer() + + return ConnectNetworkResponse(networkingStatus_decoded, debugText_decoded, errorValue_decoded) } suspend fun reorderNetwork( @@ -145,13 +710,130 @@ class NetworkCommissioningCluster( breadcrumb: ULong?, timedInvokeTimeoutMs: Int? = null ): NetworkConfigResponse { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NETWORK_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NETWORK_I_D_REQ), networkID) + + val TAG_NETWORK_INDEX_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_NETWORK_INDEX_REQ), networkIndex) + + val TAG_BREADCRUMB_REQ: Int = 2 + breadcrumb?.let { tlvWriter.put(ContextSpecificTag(TAG_BREADCRUMB_REQ), breadcrumb) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NETWORKING_STATUS: Int = 0 + var networkingStatus_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 1 + var debugText_decoded: String? = null + + val TAG_NETWORK_INDEX: Int = 2 + var networkIndex_decoded: UByte? = null + + val TAG_CLIENT_IDENTITY: Int = 3 + var clientIdentity_decoded: ByteArray? = null + + val TAG_POSSESSION_SIGNATURE: Int = 4 + var possessionSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NETWORKING_STATUS)) { + networkingStatus_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NETWORK_INDEX)) { + networkIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_CLIENT_IDENTITY)) { + clientIdentity_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_POSSESSION_SIGNATURE)) { + possessionSignature_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (networkingStatus_decoded == null) { + throw IllegalStateException("networkingStatus not found in TLV") } + + tlvReader.exitContainer() + + return NetworkConfigResponse( + networkingStatus_decoded, + debugText_decoded, + networkIndex_decoded, + clientIdentity_decoded, + possessionSignature_decoded + ) } suspend fun queryIdentity( @@ -159,184 +841,729 @@ class NetworkCommissioningCluster( possessionNonce: ByteArray?, timedInvokeTimeoutMs: Int? = null ): QueryIdentityResponse { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_KEY_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_KEY_IDENTIFIER_REQ), keyIdentifier) + + val TAG_POSSESSION_NONCE_REQ: Int = 1 + possessionNonce?.let { + tlvWriter.put(ContextSpecificTag(TAG_POSSESSION_NONCE_REQ), possessionNonce) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_IDENTITY: Int = 0 + var identity_decoded: ByteArray? = null + + val TAG_POSSESSION_SIGNATURE: Int = 1 + var possessionSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_IDENTITY)) { + identity_decoded = tlvReader.getByteArray(tag) + } + + if (tag == ContextSpecificTag(TAG_POSSESSION_SIGNATURE)) { + possessionSignature_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (identity_decoded == null) { + throw IllegalStateException("identity not found in TLV") } + + tlvReader.exitContainer() + + return QueryIdentityResponse(identity_decoded, possessionSignature_decoded) } suspend fun readMaxNetworksAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeMaxNetworksAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxnetworks attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readNetworksAttribute(): NetworksAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeNetworksAttribute(minInterval: Int, maxInterval: Int): NetworksAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readScanMaxTimeSecondsAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeScanMaxTimeSecondsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Networks attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(NetworkCommissioningClusterNetworkInfoStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return NetworksAttribute(decodedValue) } - suspend fun readConnectMaxTimeSecondsAttribute(): UByte { - // Implementation needs to be added here + suspend fun readScanMaxTimeSecondsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scanmaxtimeseconds attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeConnectMaxTimeSecondsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readConnectMaxTimeSecondsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Connectmaxtimeseconds attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readInterfaceEnabledAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun writeInterfaceEnabledAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Interfaceenabled attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } - suspend fun subscribeInterfaceEnabledAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun writeInterfaceEnabledAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readLastNetworkingStatusAttribute(): LastNetworkingStatusAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeLastNetworkingStatusAttribute( - minInterval: Int, - maxInterval: Int - ): LastNetworkingStatusAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lastnetworkingstatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LastNetworkingStatusAttribute(decodedValue) } suspend fun readLastNetworkIDAttribute(): LastNetworkIDAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeLastNetworkIDAttribute( - minInterval: Int, - maxInterval: Int - ): LastNetworkIDAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lastnetworkid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LastNetworkIDAttribute(decodedValue) } suspend fun readLastConnectErrorValueAttribute(): LastConnectErrorValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeLastConnectErrorValueAttribute( - minInterval: Int, - maxInterval: Int - ): LastConnectErrorValueAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Lastconnecterrorvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int? = + if (!tlvReader.isNull()) { + tlvReader.getInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LastConnectErrorValueAttribute(decodedValue) } suspend fun readSupportedWiFiBandsAttribute(): SupportedWiFiBandsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u - suspend fun subscribeSupportedWiFiBandsAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedWiFiBandsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readSupportedThreadFeaturesAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeSupportedThreadFeaturesAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedwifibands attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return SupportedWiFiBandsAttribute(decodedValue) } - suspend fun readThreadVersionAttribute(): UShort { - // Implementation needs to be added here + suspend fun readSupportedThreadFeaturesAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedthreadfeatures attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeThreadVersionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readThreadVersionAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Threadversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(NetworkCommissioningCluster::class.java.name) const val CLUSTER_ID: UInt = 49u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NitrogenDioxideConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NitrogenDioxideConcentrationMeasurementCluster.kt index eb911e990eaf8f..1bd7241a9ee473 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NitrogenDioxideConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NitrogenDioxideConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class NitrogenDioxideConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,643 @@ class NitrogenDioxideConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger(NitrogenDioxideConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1043u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OccupancySensingCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OccupancySensingCluster.kt index 07cb5e7d9ab25d..a3fce8d94d8c56 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OccupancySensingCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OccupancySensingCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OccupancySensingCluster( private val controller: MatterController, @@ -33,288 +40,1057 @@ class OccupancySensingCluster( class AttributeListAttribute(val value: List) suspend fun readOccupancyAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeOccupancyAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Occupancy attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOccupancySensorTypeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeOccupancySensorTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupancysensortype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOccupancySensorTypeBitmapAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeOccupancySensorTypeBitmapAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupancysensortypebitmap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readPIROccupiedToUnoccupiedDelayAttribute(): UShort { - // Implementation needs to be added here + suspend fun readPIROccupiedToUnoccupiedDelayAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Piroccupiedtounoccupieddelay attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writePIROccupiedToUnoccupiedDelayAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribePIROccupiedToUnoccupiedDelayAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readPIRUnoccupiedToOccupiedDelayAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 17u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readPIRUnoccupiedToOccupiedDelayAttribute(): UShort { - // Implementation needs to be added here + requireNotNull(attributeData) { "Pirunoccupiedtooccupieddelay attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writePIRUnoccupiedToOccupiedDelayAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 17u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribePIRUnoccupiedToOccupiedDelayAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readPIRUnoccupiedToOccupiedThresholdAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 18u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readPIRUnoccupiedToOccupiedThresholdAttribute(): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Pirunoccupiedtooccupiedthreshold attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writePIRUnoccupiedToOccupiedThresholdAttribute( value: UByte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 18u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribePIRUnoccupiedToOccupiedThresholdAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + suspend fun readUltrasonicOccupiedToUnoccupiedDelayAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 32u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readUltrasonicOccupiedToUnoccupiedDelayAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Ultrasonicoccupiedtounoccupieddelay attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeUltrasonicOccupiedToUnoccupiedDelayAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 32u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeUltrasonicOccupiedToUnoccupiedDelayAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readUltrasonicUnoccupiedToOccupiedDelayAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Ultrasonicunoccupiedtooccupieddelay attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun readUltrasonicUnoccupiedToOccupiedDelayAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } suspend fun writeUltrasonicUnoccupiedToOccupiedDelayAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 33u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeUltrasonicUnoccupiedToOccupiedDelayAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readUltrasonicUnoccupiedToOccupiedThresholdAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readUltrasonicUnoccupiedToOccupiedThresholdAttribute(): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Ultrasonicunoccupiedtooccupiedthreshold attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeUltrasonicUnoccupiedToOccupiedThresholdAttribute( value: UByte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 34u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeUltrasonicUnoccupiedToOccupiedThresholdAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + suspend fun readPhysicalContactOccupiedToUnoccupiedDelayAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readPhysicalContactOccupiedToUnoccupiedDelayAttribute(): UShort { - // Implementation needs to be added here + requireNotNull(attributeData) { + "Physicalcontactoccupiedtounoccupieddelay attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writePhysicalContactOccupiedToUnoccupiedDelayAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 48u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribePhysicalContactOccupiedToUnoccupiedDelayAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readPhysicalContactUnoccupiedToOccupiedDelayAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readPhysicalContactUnoccupiedToOccupiedDelayAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Physicalcontactunoccupiedtooccupieddelay attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writePhysicalContactUnoccupiedToOccupiedDelayAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 49u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribePhysicalContactUnoccupiedToOccupiedDelayAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + suspend fun readPhysicalContactUnoccupiedToOccupiedThresholdAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun readPhysicalContactUnoccupiedToOccupiedThresholdAttribute(): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Physicalcontactunoccupiedtooccupiedthreshold attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writePhysicalContactUnoccupiedToOccupiedThresholdAttribute( value: UByte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val ATTRIBUTE_ID: UInt = 50u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) - suspend fun subscribePhysicalContactUnoccupiedToOccupiedThresholdAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OccupancySensingCluster::class.java.name) const val CLUSTER_ID: UInt = 1030u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt index 76a0996babd8e3..ffdb73b7e2255c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt @@ -17,11 +17,20 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OnOffCluster(private val controller: MatterController, private val endpointId: UShort) { - class StartUpOnOffAttribute(val value: UInt?) + class StartUpOnOffAttribute(val value: UByte?) class GeneratedCommandListAttribute(val value: List) @@ -32,199 +41,671 @@ class OnOffCluster(private val controller: MatterController, private val endpoin class AttributeListAttribute(val value: List) suspend fun off(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun on(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun toggle(timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun offWithEffect( - effectIdentifier: UInt, - effectVariant: UInt, + effectIdentifier: UByte, + effectVariant: UByte, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 64L + val commandId: UInt = 64u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_EFFECT_IDENTIFIER_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_EFFECT_IDENTIFIER_REQ), effectIdentifier) + + val TAG_EFFECT_VARIANT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_EFFECT_VARIANT_REQ), effectVariant) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun onWithRecallGlobalScene(timedInvokeTimeoutMs: Int? = null) { - val commandId = 65L + val commandId: UInt = 65u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun onWithTimedOff( - onOffControl: UInt, + onOffControl: UByte, onTime: UShort, offWaitTime: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 66L + val commandId: UInt = 66u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ON_OFF_CONTROL_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ON_OFF_CONTROL_REQ), onOffControl) + + val TAG_ON_TIME_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ON_TIME_REQ), onTime) + + val TAG_OFF_WAIT_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_OFF_WAIT_TIME_REQ), offWaitTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readOnOffAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeOnOffAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onoff attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) - suspend fun readGlobalSceneControlAttribute(): Boolean { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeGlobalSceneControlAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readGlobalSceneControlAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 16384u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Globalscenecontrol attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readOnTimeAttribute(): UShort { - // Implementation needs to be added here + suspend fun readOnTimeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16385u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ontime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeOnTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16385u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeOnTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readOffWaitTimeAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16386u - suspend fun readOffWaitTimeAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeOffWaitTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Offwaittime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeOffWaitTimeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun writeOffWaitTimeAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16386u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readStartUpOnOffAttribute(): StartUpOnOffAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16387u - suspend fun writeStartUpOnOffAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeStartUpOnOffAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpOnOffAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startuponoff attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpOnOffAttribute(decodedValue) + } + + suspend fun writeStartUpOnOffAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16387u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OnOffCluster::class.java.name) const val CLUSTER_ID: UInt = 6u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffSwitchConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffSwitchConfigurationCluster.kt index 71c1585a842d8d..0d72cea2f57f11 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffSwitchConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffSwitchConfigurationCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OnOffSwitchConfigurationCluster( private val controller: MatterController, @@ -33,87 +40,325 @@ class OnOffSwitchConfigurationCluster( class AttributeListAttribute(val value: List) suspend fun readSwitchTypeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSwitchTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Switchtype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readSwitchActionsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16u - suspend fun writeSwitchActionsAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Switchactions attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeSwitchActionsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeSwitchActionsAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OnOffSwitchConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 7u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalCredentialsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalCredentialsCluster.kt index 66f2b93d0351d1..37a33e177d44bb 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalCredentialsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalCredentialsCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OperationalCredentialsCluster( private val controller: MatterController, @@ -33,7 +42,7 @@ class OperationalCredentialsCluster( class CSRResponse(val NOCSRElements: ByteArray, val attestationSignature: ByteArray) - class NOCResponse(val statusCode: UInt, val fabricIndex: UByte?, val debugText: String?) + class NOCResponse(val statusCode: UByte, val fabricIndex: UByte?, val debugText: String?) class NOCsAttribute(val value: List) @@ -53,26 +62,111 @@ class OperationalCredentialsCluster( attestationNonce: ByteArray, timedInvokeTimeoutMs: Int? = null ): AttestationResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ATTESTATION_NONCE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ATTESTATION_NONCE_REQ), attestationNonce) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ATTESTATION_ELEMENTS: Int = 0 + var attestationElements_decoded: ByteArray? = null + + val TAG_ATTESTATION_SIGNATURE: Int = 1 + var attestationSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ATTESTATION_ELEMENTS)) { + attestationElements_decoded = tlvReader.getByteArray(tag) + } + + if (tag == ContextSpecificTag(TAG_ATTESTATION_SIGNATURE)) { + attestationSignature_decoded = tlvReader.getByteArray(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (attestationElements_decoded == null) { + throw IllegalStateException("attestationElements not found in TLV") + } + + if (attestationSignature_decoded == null) { + throw IllegalStateException("attestationSignature not found in TLV") + } + + tlvReader.exitContainer() + + return AttestationResponse(attestationElements_decoded, attestationSignature_decoded) } suspend fun certificateChainRequest( - certificateType: UInt, + certificateType: UByte, timedInvokeTimeoutMs: Int? = null ): CertificateChainResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_CERTIFICATE_TYPE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_CERTIFICATE_TYPE_REQ), certificateType) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_CERTIFICATE: Int = 0 + var certificate_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_CERTIFICATE)) { + certificate_decoded = tlvReader.getByteArray(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (certificate_decoded == null) { + throw IllegalStateException("certificate not found in TLV") } + + tlvReader.exitContainer() + + return CertificateChainResponse(certificate_decoded) } suspend fun CSRRequest( @@ -80,13 +174,66 @@ class OperationalCredentialsCluster( isForUpdateNOC: Boolean?, timedInvokeTimeoutMs: Int? = null ): CSRResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_C_S_R_NONCE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_C_S_R_NONCE_REQ), CSRNonce) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_IS_FOR_UPDATE_N_O_C_REQ: Int = 1 + isForUpdateNOC?.let { + tlvWriter.put(ContextSpecificTag(TAG_IS_FOR_UPDATE_N_O_C_REQ), isForUpdateNOC) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_N_O_C_S_R_ELEMENTS: Int = 0 + var NOCSRElements_decoded: ByteArray? = null + + val TAG_ATTESTATION_SIGNATURE: Int = 1 + var attestationSignature_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_N_O_C_S_R_ELEMENTS)) { + NOCSRElements_decoded = tlvReader.getByteArray(tag) + } + + if (tag == ContextSpecificTag(TAG_ATTESTATION_SIGNATURE)) { + attestationSignature_decoded = tlvReader.getByteArray(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (NOCSRElements_decoded == null) { + throw IllegalStateException("NOCSRElements not found in TLV") + } + + if (attestationSignature_decoded == null) { + throw IllegalStateException("attestationSignature not found in TLV") + } + + tlvReader.exitContainer() + + return CSRResponse(NOCSRElements_decoded, attestationSignature_decoded) } suspend fun addNOC( @@ -97,13 +244,96 @@ class OperationalCredentialsCluster( adminVendorId: UShort, timedInvokeTimeoutMs: Int? = null ): NOCResponse { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_N_O_C_VALUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_N_O_C_VALUE_REQ), NOCValue) + + val TAG_I_C_A_C_VALUE_REQ: Int = 1 + ICACValue?.let { tlvWriter.put(ContextSpecificTag(TAG_I_C_A_C_VALUE_REQ), ICACValue) } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_I_P_K_VALUE_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_I_P_K_VALUE_REQ), IPKValue) + + val TAG_CASE_ADMIN_SUBJECT_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_CASE_ADMIN_SUBJECT_REQ), caseAdminSubject) + + val TAG_ADMIN_VENDOR_ID_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_ADMIN_VENDOR_ID_REQ), adminVendorId) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS_CODE: Int = 0 + var statusCode_decoded: UByte? = null + + val TAG_FABRIC_INDEX: Int = 1 + var fabricIndex_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 2 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS_CODE)) { + statusCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_FABRIC_INDEX)) { + fabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (statusCode_decoded == null) { + throw IllegalStateException("statusCode not found in TLV") + } + + tlvReader.exitContainer() + + return NOCResponse(statusCode_decoded, fabricIndex_decoded, debugText_decoded) } suspend fun updateNOC( @@ -111,165 +341,700 @@ class OperationalCredentialsCluster( ICACValue: ByteArray?, timedInvokeTimeoutMs: Int? = null ): NOCResponse { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_N_O_C_VALUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_N_O_C_VALUE_REQ), NOCValue) + + val TAG_I_C_A_C_VALUE_REQ: Int = 1 + ICACValue?.let { tlvWriter.put(ContextSpecificTag(TAG_I_C_A_C_VALUE_REQ), ICACValue) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS_CODE: Int = 0 + var statusCode_decoded: UByte? = null + + val TAG_FABRIC_INDEX: Int = 1 + var fabricIndex_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 2 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS_CODE)) { + statusCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_FABRIC_INDEX)) { + fabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (statusCode_decoded == null) { + throw IllegalStateException("statusCode not found in TLV") } + + tlvReader.exitContainer() + + return NOCResponse(statusCode_decoded, fabricIndex_decoded, debugText_decoded) } suspend fun updateFabricLabel(label: String, timedInvokeTimeoutMs: Int? = null): NOCResponse { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LABEL_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LABEL_REQ), label) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS_CODE: Int = 0 + var statusCode_decoded: UByte? = null + + val TAG_FABRIC_INDEX: Int = 1 + var fabricIndex_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 2 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS_CODE)) { + statusCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_FABRIC_INDEX)) { + fabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (statusCode_decoded == null) { + throw IllegalStateException("statusCode not found in TLV") } + + tlvReader.exitContainer() + + return NOCResponse(statusCode_decoded, fabricIndex_decoded, debugText_decoded) } suspend fun removeFabric(fabricIndex: UByte, timedInvokeTimeoutMs: Int? = null): NOCResponse { - val commandId = 10L + val commandId: UInt = 10u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_FABRIC_INDEX_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_FABRIC_INDEX_REQ), fabricIndex) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS_CODE: Int = 0 + var statusCode_decoded: UByte? = null + + val TAG_FABRIC_INDEX: Int = 1 + var fabricIndex_decoded: UByte? = null + + val TAG_DEBUG_TEXT: Int = 2 + var debugText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS_CODE)) { + statusCode_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_FABRIC_INDEX)) { + fabricIndex_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_DEBUG_TEXT)) { + debugText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (statusCode_decoded == null) { + throw IllegalStateException("statusCode not found in TLV") } + + tlvReader.exitContainer() + + return NOCResponse(statusCode_decoded, fabricIndex_decoded, debugText_decoded) } suspend fun addTrustedRootCertificate( rootCACertificate: ByteArray, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 11L + val commandId: UInt = 11u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ROOT_C_A_CERTIFICATE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ROOT_C_A_CERTIFICATE_REQ), rootCACertificate) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readNOCsAttribute(): NOCsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun readNOCsAttributeWithFabricFilter(isFabricFiltered: Boolean): NOCsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeNOCsAttribute(minInterval: Int, maxInterval: Int): NOCsAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Nocs attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(OperationalCredentialsClusterNOCStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return NOCsAttribute(decodedValue) } suspend fun readFabricsAttribute(): FabricsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun readFabricsAttributeWithFabricFilter(isFabricFiltered: Boolean): FabricsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Fabrics attribute not found in response" } - suspend fun subscribeFabricsAttribute(minInterval: Int, maxInterval: Int): FabricsAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(OperationalCredentialsClusterFabricDescriptorStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return FabricsAttribute(decodedValue) } suspend fun readSupportedFabricsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeSupportedFabricsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedfabrics attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readCommissionedFabricsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCommissionedFabricsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Commissionedfabrics attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readTrustedRootCertificatesAttribute(): TrustedRootCertificatesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Trustedrootcertificates attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getByteArray(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeTrustedRootCertificatesAttribute( - minInterval: Int, - maxInterval: Int - ): TrustedRootCertificatesAttribute { - // Implementation needs to be added here + return TrustedRootCertificatesAttribute(decodedValue) } suspend fun readCurrentFabricIndexAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeCurrentFabricIndexAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentfabricindex attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OperationalCredentialsCluster::class.java.name) const val CLUSTER_ID: UInt = 62u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalStateCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalStateCluster.kt index 2b4222c80d4efd..6c13c4a6b0b8a6 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalStateCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OperationalStateCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OperationalStateCluster( private val controller: MatterController, @@ -49,163 +58,623 @@ class OperationalStateCluster( class AttributeListAttribute(val value: List) suspend fun pause(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun stop(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun start(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun resume(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun readPhaseListAttribute(): PhaseListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribePhaseListAttribute(minInterval: Int, maxInterval: Int): PhaseListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Phaselist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PhaseListAttribute(decodedValue) } suspend fun readCurrentPhaseAttribute(): CurrentPhaseAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentPhaseAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPhaseAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentphase attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPhaseAttribute(decodedValue) } suspend fun readCountdownTimeAttribute(): CountdownTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCountdownTimeAttribute( - minInterval: Int, - maxInterval: Int - ): CountdownTimeAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Countdowntime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CountdownTimeAttribute(decodedValue) } suspend fun readOperationalStateListAttribute(): OperationalStateListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalstatelist attribute not found in response" } - suspend fun subscribeOperationalStateListAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalStateListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(OperationalStateClusterOperationalStateStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return OperationalStateListAttribute(decodedValue) } suspend fun readOperationalStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeOperationalStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOperationalErrorAttribute(): OperationalErrorAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeOperationalErrorAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalErrorAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Operationalerror attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: OperationalStateClusterErrorStateStruct = + OperationalStateClusterErrorStateStruct.fromTlv(AnonymousTag, tlvReader) + + return OperationalErrorAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OperationalStateCluster::class.java.name) const val CLUSTER_ID: UInt = 96u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateProviderCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateProviderCluster.kt index df9a021ffe3d35..80e13cc88a9958 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateProviderCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateProviderCluster.kt @@ -17,15 +17,24 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OtaSoftwareUpdateProviderCluster( private val controller: MatterController, private val endpointId: UShort ) { class QueryImageResponse( - val status: UInt, + val status: UByte, val delayedActionTime: UInt?, val imageURI: String?, val softwareVersion: UInt?, @@ -35,7 +44,7 @@ class OtaSoftwareUpdateProviderCluster( val metadataForRequestor: ByteArray? ) - class ApplyUpdateResponse(val action: UInt, val delayedActionTime: UInt) + class ApplyUpdateResponse(val action: UByte, val delayedActionTime: UInt) class GeneratedCommandListAttribute(val value: List) @@ -49,20 +58,216 @@ class OtaSoftwareUpdateProviderCluster( vendorID: UShort, productID: UShort, softwareVersion: UInt, - protocolsSupported: List, + protocolsSupported: List, hardwareVersion: UShort?, location: String?, requestorCanConsent: Boolean?, metadataForProvider: ByteArray?, timedInvokeTimeoutMs: Int? = null ): QueryImageResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_VENDOR_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_VENDOR_I_D_REQ), vendorID) + + val TAG_PRODUCT_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_PRODUCT_I_D_REQ), productID) + + val TAG_SOFTWARE_VERSION_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_SOFTWARE_VERSION_REQ), softwareVersion) + + val TAG_PROTOCOLS_SUPPORTED_REQ: Int = 3 + tlvWriter.startArray(ContextSpecificTag(TAG_PROTOCOLS_SUPPORTED_REQ)) + for (item in protocolsSupported.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + + val TAG_HARDWARE_VERSION_REQ: Int = 4 + hardwareVersion?.let { + tlvWriter.put(ContextSpecificTag(TAG_HARDWARE_VERSION_REQ), hardwareVersion) + } + + val TAG_LOCATION_REQ: Int = 5 + location?.let { tlvWriter.put(ContextSpecificTag(TAG_LOCATION_REQ), location) } + + val TAG_REQUESTOR_CAN_CONSENT_REQ: Int = 6 + requestorCanConsent?.let { + tlvWriter.put(ContextSpecificTag(TAG_REQUESTOR_CAN_CONSENT_REQ), requestorCanConsent) + } + + val TAG_METADATA_FOR_PROVIDER_REQ: Int = 7 + metadataForProvider?.let { + tlvWriter.put(ContextSpecificTag(TAG_METADATA_FOR_PROVIDER_REQ), metadataForProvider) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DELAYED_ACTION_TIME: Int = 1 + var delayedActionTime_decoded: UInt? = null + + val TAG_IMAGE_U_R_I: Int = 2 + var imageURI_decoded: String? = null + + val TAG_SOFTWARE_VERSION: Int = 3 + var softwareVersion_decoded: UInt? = null + + val TAG_SOFTWARE_VERSION_STRING: Int = 4 + var softwareVersionString_decoded: String? = null + + val TAG_UPDATE_TOKEN: Int = 5 + var updateToken_decoded: ByteArray? = null + + val TAG_USER_CONSENT_NEEDED: Int = 6 + var userConsentNeeded_decoded: Boolean? = null + + val TAG_METADATA_FOR_REQUESTOR: Int = 7 + var metadataForRequestor_decoded: ByteArray? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DELAYED_ACTION_TIME)) { + delayedActionTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUInt(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_IMAGE_U_R_I)) { + imageURI_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_SOFTWARE_VERSION)) { + softwareVersion_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUInt(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_SOFTWARE_VERSION_STRING)) { + softwareVersionString_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_UPDATE_TOKEN)) { + updateToken_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_USER_CONSENT_NEEDED)) { + userConsentNeeded_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getBoolean(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_METADATA_FOR_REQUESTOR)) { + metadataForRequestor_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getByteArray(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return QueryImageResponse( + status_decoded, + delayedActionTime_decoded, + imageURI_decoded, + softwareVersion_decoded, + softwareVersionString_decoded, + updateToken_decoded, + userConsentNeeded_decoded, + metadataForRequestor_decoded + ) } suspend fun applyUpdateRequest( @@ -70,13 +275,64 @@ class OtaSoftwareUpdateProviderCluster( newVersion: UInt, timedInvokeTimeoutMs: Int? = null ): ApplyUpdateResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_UPDATE_TOKEN_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_UPDATE_TOKEN_REQ), updateToken) + + val TAG_NEW_VERSION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_NEW_VERSION_REQ), newVersion) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ACTION: Int = 0 + var action_decoded: UByte? = null + + val TAG_DELAYED_ACTION_TIME: Int = 1 + var delayedActionTime_decoded: UInt? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ACTION)) { + action_decoded = tlvReader.getUByte(tag) + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (tag == ContextSpecificTag(TAG_DELAYED_ACTION_TIME)) { + delayedActionTime_decoded = tlvReader.getUInt(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (action_decoded == null) { + throw IllegalStateException("action not found in TLV") + } + + if (delayedActionTime_decoded == null) { + throw IllegalStateException("delayedActionTime not found in TLV") + } + + tlvReader.exitContainer() + + return ApplyUpdateResponse(action_decoded, delayedActionTime_decoded) } suspend fun notifyUpdateApplied( @@ -84,73 +340,247 @@ class OtaSoftwareUpdateProviderCluster( softwareVersion: UInt, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_UPDATE_TOKEN_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_UPDATE_TOKEN_REQ), updateToken) + + val TAG_SOFTWARE_VERSION_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SOFTWARE_VERSION_REQ), softwareVersion) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OtaSoftwareUpdateProviderCluster::class.java.name) const val CLUSTER_ID: UInt = 41u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateRequestorCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateRequestorCluster.kt index 7e422996631bdb..8bed29c639a556 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateRequestorCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OtaSoftwareUpdateRequestorCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OtaSoftwareUpdateRequestorCluster( private val controller: MatterController, @@ -41,133 +50,449 @@ class OtaSoftwareUpdateRequestorCluster( suspend fun announceOTAProvider( providerNodeID: ULong, vendorID: UShort, - announcementReason: UInt, + announcementReason: UByte, metadataForNode: ByteArray?, endpoint: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_PROVIDER_NODE_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_PROVIDER_NODE_I_D_REQ), providerNodeID) + + val TAG_VENDOR_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_VENDOR_I_D_REQ), vendorID) + + val TAG_ANNOUNCEMENT_REASON_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_ANNOUNCEMENT_REASON_REQ), announcementReason) + + val TAG_METADATA_FOR_NODE_REQ: Int = 3 + metadataForNode?.let { + tlvWriter.put(ContextSpecificTag(TAG_METADATA_FOR_NODE_REQ), metadataForNode) } + + val TAG_ENDPOINT_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_ENDPOINT_REQ), endpoint) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readDefaultOTAProvidersAttribute(): DefaultOTAProvidersAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readDefaultOTAProvidersAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): DefaultOTAProvidersAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Defaultotaproviders attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(OtaSoftwareUpdateRequestorClusterProviderLocation.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return DefaultOTAProvidersAttribute(decodedValue) } suspend fun writeDefaultOTAProvidersAttribute( value: List, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } - } - - suspend fun subscribeDefaultOTAProvidersAttribute( - minInterval: Int, - maxInterval: Int - ): DefaultOTAProvidersAttribute { - // Implementation needs to be added here } suspend fun readUpdatePossibleAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeUpdatePossibleAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + requireNotNull(attributeData) { "Updatepossible attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readUpdateStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Updatestate attribute not found in response" } - suspend fun subscribeUpdateStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readUpdateStateProgressAttribute(): UpdateStateProgressAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeUpdateStateProgressAttribute( - minInterval: Int, - maxInterval: Int - ): UpdateStateProgressAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Updatestateprogress attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return UpdateStateProgressAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OtaSoftwareUpdateRequestorCluster::class.java.name) const val CLUSTER_ID: UInt = 42u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenCavityOperationalStateCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenCavityOperationalStateCluster.kt index c114fc72d1c586..72b0a3869eeb2e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenCavityOperationalStateCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenCavityOperationalStateCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OvenCavityOperationalStateCluster( private val controller: MatterController, @@ -49,163 +58,625 @@ class OvenCavityOperationalStateCluster( class AttributeListAttribute(val value: List) suspend fun pause(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OvenCavityOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OvenCavityOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun stop(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OvenCavityOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OvenCavityOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun start(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OvenCavityOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OvenCavityOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun resume(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: OvenCavityOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + OvenCavityOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun readPhaseListAttribute(): PhaseListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePhaseListAttribute(minInterval: Int, maxInterval: Int): PhaseListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Phaselist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PhaseListAttribute(decodedValue) } suspend fun readCurrentPhaseAttribute(): CurrentPhaseAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeCurrentPhaseAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPhaseAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentphase attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPhaseAttribute(decodedValue) } suspend fun readCountdownTimeAttribute(): CountdownTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeCountdownTimeAttribute( - minInterval: Int, - maxInterval: Int - ): CountdownTimeAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Countdowntime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CountdownTimeAttribute(decodedValue) } suspend fun readOperationalStateListAttribute(): OperationalStateListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeOperationalStateListAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalStateListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalstatelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + OvenCavityOperationalStateClusterOperationalStateStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + return OperationalStateListAttribute(decodedValue) } suspend fun readOperationalStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalstate attribute not found in response" } - suspend fun subscribeOperationalStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOperationalErrorAttribute(): OperationalErrorAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalerror attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: OvenCavityOperationalStateClusterErrorStateStruct = + OvenCavityOperationalStateClusterErrorStateStruct.fromTlv(AnonymousTag, tlvReader) - suspend fun subscribeOperationalErrorAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalErrorAttribute { - // Implementation needs to be added here + return OperationalErrorAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OvenCavityOperationalStateCluster::class.java.name) const val CLUSTER_ID: UInt = 72u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenModeCluster.kt index 267bd10448cca1..607e6f6ae6df08 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OvenModeCluster.kt @@ -17,11 +17,20 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class OvenModeCluster(private val controller: MatterController, private val endpointId: UShort) { - class ChangeToModeResponse(val status: UInt, val statusText: String?) + class ChangeToModeResponse(val status: UByte, val statusText: String?) class SupportedModesAttribute(val value: List) @@ -41,127 +50,520 @@ class OvenModeCluster(private val controller: MatterController, private val endp newMode: UByte, timedInvokeTimeoutMs: Int? = null ): ChangeToModeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(OvenModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) } - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpModeAttribute { - // Implementation needs to be added here + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OvenModeCluster::class.java.name) const val CLUSTER_ID: UInt = 73u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OzoneConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OzoneConcentrationMeasurementCluster.kt index 3542a8e090a8fb..f7c57df0522842 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OzoneConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OzoneConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class OzoneConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,642 @@ class OzoneConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(OzoneConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1045u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm10ConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm10ConcentrationMeasurementCluster.kt index f6cdf804a7642f..ee41d1ccd021e9 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm10ConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm10ConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class Pm10ConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,642 @@ class Pm10ConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(Pm10ConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1069u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm1ConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm1ConcentrationMeasurementCluster.kt index f07c97fbfd4468..81a0ecb5c0c0f2 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm1ConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm1ConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class Pm1ConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,642 @@ class Pm1ConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(Pm1ConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1068u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm25ConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm25ConcentrationMeasurementCluster.kt index 424658e2bd6e0b..39a9d029becbe7 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm25ConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/Pm25ConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class Pm25ConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,642 @@ class Pm25ConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(Pm25ConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1066u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceCluster.kt index 6dc18689f87f2d..a58fddc595f7a0 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class PowerSourceCluster(private val controller: MatterController, private val endpointId: UShort) { class WiredAssessedInputVoltageAttribute(val value: UInt?) @@ -27,7 +32,7 @@ class PowerSourceCluster(private val controller: MatterController, private val e class WiredAssessedCurrentAttribute(val value: UInt?) - class ActiveWiredFaultsAttribute(val value: List?) + class ActiveWiredFaultsAttribute(val value: List?) class BatVoltageAttribute(val value: UInt?) @@ -35,13 +40,13 @@ class PowerSourceCluster(private val controller: MatterController, private val e class BatTimeRemainingAttribute(val value: UInt?) - class ActiveBatFaultsAttribute(val value: List?) + class ActiveBatFaultsAttribute(val value: List?) class BatTimeToFullChargeAttribute(val value: UInt?) class BatChargingCurrentAttribute(val value: UInt?) - class ActiveBatChargeFaultsAttribute(val value: List?) + class ActiveBatChargeFaultsAttribute(val value: List?) class EndpointListAttribute(val value: List) @@ -54,361 +59,1418 @@ class PowerSourceCluster(private val controller: MatterController, private val e class AttributeListAttribute(val value: List) suspend fun readStatusAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeStatusAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Status attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOrderAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeOrderAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readDescriptionAttribute(): CharString { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Order attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeDescriptionAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + suspend fun readDescriptionAttribute(): String { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Description attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue } suspend fun readWiredAssessedInputVoltageAttribute(): WiredAssessedInputVoltageAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeWiredAssessedInputVoltageAttribute( - minInterval: Int, - maxInterval: Int - ): WiredAssessedInputVoltageAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wiredassessedinputvoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return WiredAssessedInputVoltageAttribute(decodedValue) } suspend fun readWiredAssessedInputFrequencyAttribute(): WiredAssessedInputFrequencyAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun subscribeWiredAssessedInputFrequencyAttribute( - minInterval: Int, - maxInterval: Int - ): WiredAssessedInputFrequencyAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readWiredCurrentTypeAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Wiredassessedinputfrequency attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return WiredAssessedInputFrequencyAttribute(decodedValue) } - suspend fun subscribeWiredCurrentTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readWiredCurrentTypeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wiredcurrenttype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readWiredAssessedCurrentAttribute(): WiredAssessedCurrentAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u - suspend fun subscribeWiredAssessedCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): WiredAssessedCurrentAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readWiredNominalVoltageAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeWiredNominalVoltageAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun readWiredMaximumCurrentAttribute(): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wiredassessedcurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return WiredAssessedCurrentAttribute(decodedValue) } - suspend fun subscribeWiredMaximumCurrentAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readWiredNominalVoltageAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wirednominalvoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readWiredPresentAttribute(): Boolean { - // Implementation needs to be added here + suspend fun readWiredMaximumCurrentAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wiredmaximumcurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeWiredPresentAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readWiredPresentAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wiredpresent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readActiveWiredFaultsAttribute(): ActiveWiredFaultsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeActiveWiredFaultsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveWiredFaultsAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Activewiredfaults attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ActiveWiredFaultsAttribute(decodedValue) } suspend fun readBatVoltageAttribute(): BatVoltageAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batvoltage attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeBatVoltageAttribute( - minInterval: Int, - maxInterval: Int - ): BatVoltageAttribute { - // Implementation needs to be added here + return BatVoltageAttribute(decodedValue) } suspend fun readBatPercentRemainingAttribute(): BatPercentRemainingAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeBatPercentRemainingAttribute( - minInterval: Int, - maxInterval: Int - ): BatPercentRemainingAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batpercentremaining attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BatPercentRemainingAttribute(decodedValue) } suspend fun readBatTimeRemainingAttribute(): BatTimeRemainingAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 13u - suspend fun subscribeBatTimeRemainingAttribute( - minInterval: Int, - maxInterval: Int - ): BatTimeRemainingAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readBatChargeLevelAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeBatChargeLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readBatReplacementNeededAttribute(): Boolean { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeBatReplacementNeededAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + requireNotNull(attributeData) { "Battimeremaining attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BatTimeRemainingAttribute(decodedValue) } - suspend fun readBatReplaceabilityAttribute(): UByte { - // Implementation needs to be added here + suspend fun readBatChargeLevelAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 14u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batchargelevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBatReplaceabilityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readBatReplacementNeededAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 15u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batreplacementneeded attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readBatPresentAttribute(): Boolean { - // Implementation needs to be added here + suspend fun readBatReplaceabilityAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batreplaceability attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBatPresentAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readBatPresentAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 17u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batpresent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readActiveBatFaultsAttribute(): ActiveBatFaultsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 18u - suspend fun subscribeActiveBatFaultsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveBatFaultsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readBatReplacementDescriptionAttribute(): CharString { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeBatReplacementDescriptionAttribute( - minInterval: Int, - maxInterval: Int - ): CharString { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readBatCommonDesignationAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeBatCommonDesignationAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readBatANSIDesignationAttribute(): CharString { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeBatANSIDesignationAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Activebatfaults attribute not found in response" } - suspend fun readBatIECDesignationAttribute(): CharString { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } - suspend fun subscribeBatIECDesignationAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here + return ActiveBatFaultsAttribute(decodedValue) } - suspend fun readBatApprovedChemistryAttribute(): UShort { - // Implementation needs to be added here + suspend fun readBatReplacementDescriptionAttribute(): String? { + val ATTRIBUTE_ID: UInt = 19u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batreplacementdescription attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBatApprovedChemistryAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readBatCommonDesignationAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 20u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batcommondesignation attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readBatCapacityAttribute(): UInt { - // Implementation needs to be added here + suspend fun readBatANSIDesignationAttribute(): String? { + val ATTRIBUTE_ID: UInt = 21u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batansidesignation attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBatCapacityAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readBatIECDesignationAttribute(): String? { + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batiecdesignation attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readBatQuantityAttribute(): UByte { - // Implementation needs to be added here + suspend fun readBatApprovedChemistryAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 23u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batapprovedchemistry attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBatQuantityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readBatCapacityAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 24u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batcapacity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readBatChargeStateAttribute(): UByte { - // Implementation needs to be added here + suspend fun readBatQuantityAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 25u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batquantity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeBatChargeStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readBatChargeStateAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batchargestate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readBatTimeToFullChargeAttribute(): BatTimeToFullChargeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 27u - suspend fun subscribeBatTimeToFullChargeAttribute( - minInterval: Int, - maxInterval: Int - ): BatTimeToFullChargeAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun readBatFunctionalWhileChargingAttribute(): Boolean { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Battimetofullcharge attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BatTimeToFullChargeAttribute(decodedValue) } - suspend fun subscribeBatFunctionalWhileChargingAttribute( - minInterval: Int, - maxInterval: Int - ): Boolean { - // Implementation needs to be added here + suspend fun readBatFunctionalWhileChargingAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 28u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batfunctionalwhilecharging attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readBatChargingCurrentAttribute(): BatChargingCurrentAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 29u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeBatChargingCurrentAttribute( - minInterval: Int, - maxInterval: Int - ): BatChargingCurrentAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Batchargingcurrent attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BatChargingCurrentAttribute(decodedValue) } suspend fun readActiveBatChargeFaultsAttribute(): ActiveBatChargeFaultsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 30u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activebatchargefaults attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } - suspend fun subscribeActiveBatChargeFaultsAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveBatChargeFaultsAttribute { - // Implementation needs to be added here + return ActiveBatChargeFaultsAttribute(decodedValue) } suspend fun readEndpointListAttribute(): EndpointListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 31u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEndpointListAttribute( - minInterval: Int, - maxInterval: Int - ): EndpointListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Endpointlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EndpointListAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(PowerSourceCluster::class.java.name) const val CLUSTER_ID: UInt = 47u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceConfigurationCluster.kt index b90d42743b65f8..deb3bdc4be4eeb 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PowerSourceConfigurationCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class PowerSourceConfigurationCluster( private val controller: MatterController, @@ -35,71 +40,259 @@ class PowerSourceConfigurationCluster( class AttributeListAttribute(val value: List) suspend fun readSourcesAttribute(): SourcesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Sources attribute not found in response" } - suspend fun subscribeSourcesAttribute(minInterval: Int, maxInterval: Int): SourcesAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUShort(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return SourcesAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(PowerSourceConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 46u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PressureMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PressureMeasurementCluster.kt index 64c49e903d5988..170bf7dddf42dd 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PressureMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PressureMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class PressureMeasurementCluster( private val controller: MatterController, @@ -45,153 +50,563 @@ class PressureMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } - suspend fun readToleranceAttribute(): UShort { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } - suspend fun subscribeToleranceAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readToleranceAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tolerance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readScaledValueAttribute(): ScaledValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeScaledValueAttribute( - minInterval: Int, - maxInterval: Int - ): ScaledValueAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Scaledvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ScaledValueAttribute(decodedValue) } suspend fun readMinScaledValueAttribute(): MinScaledValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 17u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMinScaledValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinScaledValueAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minscaledvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinScaledValueAttribute(decodedValue) } suspend fun readMaxScaledValueAttribute(): MaxScaledValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 18u - suspend fun subscribeMaxScaledValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxScaledValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readScaledToleranceAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeScaledToleranceAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxscaledvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxScaledValueAttribute(decodedValue) } - suspend fun readScaleAttribute(): Byte { - // Implementation needs to be added here + suspend fun readScaledToleranceAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 19u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scaledtolerance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeScaleAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here + suspend fun readScaleAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 20u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scale attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(PressureMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1027u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyConfigurationCluster.kt index fe0e582c9d45da..b105f9a0e8bc4e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyConfigurationCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class ProxyConfigurationCluster( private val controller: MatterController, @@ -33,63 +38,221 @@ class ProxyConfigurationCluster( class AttributeListAttribute(val value: List) suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ProxyConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 66u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyDiscoveryCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyDiscoveryCluster.kt index fd1c428646a714..5848e54b448ce3 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyDiscoveryCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyDiscoveryCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class ProxyDiscoveryCluster( private val controller: MatterController, @@ -33,63 +38,221 @@ class ProxyDiscoveryCluster( class AttributeListAttribute(val value: List) suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ProxyDiscoveryCluster::class.java.name) const val CLUSTER_ID: UInt = 67u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyValidCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyValidCluster.kt index 589502096ac382..40877853aecbf6 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyValidCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ProxyValidCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class ProxyValidCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -30,63 +35,221 @@ class ProxyValidCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ProxyValidCluster::class.java.name) const val CLUSTER_ID: UInt = 68u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PulseWidthModulationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PulseWidthModulationCluster.kt index d7e43df772c99b..3536085c7f4c0f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PulseWidthModulationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PulseWidthModulationCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class PulseWidthModulationCluster( private val controller: MatterController, @@ -33,63 +38,221 @@ class PulseWidthModulationCluster( class AttributeListAttribute(val value: List) suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(PulseWidthModulationCluster::class.java.name) const val CLUSTER_ID: UInt = 28u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PumpConfigurationAndControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PumpConfigurationAndControlCluster.kt index 501850ac2264d9..3666a39afcf77f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PumpConfigurationAndControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/PumpConfigurationAndControlCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class PumpConfigurationAndControlCluster( private val controller: MatterController, @@ -69,318 +76,1276 @@ class PumpConfigurationAndControlCluster( class AttributeListAttribute(val value: List) suspend fun readMaxPressureAttribute(): MaxPressureAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeMaxPressureAttribute( - minInterval: Int, - maxInterval: Int - ): MaxPressureAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Maxpressure attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxPressureAttribute(decodedValue) } suspend fun readMaxSpeedAttribute(): MaxSpeedAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxspeed attribute not found in response" } - suspend fun subscribeMaxSpeedAttribute(minInterval: Int, maxInterval: Int): MaxSpeedAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxSpeedAttribute(decodedValue) } suspend fun readMaxFlowAttribute(): MaxFlowAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxflow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeMaxFlowAttribute(minInterval: Int, maxInterval: Int): MaxFlowAttribute { - // Implementation needs to be added here + return MaxFlowAttribute(decodedValue) } suspend fun readMinConstPressureAttribute(): MinConstPressureAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeMinConstPressureAttribute( - minInterval: Int, - maxInterval: Int - ): MinConstPressureAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minconstpressure attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinConstPressureAttribute(decodedValue) } suspend fun readMaxConstPressureAttribute(): MaxConstPressureAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxConstPressureAttribute( - minInterval: Int, - maxInterval: Int - ): MaxConstPressureAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxconstpressure attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxConstPressureAttribute(decodedValue) } suspend fun readMinCompPressureAttribute(): MinCompPressureAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMinCompPressureAttribute( - minInterval: Int, - maxInterval: Int - ): MinCompPressureAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Mincomppressure attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinCompPressureAttribute(decodedValue) } suspend fun readMaxCompPressureAttribute(): MaxCompPressureAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u - suspend fun subscribeMaxCompPressureAttribute( - minInterval: Int, - maxInterval: Int - ): MaxCompPressureAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxcomppressure attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxCompPressureAttribute(decodedValue) } suspend fun readMinConstSpeedAttribute(): MinConstSpeedAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMinConstSpeedAttribute( - minInterval: Int, - maxInterval: Int - ): MinConstSpeedAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minconstspeed attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinConstSpeedAttribute(decodedValue) } suspend fun readMaxConstSpeedAttribute(): MaxConstSpeedAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeMaxConstSpeedAttribute( - minInterval: Int, - maxInterval: Int - ): MaxConstSpeedAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxconstspeed attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxConstSpeedAttribute(decodedValue) } suspend fun readMinConstFlowAttribute(): MinConstFlowAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMinConstFlowAttribute( - minInterval: Int, - maxInterval: Int - ): MinConstFlowAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minconstflow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinConstFlowAttribute(decodedValue) } suspend fun readMaxConstFlowAttribute(): MaxConstFlowAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMaxConstFlowAttribute( - minInterval: Int, - maxInterval: Int - ): MaxConstFlowAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxconstflow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxConstFlowAttribute(decodedValue) } suspend fun readMinConstTempAttribute(): MinConstTempAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 11u - suspend fun subscribeMinConstTempAttribute( - minInterval: Int, - maxInterval: Int - ): MinConstTempAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minconsttemp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinConstTempAttribute(decodedValue) } suspend fun readMaxConstTempAttribute(): MaxConstTempAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 12u - suspend fun subscribeMaxConstTempAttribute( - minInterval: Int, - maxInterval: Int - ): MaxConstTempAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readPumpStatusAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxconsttemp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxConstTempAttribute(decodedValue) } - suspend fun subscribePumpStatusAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readPumpStatusAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Pumpstatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readEffectiveOperationModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 17u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEffectiveOperationModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Effectiveoperationmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readEffectiveControlModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 18u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Effectivecontrolmode attribute not found in response" } - suspend fun subscribeEffectiveControlModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readCapacityAttribute(): CapacityAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 19u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeCapacityAttribute(minInterval: Int, maxInterval: Int): CapacityAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Capacity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CapacityAttribute(decodedValue) } suspend fun readSpeedAttribute(): SpeedAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 20u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeSpeedAttribute(minInterval: Int, maxInterval: Int): SpeedAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Speed attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SpeedAttribute(decodedValue) } suspend fun readLifetimeRunningHoursAttribute(): LifetimeRunningHoursAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 21u - suspend fun writeLifetimeRunningHoursAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lifetimerunninghours attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LifetimeRunningHoursAttribute(decodedValue) } - suspend fun subscribeLifetimeRunningHoursAttribute( - minInterval: Int, - maxInterval: Int - ): LifetimeRunningHoursAttribute { - // Implementation needs to be added here + suspend fun writeLifetimeRunningHoursAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 21u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readPowerAttribute(): PowerAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePowerAttribute(minInterval: Int, maxInterval: Int): PowerAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Power attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PowerAttribute(decodedValue) } suspend fun readLifetimeEnergyConsumedAttribute(): LifetimeEnergyConsumedAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 23u - suspend fun writeLifetimeEnergyConsumedAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lifetimeenergyconsumed attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LifetimeEnergyConsumedAttribute(decodedValue) } - suspend fun subscribeLifetimeEnergyConsumedAttribute( - minInterval: Int, - maxInterval: Int - ): LifetimeEnergyConsumedAttribute { - // Implementation needs to be added here + suspend fun writeLifetimeEnergyConsumedAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 23u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOperationModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 32u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeOperationModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeOperationModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readControlModeAttribute(): UByte { - // Implementation needs to be added here + suspend fun writeOperationModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 32u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun writeControlModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readControlModeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Controlmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeControlModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeControlModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 33u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(PumpConfigurationAndControlCluster::class.java.name) const val CLUSTER_ID: UInt = 512u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RadonConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RadonConcentrationMeasurementCluster.kt index 5c54c5f5fee2fe..bc5879175f1522 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RadonConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RadonConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class RadonConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,642 @@ class RadonConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(RadonConcentrationMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1071u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAlarmCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAlarmCluster.kt index 9aebd7443d205e..0f494ac42cc70e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAlarmCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAlarmCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class RefrigeratorAlarmCluster( private val controller: MatterController, @@ -33,87 +38,314 @@ class RefrigeratorAlarmCluster( class AttributeListAttribute(val value: List) suspend fun readMaskAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMaskAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Mask attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readStateAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeStateAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "State attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readSupportedAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeSupportedAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supported attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(RefrigeratorAlarmCluster::class.java.name) const val CLUSTER_ID: UInt = 87u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAndTemperatureControlledCabinetModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAndTemperatureControlledCabinetModeCluster.kt index bfb589a815d089..d0600fe2dd8d4c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAndTemperatureControlledCabinetModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RefrigeratorAndTemperatureControlledCabinetModeCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class RefrigeratorAndTemperatureControlledCabinetModeCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ChangeToModeResponse(val status: UInt, val statusText: String?) + class ChangeToModeResponse(val status: UByte, val statusText: String?) class SupportedModesAttribute( val value: List @@ -46,127 +55,526 @@ class RefrigeratorAndTemperatureControlledCabinetModeCluster( newMode: UByte, timedInvokeTimeoutMs: Int? = null ): ChangeToModeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + RefrigeratorAndTemperatureControlledCabinetModeClusterModeOptionStruct.fromTlv( + AnonymousTag, + tlvReader + ) + ) + } + tlvReader.exitContainer() + } + + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) } - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int - ): StartUpModeAttribute { - // Implementation needs to be added here + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger(RefrigeratorAndTemperatureControlledCabinetModeCluster::class.java.name) const val CLUSTER_ID: UInt = 82u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RelativeHumidityMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RelativeHumidityMeasurementCluster.kt index d2240d51f6ae74..46d56b18c2a610 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RelativeHumidityMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RelativeHumidityMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class RelativeHumidityMeasurementCluster( private val controller: MatterController, @@ -39,104 +44,368 @@ class RelativeHumidityMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readToleranceAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } - suspend fun subscribeToleranceAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readToleranceAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tolerance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(RelativeHumidityMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1029u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcCleanModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcCleanModeCluster.kt index 2a5620f647505c..b2a0fab4c6c32a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcCleanModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcCleanModeCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class RvcCleanModeCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ChangeToModeResponse(val status: UInt, val statusText: String?) + class ChangeToModeResponse(val status: UByte, val statusText: String?) class SupportedModesAttribute(val value: List) @@ -42,108 +51,437 @@ class RvcCleanModeCluster( newMode: UByte, timedInvokeTimeoutMs: Int? = null ): ChangeToModeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(RvcCleanModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(RvcCleanModeCluster::class.java.name) const val CLUSTER_ID: UInt = 85u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcOperationalStateCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcOperationalStateCluster.kt index abb27510e5590c..4db41573c87302 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcOperationalStateCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcOperationalStateCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class RvcOperationalStateCluster( private val controller: MatterController, @@ -49,163 +58,623 @@ class RvcOperationalStateCluster( class AttributeListAttribute(val value: List) suspend fun pause(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: RvcOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + RvcOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun stop(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: RvcOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + RvcOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun start(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: RvcOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + RvcOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun resume(timedInvokeTimeoutMs: Int? = null): OperationalCommandResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: RvcOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + RvcOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) } suspend fun readPhaseListAttribute(): PhaseListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribePhaseListAttribute(minInterval: Int, maxInterval: Int): PhaseListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Phaselist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PhaseListAttribute(decodedValue) } suspend fun readCurrentPhaseAttribute(): CurrentPhaseAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentPhaseAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPhaseAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentphase attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPhaseAttribute(decodedValue) } suspend fun readCountdownTimeAttribute(): CountdownTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCountdownTimeAttribute( - minInterval: Int, - maxInterval: Int - ): CountdownTimeAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Countdowntime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CountdownTimeAttribute(decodedValue) } suspend fun readOperationalStateListAttribute(): OperationalStateListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalstatelist attribute not found in response" } - suspend fun subscribeOperationalStateListAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalStateListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(RvcOperationalStateClusterOperationalStateStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return OperationalStateListAttribute(decodedValue) } suspend fun readOperationalStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeOperationalStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationalstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOperationalErrorAttribute(): OperationalErrorAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeOperationalErrorAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalErrorAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Operationalerror attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: RvcOperationalStateClusterErrorStateStruct = + RvcOperationalStateClusterErrorStateStruct.fromTlv(AnonymousTag, tlvReader) + + return OperationalErrorAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(RvcOperationalStateCluster::class.java.name) const val CLUSTER_ID: UInt = 97u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcRunModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcRunModeCluster.kt index 6c4879b6144e03..5c8faaef858748 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcRunModeCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/RvcRunModeCluster.kt @@ -17,11 +17,20 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class RvcRunModeCluster(private val controller: MatterController, private val endpointId: UShort) { - class ChangeToModeResponse(val status: UInt, val statusText: String?) + class ChangeToModeResponse(val status: UByte, val statusText: String?) class SupportedModesAttribute(val value: List) @@ -39,108 +48,437 @@ class RvcRunModeCluster(private val controller: MatterController, private val en newMode: UByte, timedInvokeTimeoutMs: Int? = null ): ChangeToModeResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) } suspend fun readSupportedModesAttribute(): SupportedModesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeSupportedModesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedModesAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(RvcRunModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return SupportedModesAttribute(decodedValue) } suspend fun readCurrentModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readOnModeAttribute(): OnModeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) } - suspend fun subscribeOnModeAttribute(minInterval: Int, maxInterval: Int): OnModeAttribute { - // Implementation needs to be added here + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(RvcRunModeCluster::class.java.name) const val CLUSTER_ID: UInt = 84u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SampleMeiCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SampleMeiCluster.kt index a19737df6c3d4e..dac11958f33293 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SampleMeiCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SampleMeiCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class SampleMeiCluster(private val controller: MatterController, private val endpointId: UShort) { class AddArgumentsResponse(val returnValue: UByte) @@ -32,13 +41,23 @@ class SampleMeiCluster(private val controller: MatterController, private val end class AttributeListAttribute(val value: List) suspend fun ping(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun addArguments( @@ -46,89 +65,344 @@ class SampleMeiCluster(private val controller: MatterController, private val end arg2: UByte, timedInvokeTimeoutMs: Int? = null ): AddArgumentsResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) + + val TAG_ARG2_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ARG2_REQ), arg2) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_RETURN_VALUE: Int = 0 + var returnValue_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_RETURN_VALUE)) { + returnValue_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (returnValue_decoded == null) { + throw IllegalStateException("returnValue not found in TLV") } + + tlvReader.exitContainer() + + return AddArgumentsResponse(returnValue_decoded) } suspend fun readFlipFlopAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun writeFlipFlopAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Flipflop attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } - suspend fun subscribeFlipFlopAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun writeFlipFlopAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(SampleMeiCluster::class.java.name) const val CLUSTER_ID: UInt = 4294048800u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ScenesCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ScenesCluster.kt index 0a19851046e346..9ee914f9da9652 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ScenesCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ScenesCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ScenesCluster(private val controller: MatterController, private val endpointId: UShort) { class AddSceneResponse(val status: UByte, val groupID: UShort, val sceneID: UByte) @@ -82,13 +91,88 @@ class ScenesCluster(private val controller: MatterController, private val endpoi extensionFieldSets: List, timedInvokeTimeoutMs: Int? = null ): AddSceneResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_SCENE_NAME_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_NAME_REQ), sceneName) + + val TAG_EXTENSION_FIELD_SETS_REQ: Int = 4 + tlvWriter.startArray(ContextSpecificTag(TAG_EXTENSION_FIELD_SETS_REQ)) + for (item in extensionFieldSets.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_SCENE_I_D: Int = 2 + var sceneID_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_I_D)) { + sceneID_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + if (sceneID_decoded == null) { + throw IllegalStateException("sceneID not found in TLV") + } + + tlvReader.exitContainer() + + return AddSceneResponse(status_decoded, groupID_decoded, sceneID_decoded) } suspend fun viewScene( @@ -96,13 +180,139 @@ class ScenesCluster(private val controller: MatterController, private val endpoi sceneID: UByte, timedInvokeTimeoutMs: Int? = null ): ViewSceneResponse { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_SCENE_I_D: Int = 2 + var sceneID_decoded: UByte? = null + + val TAG_TRANSITION_TIME: Int = 3 + var transitionTime_decoded: UShort? = null + + val TAG_SCENE_NAME: Int = 4 + var sceneName_decoded: String? = null + + val TAG_EXTENSION_FIELD_SETS: Int = 5 + var extensionFieldSets_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_I_D)) { + sceneID_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_TRANSITION_TIME)) { + transitionTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_SCENE_NAME)) { + sceneName_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_EXTENSION_FIELD_SETS)) { + extensionFieldSets_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(ScenesClusterExtensionFieldSet.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + if (sceneID_decoded == null) { + throw IllegalStateException("sceneID not found in TLV") + } + + tlvReader.exitContainer() + + return ViewSceneResponse( + status_decoded, + groupID_decoded, + sceneID_decoded, + transitionTime_decoded, + sceneName_decoded, + extensionFieldSets_decoded + ) } suspend fun removeScene( @@ -110,26 +320,136 @@ class ScenesCluster(private val controller: MatterController, private val endpoi sceneID: UByte, timedInvokeTimeoutMs: Int? = null ): RemoveSceneResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_SCENE_I_D: Int = 2 + var sceneID_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_I_D)) { + sceneID_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + if (sceneID_decoded == null) { + throw IllegalStateException("sceneID not found in TLV") + } + + tlvReader.exitContainer() + + return RemoveSceneResponse(status_decoded, groupID_decoded, sceneID_decoded) } suspend fun removeAllScenes( groupID: UShort, timedInvokeTimeoutMs: Int? = null ): RemoveAllScenesResponse { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + tlvReader.exitContainer() + + return RemoveAllScenesResponse(status_decoded, groupID_decoded) } suspend fun storeScene( @@ -137,13 +457,75 @@ class ScenesCluster(private val controller: MatterController, private val endpoi sceneID: UByte, timedInvokeTimeoutMs: Int? = null ): StoreSceneResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_SCENE_I_D: Int = 2 + var sceneID_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_I_D)) { + sceneID_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") } + + if (sceneID_decoded == null) { + throw IllegalStateException("sceneID not found in TLV") + } + + tlvReader.exitContainer() + + return StoreSceneResponse(status_decoded, groupID_decoded, sceneID_decoded) } suspend fun recallScene( @@ -152,26 +534,141 @@ class ScenesCluster(private val controller: MatterController, private val endpoi transitionTime: UShort?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + transitionTime?.let { + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getSceneMembership( groupID: UShort, timedInvokeTimeoutMs: Int? = null ): GetSceneMembershipResponse { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_CAPACITY: Int = 1 + var capacity_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 2 + var groupID_decoded: UShort? = null + + val TAG_SCENE_LIST: Int = 3 + var sceneList_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_CAPACITY)) { + capacity_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + tlvReader.getUByte(tag) + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_LIST)) { + sceneList_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") } + + tlvReader.exitContainer() + + return GetSceneMembershipResponse( + status_decoded, + capacity_decoded, + groupID_decoded, + sceneList_decoded + ) } suspend fun enhancedAddScene( @@ -182,13 +679,88 @@ class ScenesCluster(private val controller: MatterController, private val endpoi extensionFieldSets: List, timedInvokeTimeoutMs: Int? = null ): EnhancedAddSceneResponse { - val commandId = 64L + val commandId: UInt = 64u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + + val TAG_TRANSITION_TIME_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_TRANSITION_TIME_REQ), transitionTime) + + val TAG_SCENE_NAME_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_NAME_REQ), sceneName) + + val TAG_EXTENSION_FIELD_SETS_REQ: Int = 4 + tlvWriter.startArray(ContextSpecificTag(TAG_EXTENSION_FIELD_SETS_REQ)) + for (item in extensionFieldSets.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_SCENE_I_D: Int = 2 + var sceneID_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_I_D)) { + sceneID_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + if (sceneID_decoded == null) { + throw IllegalStateException("sceneID not found in TLV") + } + + tlvReader.exitContainer() + + return EnhancedAddSceneResponse(status_decoded, groupID_decoded, sceneID_decoded) } suspend fun enhancedViewScene( @@ -196,166 +768,734 @@ class ScenesCluster(private val controller: MatterController, private val endpoi sceneID: UByte, timedInvokeTimeoutMs: Int? = null ): EnhancedViewSceneResponse { - val commandId = 65L + val commandId: UInt = 65u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_GROUP_I_D_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_I_D_REQ), groupID) + + val TAG_SCENE_I_D_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_I_D_REQ), sceneID) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_I_D: Int = 1 + var groupID_decoded: UShort? = null + + val TAG_SCENE_I_D: Int = 2 + var sceneID_decoded: UByte? = null + + val TAG_TRANSITION_TIME: Int = 3 + var transitionTime_decoded: UShort? = null + + val TAG_SCENE_NAME: Int = 4 + var sceneName_decoded: String? = null + + val TAG_EXTENSION_FIELD_SETS: Int = 5 + var extensionFieldSets_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_I_D)) { + groupID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_I_D)) { + sceneID_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_TRANSITION_TIME)) { + transitionTime_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_SCENE_NAME)) { + sceneName_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_EXTENSION_FIELD_SETS)) { + extensionFieldSets_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(ScenesClusterExtensionFieldSet.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } + + if (groupID_decoded == null) { + throw IllegalStateException("groupID not found in TLV") + } + + if (sceneID_decoded == null) { + throw IllegalStateException("sceneID not found in TLV") + } + + tlvReader.exitContainer() + + return EnhancedViewSceneResponse( + status_decoded, + groupID_decoded, + sceneID_decoded, + transitionTime_decoded, + sceneName_decoded, + extensionFieldSets_decoded + ) } suspend fun copyScene( - mode: UInt, + mode: UByte, groupIdentifierFrom: UShort, sceneIdentifierFrom: UByte, groupIdentifierTo: UShort, sceneIdentifierTo: UByte, timedInvokeTimeoutMs: Int? = null ): CopySceneResponse { - val commandId = 66L + val commandId: UInt = 66u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MODE_REQ), mode) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_GROUP_IDENTIFIER_FROM_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_IDENTIFIER_FROM_REQ), groupIdentifierFrom) + + val TAG_SCENE_IDENTIFIER_FROM_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_IDENTIFIER_FROM_REQ), sceneIdentifierFrom) + + val TAG_GROUP_IDENTIFIER_TO_REQ: Int = 3 + tlvWriter.put(ContextSpecificTag(TAG_GROUP_IDENTIFIER_TO_REQ), groupIdentifierTo) + + val TAG_SCENE_IDENTIFIER_TO_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_SCENE_IDENTIFIER_TO_REQ), sceneIdentifierTo) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_GROUP_IDENTIFIER_FROM: Int = 1 + var groupIdentifierFrom_decoded: UShort? = null + + val TAG_SCENE_IDENTIFIER_FROM: Int = 2 + var sceneIdentifierFrom_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_GROUP_IDENTIFIER_FROM)) { + groupIdentifierFrom_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_SCENE_IDENTIFIER_FROM)) { + sceneIdentifierFrom_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } } - } - suspend fun readSceneCountAttribute(): UByte { - // Implementation needs to be added here - } + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } - suspend fun subscribeSceneCountAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + if (groupIdentifierFrom_decoded == null) { + throw IllegalStateException("groupIdentifierFrom not found in TLV") + } - suspend fun readCurrentSceneAttribute(): UByte { - // Implementation needs to be added here - } + if (sceneIdentifierFrom_decoded == null) { + throw IllegalStateException("sceneIdentifierFrom not found in TLV") + } + + tlvReader.exitContainer() - suspend fun subscribeCurrentSceneAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return CopySceneResponse( + status_decoded, + groupIdentifierFrom_decoded, + sceneIdentifierFrom_decoded + ) } - suspend fun readCurrentGroupAttribute(): UShort { - // Implementation needs to be added here + suspend fun readSceneCountAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scenecount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeCurrentGroupAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readCurrentSceneAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentscene attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readSceneValidAttribute(): Boolean { - // Implementation needs to be added here + suspend fun readCurrentGroupAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentgroup attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeSceneValidAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readSceneValidAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scenevalid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readNameSupportAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeNameSupportAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Namesupport attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readLastConfiguredByAttribute(): LastConfiguredByAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeLastConfiguredByAttribute( - minInterval: Int, - maxInterval: Int - ): LastConfiguredByAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Lastconfiguredby attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LastConfiguredByAttribute(decodedValue) } suspend fun readSceneTableSizeAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Scenetablesize attribute not found in response" } - suspend fun subscribeSceneTableSizeAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } suspend fun readFabricSceneInfoAttribute(): FabricSceneInfoAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun readFabricSceneInfoAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): FabricSceneInfoAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFabricSceneInfoAttribute( - minInterval: Int, - maxInterval: Int - ): FabricSceneInfoAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Fabricsceneinfo attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ScenesClusterSceneInfoStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return FabricSceneInfoAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ScenesCluster::class.java.name) const val CLUSTER_ID: UInt = 5u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SmokeCoAlarmCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SmokeCoAlarmCluster.kt index 384b52fbfcfea7..76d2a7397717a2 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SmokeCoAlarmCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SmokeCoAlarmCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class SmokeCoAlarmCluster( private val controller: MatterController, @@ -33,185 +41,726 @@ class SmokeCoAlarmCluster( class AttributeListAttribute(val value: List) suspend fun selfTestRequest(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readExpressedStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeExpressedStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readSmokeStateAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Expressedstate attribute not found in response" } - suspend fun subscribeSmokeStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readCOStateAttribute(): UByte { - // Implementation needs to be added here + suspend fun readSmokeStateAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Smokestate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeCOStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readCOStateAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Costate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readBatteryAlertAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeBatteryAlertAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readDeviceMutedAttribute(): UByte { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Batteryalert attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeDeviceMutedAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readDeviceMutedAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Devicemuted attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readTestInProgressAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeTestInProgressAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Testinprogress attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readHardwareFaultAlertAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Hardwarefaultalert attribute not found in response" } - suspend fun subscribeHardwareFaultAlertAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } suspend fun readEndOfServiceAlertAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeEndOfServiceAlertAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readInterconnectSmokeAlarmAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeInterconnectSmokeAlarmAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readInterconnectCOAlarmAttribute(): UByte { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeInterconnectCOAlarmAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readContaminationStateAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeContaminationStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Endofservicealert attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readSmokeSensitivityLevelAttribute(): UByte { - // Implementation needs to be added here + suspend fun readInterconnectSmokeAlarmAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Interconnectsmokealarm attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeSmokeSensitivityLevelAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readInterconnectCOAlarmAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Interconnectcoalarm attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeSmokeSensitivityLevelAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readContaminationStateAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Contaminationstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readExpiryDateAttribute(): UInt { - // Implementation needs to be added here + suspend fun readSmokeSensitivityLevelAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Smokesensitivitylevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeSmokeSensitivityLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 11u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeExpiryDateAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readExpiryDateAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Expirydate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(SmokeCoAlarmCluster::class.java.name) const val CLUSTER_ID: UInt = 92u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SoftwareDiagnosticsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SoftwareDiagnosticsCluster.kt index 0132daa4368246..ca8344fdca52cc 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SoftwareDiagnosticsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SoftwareDiagnosticsCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class SoftwareDiagnosticsCluster( private val controller: MatterController, @@ -35,111 +43,391 @@ class SoftwareDiagnosticsCluster( class AttributeListAttribute(val value: List) suspend fun resetWatermarks(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readThreadMetricsAttribute(): ThreadMetricsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeThreadMetricsAttribute( - minInterval: Int, - maxInterval: Int - ): ThreadMetricsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readCurrentHeapFreeAttribute(): ULong { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCurrentHeapFreeAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Threadmetrics attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(SoftwareDiagnosticsClusterThreadMetricsStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } - suspend fun readCurrentHeapUsedAttribute(): ULong { - // Implementation needs to be added here + return ThreadMetricsAttribute(decodedValue) } - suspend fun subscribeCurrentHeapUsedAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun readCurrentHeapFreeAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentheapfree attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readCurrentHeapHighWatermarkAttribute(): ULong { - // Implementation needs to be added here + suspend fun readCurrentHeapUsedAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentheapused attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeCurrentHeapHighWatermarkAttribute( - minInterval: Int, - maxInterval: Int - ): ULong { - // Implementation needs to be added here + suspend fun readCurrentHeapHighWatermarkAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentheaphighwatermark attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(SoftwareDiagnosticsCluster::class.java.name) const val CLUSTER_ID: UInt = 52u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SwitchCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SwitchCluster.kt index a27cc29bd7b640..39fd1cf22e7c7a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SwitchCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/SwitchCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class SwitchCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -30,87 +35,319 @@ class SwitchCluster(private val controller: MatterController, private val endpoi class AttributeListAttribute(val value: List) suspend fun readNumberOfPositionsAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeNumberOfPositionsAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofpositions attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readCurrentPositionAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeCurrentPositionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMultiPressMaxAttribute(): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentposition attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeMultiPressMaxAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMultiPressMaxAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Multipressmax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(SwitchCluster::class.java.name) const val CLUSTER_ID: UInt = 59u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TargetNavigatorCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TargetNavigatorCluster.kt index 691bc7adc452b1..77d8a698e72782 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TargetNavigatorCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TargetNavigatorCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class TargetNavigatorCluster( private val controller: MatterController, private val endpointId: UShort ) { - class NavigateTargetResponse(val status: UInt, val data: String?) + class NavigateTargetResponse(val status: UByte, val data: String?) class TargetListAttribute(val value: List) @@ -41,92 +50,362 @@ class TargetNavigatorCluster( data: String?, timedInvokeTimeoutMs: Int? = null ): NavigateTargetResponse { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TARGET_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TARGET_REQ), target) + + val TAG_DATA_REQ: Int = 1 + data?.let { tlvWriter.put(ContextSpecificTag(TAG_DATA_REQ), data) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_DATA: Int = 1 + var data_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return NavigateTargetResponse(status_decoded, data_decoded) } suspend fun readTargetListAttribute(): TargetListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeTargetListAttribute( - minInterval: Int, - maxInterval: Int - ): TargetListAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readCurrentTargetAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Targetlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(TargetNavigatorClusterTargetInfoStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return TargetListAttribute(decodedValue) } - suspend fun subscribeCurrentTargetAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readCurrentTargetAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currenttarget attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(TargetNavigatorCluster::class.java.name) const val CLUSTER_ID: UInt = 1285u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureControlCluster.kt index 978f543f84231a..1c83c274b0314c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class TemperatureControlCluster( private val controller: MatterController, @@ -39,127 +48,473 @@ class TemperatureControlCluster( targetTemperatureLevel: UByte?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TARGET_TEMPERATURE_REQ: Int = 0 + targetTemperature?.let { + tlvWriter.put(ContextSpecificTag(TAG_TARGET_TEMPERATURE_REQ), targetTemperature) } - } - suspend fun readTemperatureSetpointAttribute(): Short { - // Implementation needs to be added here - } + val TAG_TARGET_TEMPERATURE_LEVEL_REQ: Int = 1 + targetTemperatureLevel?.let { + tlvWriter.put(ContextSpecificTag(TAG_TARGET_TEMPERATURE_LEVEL_REQ), targetTemperatureLevel) + } + tlvWriter.endStructure() - suspend fun subscribeTemperatureSetpointAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) - suspend fun readMinTemperatureAttribute(): Short { - // Implementation needs to be added here + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun subscribeMinTemperatureAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readTemperatureSetpointAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 0u - suspend fun readMaxTemperatureAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMaxTemperatureAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Temperaturesetpoint attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readStepAttribute(): Short { - // Implementation needs to be added here + suspend fun readMinTemperatureAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Mintemperature attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeStepAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here + suspend fun readMaxTemperatureAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxtemperature attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readSelectedTemperatureLevelAttribute(): UByte { - // Implementation needs to be added here + suspend fun readStepAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Step attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeSelectedTemperatureLevelAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here + suspend fun readSelectedTemperatureLevelAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Selectedtemperaturelevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readSupportedTemperatureLevelsAttribute(): SupportedTemperatureLevelsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSupportedTemperatureLevelsAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedTemperatureLevelsAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedtemperaturelevels attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return SupportedTemperatureLevelsAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(TemperatureControlCluster::class.java.name) const val CLUSTER_ID: UInt = 86u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureMeasurementCluster.kt index 5c6a6ff41fd1eb..56b30a72f071e4 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TemperatureMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class TemperatureMeasurementCluster( private val controller: MatterController, @@ -39,104 +44,368 @@ class TemperatureMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readToleranceAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } - suspend fun subscribeToleranceAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readToleranceAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Tolerance attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(TemperatureMeasurementCluster::class.java.name) const val CLUSTER_ID: UInt = 1026u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatCluster.kt index 6eeddc77e8fb7f..1c31b1b3c404cb 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatCluster.kt @@ -17,14 +17,23 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ThermostatCluster(private val controller: MatterController, private val endpointId: UShort) { class GetWeeklyScheduleResponse( val numberOfTransitionsForSequence: UByte, - val dayOfWeekForSequence: UInt, - val modeForSequence: UInt, + val dayOfWeekForSequence: UByte, + val modeForSequence: UByte, val transitions: List ) @@ -58,810 +67,3388 @@ class ThermostatCluster(private val controller: MatterController, private val en class AttributeListAttribute(val value: List) - suspend fun setpointRaiseLower(mode: UInt, amount: Byte, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + suspend fun setpointRaiseLower(mode: UByte, amount: Byte, timedInvokeTimeoutMs: Int? = null) { + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_MODE_REQ), mode) + + val TAG_AMOUNT_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_AMOUNT_REQ), amount) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setWeeklySchedule( numberOfTransitionsForSequence: UByte, - dayOfWeekForSequence: UInt, - modeForSequence: UInt, + dayOfWeekForSequence: UByte, + modeForSequence: UByte, transitions: List, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NUMBER_OF_TRANSITIONS_FOR_SEQUENCE_REQ: Int = 0 + tlvWriter.put( + ContextSpecificTag(TAG_NUMBER_OF_TRANSITIONS_FOR_SEQUENCE_REQ), + numberOfTransitionsForSequence + ) + + val TAG_DAY_OF_WEEK_FOR_SEQUENCE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_DAY_OF_WEEK_FOR_SEQUENCE_REQ), dayOfWeekForSequence) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_MODE_FOR_SEQUENCE_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_MODE_FOR_SEQUENCE_REQ), modeForSequence) + + val TAG_TRANSITIONS_REQ: Int = 3 + tlvWriter.startArray(ContextSpecificTag(TAG_TRANSITIONS_REQ)) + for (item in transitions.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun getWeeklySchedule( - daysToReturn: UInt, - modeToReturn: UInt, + daysToReturn: UByte, + modeToReturn: UByte, timedInvokeTimeoutMs: Int? = null ): GetWeeklyScheduleResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DAYS_TO_RETURN_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_DAYS_TO_RETURN_REQ), daysToReturn) + + val TAG_MODE_TO_RETURN_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_MODE_TO_RETURN_REQ), modeToReturn) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NUMBER_OF_TRANSITIONS_FOR_SEQUENCE: Int = 0 + var numberOfTransitionsForSequence_decoded: UByte? = null + + val TAG_DAY_OF_WEEK_FOR_SEQUENCE: Int = 1 + var dayOfWeekForSequence_decoded: UByte? = null + + val TAG_MODE_FOR_SEQUENCE: Int = 2 + var modeForSequence_decoded: UByte? = null + + val TAG_TRANSITIONS: Int = 3 + var transitions_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NUMBER_OF_TRANSITIONS_FOR_SEQUENCE)) { + numberOfTransitionsForSequence_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DAY_OF_WEEK_FOR_SEQUENCE)) { + dayOfWeekForSequence_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_MODE_FOR_SEQUENCE)) { + modeForSequence_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_TRANSITIONS)) { + transitions_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(ThermostatClusterWeeklyScheduleTransitionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (numberOfTransitionsForSequence_decoded == null) { + throw IllegalStateException("numberOfTransitionsForSequence not found in TLV") } - } - suspend fun clearWeeklySchedule(timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L + if (dayOfWeekForSequence_decoded == null) { + throw IllegalStateException("dayOfWeekForSequence not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (modeForSequence_decoded == null) { + throw IllegalStateException("modeForSequence not found in TLV") } - } - suspend fun readLocalTemperatureAttribute(): LocalTemperatureAttribute { - // Implementation needs to be added here - } + if (transitions_decoded == null) { + throw IllegalStateException("transitions not found in TLV") + } - suspend fun subscribeLocalTemperatureAttribute( - minInterval: Int, - maxInterval: Int - ): LocalTemperatureAttribute { - // Implementation needs to be added here - } + tlvReader.exitContainer() - suspend fun readOutdoorTemperatureAttribute(): OutdoorTemperatureAttribute { - // Implementation needs to be added here + return GetWeeklyScheduleResponse( + numberOfTransitionsForSequence_decoded, + dayOfWeekForSequence_decoded, + modeForSequence_decoded, + transitions_decoded + ) } - suspend fun subscribeOutdoorTemperatureAttribute( - minInterval: Int, - maxInterval: Int - ): OutdoorTemperatureAttribute { - // Implementation needs to be added here - } + suspend fun clearWeeklySchedule(timedInvokeTimeoutMs: Int? = null) { + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - suspend fun readOccupancyAttribute(): UByte { - // Implementation needs to be added here - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() - suspend fun subscribeOccupancyAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) - suspend fun readAbsMinHeatSetpointLimitAttribute(): Short { - // Implementation needs to be added here + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun subscribeAbsMinHeatSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + suspend fun readLocalTemperatureAttribute(): LocalTemperatureAttribute { + val ATTRIBUTE_ID: UInt = 0u - suspend fun readAbsMaxHeatSetpointLimitAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAbsMaxHeatSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readAbsMinCoolSetpointLimitAttribute(): Short { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeAbsMinCoolSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readAbsMaxCoolSetpointLimitAttribute(): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeAbsMaxCoolSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readPICoolingDemandAttribute(): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Localtemperature attribute not found in response" } - suspend fun subscribePICoolingDemandAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readPIHeatingDemandAttribute(): UByte { - // Implementation needs to be added here + return LocalTemperatureAttribute(decodedValue) } - suspend fun subscribePIHeatingDemandAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + suspend fun readOutdoorTemperatureAttribute(): OutdoorTemperatureAttribute { + val ATTRIBUTE_ID: UInt = 1u - suspend fun readHVACSystemTypeConfigurationAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeHVACSystemTypeConfigurationAttribute( - value: UInt, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeHVACSystemTypeConfigurationAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readLocalTemperatureCalibrationAttribute(): Byte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeLocalTemperatureCalibrationAttribute( - value: Byte, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Outdoortemperature attribute not found in response" } - suspend fun subscribeLocalTemperatureCalibrationAttribute( - minInterval: Int, - maxInterval: Int - ): Byte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readOccupiedCoolingSetpointAttribute(): Short { - // Implementation needs to be added here + return OutdoorTemperatureAttribute(decodedValue) } - suspend fun writeOccupiedCoolingSetpointAttribute( - value: Short, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readOccupancyAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u - suspend fun subscribeOccupiedCoolingSetpointAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readOccupiedHeatingSetpointAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeOccupiedHeatingSetpointAttribute( - value: Short, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeOccupiedHeatingSetpointAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readUnoccupiedCoolingSetpointAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeUnoccupiedCoolingSetpointAttribute( - value: Short, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Occupancy attribute not found in response" } - suspend fun subscribeUnoccupiedCoolingSetpointAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun readUnoccupiedHeatingSetpointAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun writeUnoccupiedHeatingSetpointAttribute( - value: Short, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readAbsMinHeatSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeUnoccupiedHeatingSetpointAttribute( - minInterval: Int, - maxInterval: Int - ): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMinHeatSetpointLimitAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeMinHeatSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeMinHeatSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readMaxHeatSetpointLimitAttribute(): Short { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeMaxHeatSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Absminheatsetpointlimit attribute not found in response" } - suspend fun subscribeMaxHeatSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun readMinCoolSetpointLimitAttribute(): Short { - // Implementation needs to be added here + return decodedValue } - suspend fun writeMinCoolSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readAbsMaxHeatSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 4u - suspend fun subscribeMinCoolSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readMaxCoolSetpointLimitAttribute(): Short { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeMaxCoolSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeMaxCoolSetpointLimitAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readMinSetpointDeadBandAttribute(): Byte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeMinSetpointDeadBandAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Absmaxheatsetpointlimit attribute not found in response" } - suspend fun subscribeMinSetpointDeadBandAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun readRemoteSensingAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun writeRemoteSensingAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + suspend fun readAbsMinCoolSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeRemoteSensingAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readControlSequenceOfOperationAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeControlSequenceOfOperationAttribute( - value: UInt, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeControlSequenceOfOperationAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readSystemModeAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeSystemModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Absmincoolsetpointlimit attribute not found in response" } - suspend fun subscribeSystemModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun readThermostatRunningModeAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeThermostatRunningModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + suspend fun readAbsMaxCoolSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 6u - suspend fun readStartOfWeekAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeStartOfWeekAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readNumberOfWeeklyTransitionsAttribute(): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeNumberOfWeeklyTransitionsAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readNumberOfDailyTransitionsAttribute(): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeNumberOfDailyTransitionsAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readTemperatureSetpointHoldAttribute(): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Absmaxcoolsetpointlimit attribute not found in response" } - suspend fun writeTemperatureSetpointHoldAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeTemperatureSetpointHoldAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun readTemperatureSetpointHoldDurationAttribute(): - TemperatureSetpointHoldDurationAttribute { - // Implementation needs to be added here - } + suspend fun readPICoolingDemandAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 7u - suspend fun writeTemperatureSetpointHoldDurationAttribute( - value: UShort, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeTemperatureSetpointHoldDurationAttribute( - minInterval: Int, - maxInterval: Int - ): TemperatureSetpointHoldDurationAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readThermostatProgrammingOperationModeAttribute(): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeThermostatProgrammingOperationModeAttribute( - value: UInt, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - - suspend fun subscribeThermostatProgrammingOperationModeAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here - } - suspend fun readThermostatRunningStateAttribute(): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeThermostatRunningStateAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readSetpointChangeSourceAttribute(): UByte { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Picoolingdemand attribute not found in response" } - suspend fun subscribeSetpointChangeSourceAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun readSetpointChangeAmountAttribute(): SetpointChangeAmountAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeSetpointChangeAmountAttribute( - minInterval: Int, - maxInterval: Int - ): SetpointChangeAmountAttribute { - // Implementation needs to be added here - } + suspend fun readPIHeatingDemandAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u - suspend fun readSetpointChangeSourceTimestampAttribute(): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeSetpointChangeSourceTimestampAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readOccupiedSetbackAttribute(): OccupiedSetbackAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeOccupiedSetbackAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeOccupiedSetbackAttribute( - minInterval: Int, - maxInterval: Int - ): OccupiedSetbackAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readOccupiedSetbackMinAttribute(): OccupiedSetbackMinAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeOccupiedSetbackMinAttribute( - minInterval: Int, - maxInterval: Int - ): OccupiedSetbackMinAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Piheatingdemand attribute not found in response" } - suspend fun readOccupiedSetbackMaxAttribute(): OccupiedSetbackMaxAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } - suspend fun subscribeOccupiedSetbackMaxAttribute( - minInterval: Int, - maxInterval: Int - ): OccupiedSetbackMaxAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readUnoccupiedSetbackAttribute(): UnoccupiedSetbackAttribute { - // Implementation needs to be added here - } + suspend fun readHVACSystemTypeConfigurationAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u - suspend fun writeUnoccupiedSetbackAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeUnoccupiedSetbackAttribute( - minInterval: Int, - maxInterval: Int - ): UnoccupiedSetbackAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readUnoccupiedSetbackMinAttribute(): UnoccupiedSetbackMinAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeUnoccupiedSetbackMinAttribute( - minInterval: Int, - maxInterval: Int - ): UnoccupiedSetbackMinAttribute { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readUnoccupiedSetbackMaxAttribute(): UnoccupiedSetbackMaxAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeUnoccupiedSetbackMaxAttribute( - minInterval: Int, - maxInterval: Int - ): UnoccupiedSetbackMaxAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Hvacsystemtypeconfiguration attribute not found in response" } - suspend fun readEmergencyHeatDeltaAttribute(): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeEmergencyHeatDeltaAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeHVACSystemTypeConfigurationAttribute( + value: UByte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 9u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeEmergencyHeatDeltaAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + suspend fun readLocalTemperatureCalibrationAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 16u - suspend fun readACTypeAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeACTypeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeACTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readACCapacityAttribute(): UShort { - // Implementation needs to be added here + requireNotNull(attributeData) { "Localtemperaturecalibration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeACCapacityAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeLocalTemperatureCalibrationAttribute( + value: Byte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeACCapacityAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readOccupiedCoolingSetpointAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 17u - suspend fun readACRefrigerantTypeAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeACRefrigerantTypeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeACRefrigerantTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupiedcoolingsetpoint attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun readACCompressorTypeAttribute(): UByte { - // Implementation needs to be added here + return decodedValue } - suspend fun writeACCompressorTypeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeOccupiedCoolingSetpointAttribute( + value: Short, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 17u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeACCompressorTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + suspend fun readOccupiedHeatingSetpointAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 18u - suspend fun readACErrorCodeAttribute(): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun writeACErrorCodeAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeACErrorCodeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupiedheatingsetpoint attribute not found in response" } - suspend fun readACLouverPositionAttribute(): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun writeACLouverPositionAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeOccupiedHeatingSetpointAttribute( + value: Short, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 18u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeACLouverPositionAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + suspend fun readUnoccupiedCoolingSetpointAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 19u - suspend fun readACCoilTemperatureAttribute(): ACCoilTemperatureAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeACCoilTemperatureAttribute( - minInterval: Int, - maxInterval: Int - ): ACCoilTemperatureAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readACCapacityformatAttribute(): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeACCapacityformatAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeACCapacityformatAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Unoccupiedcoolingsetpoint attribute not found in response" } - suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here + suspend fun writeUnoccupiedCoolingSetpointAttribute( + value: Short, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 19u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here - } + suspend fun readUnoccupiedHeatingSetpointAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 20u - suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Unoccupiedheatingsetpoint attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeUnoccupiedHeatingSetpointAttribute( + value: Short, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 20u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readMinHeatSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 21u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minheatsetpointlimit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeMinHeatSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 21u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readMaxHeatSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxheatsetpointlimit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeMaxHeatSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 22u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readMinCoolSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 23u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Mincoolsetpointlimit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeMinCoolSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 23u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readMaxCoolSetpointLimitAttribute(): Short? { + val ATTRIBUTE_ID: UInt = 24u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxcoolsetpointlimit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeMaxCoolSetpointLimitAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 24u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readMinSetpointDeadBandAttribute(): Byte? { + val ATTRIBUTE_ID: UInt = 25u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minsetpointdeadband attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeMinSetpointDeadBandAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 25u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRemoteSensingAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Remotesensing attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeRemoteSensingAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 26u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readControlSequenceOfOperationAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 27u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Controlsequenceofoperation attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeControlSequenceOfOperationAttribute( + value: UByte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 27u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readSystemModeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 28u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Systemmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeSystemModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 28u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readThermostatRunningModeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 30u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Thermostatrunningmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readStartOfWeekAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 32u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startofweek attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readNumberOfWeeklyTransitionsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofweeklytransitions attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readNumberOfDailyTransitionsAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofdailytransitions attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTemperatureSetpointHoldAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 35u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Temperaturesetpointhold attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeTemperatureSetpointHoldAttribute( + value: UByte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 35u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readTemperatureSetpointHoldDurationAttribute(): + TemperatureSetpointHoldDurationAttribute { + val ATTRIBUTE_ID: UInt = 36u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Temperaturesetpointholdduration attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return TemperatureSetpointHoldDurationAttribute(decodedValue) + } + + suspend fun writeTemperatureSetpointHoldDurationAttribute( + value: UShort, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 36u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readThermostatProgrammingOperationModeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 37u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Thermostatprogrammingoperationmode attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeThermostatProgrammingOperationModeAttribute( + value: UByte, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 37u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readThermostatRunningStateAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 41u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Thermostatrunningstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readSetpointChangeSourceAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Setpointchangesource attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readSetpointChangeAmountAttribute(): SetpointChangeAmountAttribute { + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Setpointchangeamount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SetpointChangeAmountAttribute(decodedValue) + } + + suspend fun readSetpointChangeSourceTimestampAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Setpointchangesourcetimestamp attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readOccupiedSetbackAttribute(): OccupiedSetbackAttribute { + val ATTRIBUTE_ID: UInt = 52u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupiedsetback attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OccupiedSetbackAttribute(decodedValue) + } + + suspend fun writeOccupiedSetbackAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 52u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readOccupiedSetbackMinAttribute(): OccupiedSetbackMinAttribute { + val ATTRIBUTE_ID: UInt = 53u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupiedsetbackmin attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OccupiedSetbackMinAttribute(decodedValue) + } + + suspend fun readOccupiedSetbackMaxAttribute(): OccupiedSetbackMaxAttribute { + val ATTRIBUTE_ID: UInt = 54u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Occupiedsetbackmax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OccupiedSetbackMaxAttribute(decodedValue) + } + + suspend fun readUnoccupiedSetbackAttribute(): UnoccupiedSetbackAttribute { + val ATTRIBUTE_ID: UInt = 55u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Unoccupiedsetback attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return UnoccupiedSetbackAttribute(decodedValue) + } + + suspend fun writeUnoccupiedSetbackAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 55u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readUnoccupiedSetbackMinAttribute(): UnoccupiedSetbackMinAttribute { + val ATTRIBUTE_ID: UInt = 56u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Unoccupiedsetbackmin attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return UnoccupiedSetbackMinAttribute(decodedValue) + } + + suspend fun readUnoccupiedSetbackMaxAttribute(): UnoccupiedSetbackMaxAttribute { + val ATTRIBUTE_ID: UInt = 57u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Unoccupiedsetbackmax attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return UnoccupiedSetbackMaxAttribute(decodedValue) + } + + suspend fun readEmergencyHeatDeltaAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 58u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Emergencyheatdelta attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeEmergencyHeatDeltaAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 58u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACTypeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 64u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Actype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACTypeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 64u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACCapacityAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 65u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accapacity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACCapacityAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 65u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACRefrigerantTypeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 66u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acrefrigeranttype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACRefrigerantTypeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 66u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACCompressorTypeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 67u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accompressortype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACCompressorTypeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 67u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACErrorCodeAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 68u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acerrorcode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACErrorCodeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 68u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACLouverPositionAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 69u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Aclouverposition attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACLouverPositionAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 69u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readACCoilTemperatureAttribute(): ACCoilTemperatureAttribute { + val ATTRIBUTE_ID: UInt = 70u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accoiltemperature attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ACCoilTemperatureAttribute(decodedValue) + } + + suspend fun readACCapacityformatAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 71u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Accapacityformat attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeACCapacityformatAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 71u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } companion object { + private val logger = Logger.getLogger(ThermostatCluster::class.java.name) const val CLUSTER_ID: UInt = 513u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt index 12ed570344c446..1b43203609b013 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThermostatUserInterfaceConfigurationCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ThermostatUserInterfaceConfigurationCluster( private val controller: MatterController, @@ -33,117 +40,451 @@ class ThermostatUserInterfaceConfigurationCluster( class AttributeListAttribute(val value: List) suspend fun readTemperatureDisplayModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun writeTemperatureDisplayModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Temperaturedisplaymode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeTemperatureDisplayModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeTemperatureDisplayModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readKeypadLockoutAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeKeypadLockoutAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Keypadlockout attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeKeypadLockoutAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeKeypadLockoutAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun readScheduleProgrammingVisibilityAttribute(): UByte { - // Implementation needs to be added here + suspend fun readScheduleProgrammingVisibilityAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Scheduleprogrammingvisibility attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun writeScheduleProgrammingVisibilityAttribute( - value: UInt, + value: UByte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } - suspend fun subscribeScheduleProgrammingVisibilityAttribute( - minInterval: Int, - maxInterval: Int - ): UByte { - // Implementation needs to be added here + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger(ThermostatUserInterfaceConfigurationCluster::class.java.name) const val CLUSTER_ID: UInt = 516u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt index 86e2cb8e290a64..41e863dc58b3ec 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ThreadNetworkDiagnosticsCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ThreadNetworkDiagnosticsCluster( private val controller: MatterController, @@ -26,7 +34,7 @@ class ThreadNetworkDiagnosticsCluster( ) { class ChannelAttribute(val value: UShort?) - class RoutingRoleAttribute(val value: UInt?) + class RoutingRoleAttribute(val value: UByte?) class NetworkNameAttribute(val value: String?) @@ -64,7 +72,7 @@ class ThreadNetworkDiagnosticsCluster( val value: ThreadNetworkDiagnosticsClusterOperationalDatasetComponents? ) - class ActiveNetworkFaultsListAttribute(val value: List) + class ActiveNetworkFaultsListAttribute(val value: List) class GeneratedCommandListAttribute(val value: List) @@ -75,637 +83,2548 @@ class ThreadNetworkDiagnosticsCluster( class AttributeListAttribute(val value: List) suspend fun resetCounts(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readChannelAttribute(): ChannelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Channel attribute not found in response" } - suspend fun subscribeChannelAttribute(minInterval: Int, maxInterval: Int): ChannelAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ChannelAttribute(decodedValue) } suspend fun readRoutingRoleAttribute(): RoutingRoleAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRoutingRoleAttribute( - minInterval: Int, - maxInterval: Int - ): RoutingRoleAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Routingrole attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return RoutingRoleAttribute(decodedValue) } suspend fun readNetworkNameAttribute(): NetworkNameAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Networkname attribute not found in response" } - suspend fun subscribeNetworkNameAttribute( - minInterval: Int, - maxInterval: Int - ): NetworkNameAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (!tlvReader.isNull()) { + tlvReader.getString(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NetworkNameAttribute(decodedValue) } suspend fun readPanIdAttribute(): PanIdAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribePanIdAttribute(minInterval: Int, maxInterval: Int): PanIdAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Panid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PanIdAttribute(decodedValue) } suspend fun readExtendedPanIdAttribute(): ExtendedPanIdAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Extendedpanid attribute not found in response" } - suspend fun subscribeExtendedPanIdAttribute( - minInterval: Int, - maxInterval: Int - ): ExtendedPanIdAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ExtendedPanIdAttribute(decodedValue) } suspend fun readMeshLocalPrefixAttribute(): MeshLocalPrefixAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeMeshLocalPrefixAttribute( - minInterval: Int, - maxInterval: Int - ): MeshLocalPrefixAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readOverrunCountAttribute(): ULong { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Meshlocalprefix attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeshLocalPrefixAttribute(decodedValue) } - suspend fun subscribeOverrunCountAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here + suspend fun readOverrunCountAttribute(): ULong? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Overruncount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readNeighborTableAttribute(): NeighborTableAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeNeighborTableAttribute( - minInterval: Int, - maxInterval: Int - ): NeighborTableAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Neighbortable attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ThreadNetworkDiagnosticsClusterNeighborTableStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return NeighborTableAttribute(decodedValue) } suspend fun readRouteTableAttribute(): RouteTableAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Routetable attribute not found in response" } - suspend fun subscribeRouteTableAttribute( - minInterval: Int, - maxInterval: Int - ): RouteTableAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ThreadNetworkDiagnosticsClusterRouteTableStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return RouteTableAttribute(decodedValue) } suspend fun readPartitionIdAttribute(): PartitionIdAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePartitionIdAttribute( - minInterval: Int, - maxInterval: Int - ): PartitionIdAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Partitionid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PartitionIdAttribute(decodedValue) } suspend fun readWeightingAttribute(): WeightingAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Weighting attribute not found in response" } - suspend fun subscribeWeightingAttribute(minInterval: Int, maxInterval: Int): WeightingAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return WeightingAttribute(decodedValue) } suspend fun readDataVersionAttribute(): DataVersionAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeDataVersionAttribute( - minInterval: Int, - maxInterval: Int - ): DataVersionAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Dataversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return DataVersionAttribute(decodedValue) } suspend fun readStableDataVersionAttribute(): StableDataVersionAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Stabledataversion attribute not found in response" } - suspend fun subscribeStableDataVersionAttribute( - minInterval: Int, - maxInterval: Int - ): StableDataVersionAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StableDataVersionAttribute(decodedValue) } suspend fun readLeaderRouterIdAttribute(): LeaderRouterIdAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 13u - suspend fun subscribeLeaderRouterIdAttribute( - minInterval: Int, - maxInterval: Int - ): LeaderRouterIdAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readDetachedRoleCountAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeDetachedRoleCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readChildRoleCountAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeChildRoleCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRouterRoleCountAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeRouterRoleCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Leaderrouterid attribute not found in response" } - suspend fun readLeaderRoleCountAttribute(): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeLeaderRoleCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return LeaderRouterIdAttribute(decodedValue) } - suspend fun readAttachAttemptCountAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readDetachedRoleCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 14u - suspend fun subscribeAttachAttemptCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPartitionIdChangeCountAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePartitionIdChangeCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readBetterPartitionAttachAttemptCountAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeBetterPartitionAttachAttemptCountAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readParentChangeCountAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeParentChangeCountAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Detachedrolecount attribute not found in response" } - suspend fun readTxTotalCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeTxTotalCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readTxUnicastCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readChildRoleCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 15u - suspend fun subscribeTxUnicastCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readTxBroadcastCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeTxBroadcastCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readTxAckRequestedCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeTxAckRequestedCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTxAckedCountAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTxAckedCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Childrolecount attribute not found in response" } - suspend fun readTxNoAckRequestedCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeTxNoAckRequestedCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readTxDataCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readRouterRoleCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16u - suspend fun subscribeTxDataCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readTxDataPollCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeTxDataPollCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readTxBeaconCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeTxBeaconCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTxBeaconRequestCountAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTxBeaconRequestCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Routerrolecount attribute not found in response" } - suspend fun readTxOtherCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeTxOtherCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readTxRetryCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readLeaderRoleCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 17u - suspend fun subscribeTxRetryCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readTxDirectMaxRetryExpiryCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeTxDirectMaxRetryExpiryCountAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readTxIndirectMaxRetryExpiryCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeTxIndirectMaxRetryExpiryCountAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTxErrCcaCountAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTxErrCcaCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Leaderrolecount attribute not found in response" } - suspend fun readTxErrAbortCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeTxErrAbortCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readTxErrBusyChannelCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readAttachAttemptCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 18u - suspend fun subscribeTxErrBusyChannelCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRxTotalCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRxTotalCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readRxUnicastCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeRxUnicastCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRxBroadcastCountAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeRxBroadcastCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Attachattemptcount attribute not found in response" } - suspend fun readRxDataCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeRxDataCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readRxDataPollCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readPartitionIdChangeCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 19u - suspend fun subscribeRxDataPollCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRxBeaconCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRxBeaconCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readRxBeaconRequestCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeRxBeaconRequestCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRxOtherCountAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeRxOtherCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Partitionidchangecount attribute not found in response" } - suspend fun readRxAddressFilteredCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeRxAddressFilteredCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readRxDestAddrFilteredCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readBetterPartitionAttachAttemptCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 20u - suspend fun subscribeRxDestAddrFilteredCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRxDuplicatedCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRxDuplicatedCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readRxErrNoFrameCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeRxErrNoFrameCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRxErrUnknownNeighborCountAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeRxErrUnknownNeighborCountAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + requireNotNull(attributeData) { + "Betterpartitionattachattemptcount attribute not found in response" + } - suspend fun readRxErrInvalidSrcAddrCountAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribeRxErrInvalidSrcAddrCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readRxErrSecCountAttribute(): UInt { - // Implementation needs to be added here - } + suspend fun readParentChangeCountAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 21u - suspend fun subscribeRxErrSecCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readRxErrFcsCountAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeRxErrFcsCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readRxErrOtherCountAttribute(): UInt { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeRxErrOtherCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readActiveTimestampAttribute(): ActiveTimestampAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeActiveTimestampAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveTimestampAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Parentchangecount attribute not found in response" } - suspend fun readPendingTimestampAttribute(): PendingTimestampAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } - suspend fun subscribePendingTimestampAttribute( - minInterval: Int, - maxInterval: Int - ): PendingTimestampAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readDelayAttribute(): DelayAttribute { - // Implementation needs to be added here - } + suspend fun readTxTotalCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 22u - suspend fun subscribeDelayAttribute(minInterval: Int, maxInterval: Int): DelayAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readSecurityPolicyAttribute(): SecurityPolicyAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeSecurityPolicyAttribute( - minInterval: Int, - maxInterval: Int - ): SecurityPolicyAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readChannelPage0MaskAttribute(): ChannelPage0MaskAttribute { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeChannelPage0MaskAttribute( - minInterval: Int, - maxInterval: Int - ): ChannelPage0MaskAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readOperationalDatasetComponentsAttribute(): OperationalDatasetComponentsAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeOperationalDatasetComponentsAttribute( - minInterval: Int, - maxInterval: Int - ): OperationalDatasetComponentsAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Txtotalcount attribute not found in response" } - suspend fun readActiveNetworkFaultsListAttribute(): ActiveNetworkFaultsListAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } - suspend fun subscribeActiveNetworkFaultsListAttribute( - minInterval: Int, - maxInterval: Int - ): ActiveNetworkFaultsListAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + suspend fun readTxUnicastCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 23u - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Txunicastcount attribute not found in response" } - suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here + suspend fun readTxBroadcastCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 24u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txbroadcastcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxAckRequestedCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 25u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txackrequestedcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxAckedCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txackedcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxNoAckRequestedCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 27u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txnoackrequestedcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxDataCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 28u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txdatacount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxDataPollCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 29u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txdatapollcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxBeaconCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 30u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txbeaconcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxBeaconRequestCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 31u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txbeaconrequestcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxOtherCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 32u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txothercount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxRetryCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txretrycount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxDirectMaxRetryExpiryCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txdirectmaxretryexpirycount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxIndirectMaxRetryExpiryCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 35u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Txindirectmaxretryexpirycount attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxErrCcaCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 36u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txerrccacount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxErrAbortCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 37u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txerrabortcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readTxErrBusyChannelCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 38u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Txerrbusychannelcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxTotalCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 39u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxtotalcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxUnicastCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 40u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxunicastcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxBroadcastCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 41u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxbroadcastcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxDataCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 42u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxdatacount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxDataPollCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 43u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxdatapollcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxBeaconCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 44u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxbeaconcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxBeaconRequestCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 45u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxbeaconrequestcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxOtherCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 46u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxothercount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxAddressFilteredCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 47u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxaddressfilteredcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxDestAddrFilteredCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxdestaddrfilteredcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxDuplicatedCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxduplicatedcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxErrNoFrameCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxerrnoframecount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxErrUnknownNeighborCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 51u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxerrunknownneighborcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxErrInvalidSrcAddrCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 52u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxerrinvalidsrcaddrcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxErrSecCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 53u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxerrseccount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxErrFcsCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 54u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxerrfcscount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readRxErrOtherCountAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 55u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rxerrothercount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun readActiveTimestampAttribute(): ActiveTimestampAttribute { + val ATTRIBUTE_ID: UInt = 56u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activetimestamp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ActiveTimestampAttribute(decodedValue) + } + + suspend fun readPendingTimestampAttribute(): PendingTimestampAttribute { + val ATTRIBUTE_ID: UInt = 57u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Pendingtimestamp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PendingTimestampAttribute(decodedValue) + } + + suspend fun readDelayAttribute(): DelayAttribute { + val ATTRIBUTE_ID: UInt = 58u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Delay attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return DelayAttribute(decodedValue) } - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readSecurityPolicyAttribute(): SecurityPolicyAttribute { + val ATTRIBUTE_ID: UInt = 59u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Securitypolicy attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ThreadNetworkDiagnosticsClusterSecurityPolicy? = + if (!tlvReader.isNull()) { + ThreadNetworkDiagnosticsClusterSecurityPolicy.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SecurityPolicyAttribute(decodedValue) + } + + suspend fun readChannelPage0MaskAttribute(): ChannelPage0MaskAttribute { + val ATTRIBUTE_ID: UInt = 60u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Channelpage0mask attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ChannelPage0MaskAttribute(decodedValue) + } + + suspend fun readOperationalDatasetComponentsAttribute(): OperationalDatasetComponentsAttribute { + val ATTRIBUTE_ID: UInt = 61u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Operationaldatasetcomponents attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ThreadNetworkDiagnosticsClusterOperationalDatasetComponents? = + if (!tlvReader.isNull()) { + ThreadNetworkDiagnosticsClusterOperationalDatasetComponents.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OperationalDatasetComponentsAttribute(decodedValue) + } + + suspend fun readActiveNetworkFaultsListAttribute(): ActiveNetworkFaultsListAttribute { + val ATTRIBUTE_ID: UInt = 62u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activenetworkfaultslist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return ActiveNetworkFaultsListAttribute(decodedValue) + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue } companion object { + private val logger = Logger.getLogger(ThreadNetworkDiagnosticsCluster::class.java.name) const val CLUSTER_ID: UInt = 53u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeFormatLocalizationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeFormatLocalizationCluster.kt index d3916cb0db2233..a17c5155dd52e2 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeFormatLocalizationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeFormatLocalizationCluster.kt @@ -17,14 +17,21 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class TimeFormatLocalizationCluster( private val controller: MatterController, private val endpointId: UShort ) { - class SupportedCalendarTypesAttribute(val value: List?) + class SupportedCalendarTypesAttribute(val value: List?) class GeneratedCommandListAttribute(val value: List) @@ -35,106 +42,414 @@ class TimeFormatLocalizationCluster( class AttributeListAttribute(val value: List) suspend fun readHourFormatAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun writeHourFormatAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeHourFormatAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Hourformat attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readActiveCalendarTypeAttribute(): UByte { - // Implementation needs to be added here + suspend fun writeHourFormatAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun writeActiveCalendarTypeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readActiveCalendarTypeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Activecalendartype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeActiveCalendarTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeActiveCalendarTypeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readSupportedCalendarTypesAttribute(): SupportedCalendarTypesAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeSupportedCalendarTypesAttribute( - minInterval: Int, - maxInterval: Int - ): SupportedCalendarTypesAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedcalendartypes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return SupportedCalendarTypesAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(TimeFormatLocalizationCluster::class.java.name) const val CLUSTER_ID: UInt = 44u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeSynchronizationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeSynchronizationCluster.kt index d9b0d983141f95..6cd9a035e51f97 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeSynchronizationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimeSynchronizationCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class TimeSynchronizationCluster( private val controller: MatterController, @@ -48,236 +57,880 @@ class TimeSynchronizationCluster( suspend fun setUTCTime( UTCTime: ULong, - granularity: UInt, - timeSource: UInt?, + granularity: UByte, + timeSource: UByte?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_U_T_C_TIME_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_U_T_C_TIME_REQ), UTCTime) + + val TAG_GRANULARITY_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_GRANULARITY_REQ), granularity) + + val TAG_TIME_SOURCE_REQ: Int = 2 + timeSource?.let { tlvWriter.put(ContextSpecificTag(TAG_TIME_SOURCE_REQ), timeSource) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setTrustedTimeSource( trustedTimeSource: TimeSynchronizationClusterFabricScopedTrustedTimeSourceStruct?, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_TRUSTED_TIME_SOURCE_REQ: Int = 0 + trustedTimeSource?.let { + trustedTimeSource.toTlv(ContextSpecificTag(TAG_TRUSTED_TIME_SOURCE_REQ), tlvWriter) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setTimeZone( timeZone: List, timedInvokeTimeoutMs: Int? = null ): SetTimeZoneResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TIME_ZONE_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_TIME_ZONE_REQ)) + for (item in timeZone.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_D_S_T_OFFSET_REQUIRED: Int = 0 + var DSTOffsetRequired_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_D_S_T_OFFSET_REQUIRED)) { + DSTOffsetRequired_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } } + + if (DSTOffsetRequired_decoded == null) { + throw IllegalStateException("DSTOffsetRequired not found in TLV") + } + + tlvReader.exitContainer() + + return SetTimeZoneResponse(DSTOffsetRequired_decoded) } suspend fun setDSTOffset( DSTOffset: List, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_D_S_T_OFFSET_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_D_S_T_OFFSET_REQ)) + for (item in DSTOffset.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setDefaultNTP(defaultNTP: String?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_DEFAULT_N_T_P_REQ: Int = 0 + defaultNTP?.let { tlvWriter.put(ContextSpecificTag(TAG_DEFAULT_N_T_P_REQ), defaultNTP) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readUTCTimeAttribute(): UTCTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeUTCTimeAttribute(minInterval: Int, maxInterval: Int): UTCTimeAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Utctime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return UTCTimeAttribute(decodedValue) } suspend fun readGranularityAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeGranularityAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readTimeSourceAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Granularity attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun subscribeTimeSourceAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readTimeSourceAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timesource attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readTrustedTimeSourceAttribute(): TrustedTimeSourceAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribeTrustedTimeSourceAttribute( - minInterval: Int, - maxInterval: Int - ): TrustedTimeSourceAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Trustedtimesource attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: TimeSynchronizationClusterTrustedTimeSourceStruct? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + TimeSynchronizationClusterTrustedTimeSourceStruct.fromTlv(AnonymousTag, tlvReader) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return TrustedTimeSourceAttribute(decodedValue) } suspend fun readDefaultNTPAttribute(): DefaultNTPAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeDefaultNTPAttribute( - minInterval: Int, - maxInterval: Int - ): DefaultNTPAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Defaultntp attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return DefaultNTPAttribute(decodedValue) } suspend fun readTimeZoneAttribute(): TimeZoneAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTimeZoneAttribute(minInterval: Int, maxInterval: Int): TimeZoneAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Timezone attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(TimeSynchronizationClusterTimeZoneStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return TimeZoneAttribute(decodedValue) } suspend fun readDSTOffsetAttribute(): DSTOffsetAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeDSTOffsetAttribute(minInterval: Int, maxInterval: Int): DSTOffsetAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Dstoffset attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(TimeSynchronizationClusterDSTOffsetStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return DSTOffsetAttribute(decodedValue) } suspend fun readLocalTimeAttribute(): LocalTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u - suspend fun subscribeLocalTimeAttribute(minInterval: Int, maxInterval: Int): LocalTimeAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readTimeZoneDatabaseAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeTimeZoneDatabaseAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readNTPServerAvailableAttribute(): Boolean { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeNTPServerAvailableAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun readTimeZoneListMaxSizeAttribute(): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Localtime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return LocalTimeAttribute(decodedValue) } - suspend fun subscribeTimeZoneListMaxSizeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readTimeZoneDatabaseAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timezonedatabase attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readDSTOffsetListMaxSizeAttribute(): UByte { - // Implementation needs to be added here + suspend fun readNTPServerAvailableAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Ntpserveravailable attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeDSTOffsetListMaxSizeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readTimeZoneListMaxSizeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timezonelistmaxsize attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readSupportsDNSResolveAttribute(): Boolean { - // Implementation needs to be added here + suspend fun readDSTOffsetListMaxSizeAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Dstoffsetlistmaxsize attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeSupportsDNSResolveAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun readSupportsDNSResolveAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportsdnsresolve attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(TimeSynchronizationCluster::class.java.name) const val CLUSTER_ID: UInt = 56u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimerCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimerCluster.kt index 2ec115fde7742e..83198c68f612c6 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimerCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TimerCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class TimerCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -30,127 +39,403 @@ class TimerCluster(private val controller: MatterController, private val endpoin class AttributeListAttribute(val value: List) suspend fun setTimer(newTime: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_TIME_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_TIME_REQ), newTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun resetTimer(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun addTime(additionalTime: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ADDITIONAL_TIME_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ADDITIONAL_TIME_REQ), additionalTime) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun reduceTime(timeReduction: UInt, timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L - - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TIME_REDUCTION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TIME_REDUCTION_REQ), timeReduction) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readSetTimeAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeSetTimeAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Settime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readTimeRemainingAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeTimeRemainingAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timeremaining attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readTimerStateAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timerstate attribute not found in response" } - suspend fun subscribeTimerStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(TimerCluster::class.java.name) const val CLUSTER_ID: UInt = 71u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TotalVolatileOrganicCompoundsConcentrationMeasurementCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TotalVolatileOrganicCompoundsConcentrationMeasurementCluster.kt index bd37b97759d83e..87720edf99a0a9 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TotalVolatileOrganicCompoundsConcentrationMeasurementCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/TotalVolatileOrganicCompoundsConcentrationMeasurementCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class TotalVolatileOrganicCompoundsConcentrationMeasurementCluster( private val controller: MatterController, @@ -43,169 +48,645 @@ class TotalVolatileOrganicCompoundsConcentrationMeasurementCluster( class AttributeListAttribute(val value: List) suspend fun readMeasuredValueAttribute(): MeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MeasuredValueAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MeasuredValueAttribute(decodedValue) } suspend fun readMinMeasuredValueAttribute(): MinMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u - suspend fun subscribeMinMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MinMeasuredValueAttribute { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Minmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MinMeasuredValueAttribute(decodedValue) } suspend fun readMaxMeasuredValueAttribute(): MaxMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeMaxMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): MaxMeasuredValueAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Maxmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return MaxMeasuredValueAttribute(decodedValue) } suspend fun readPeakMeasuredValueAttribute(): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u - suspend fun subscribePeakMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): PeakMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readPeakMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PeakMeasuredValueAttribute(decodedValue) } - suspend fun subscribePeakMeasuredValueWindowAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + suspend fun readPeakMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Peakmeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readAverageMeasuredValueAttribute(): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u - suspend fun subscribeAverageMeasuredValueAttribute( - minInterval: Int, - maxInterval: Int - ): AverageMeasuredValueAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readAverageMeasuredValueWindowAttribute(): UInt { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAverageMeasuredValueWindowAttribute( - minInterval: Int, - maxInterval: Int - ): UInt { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readUncertaintyAttribute(): Float { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeUncertaintyAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readMeasurementUnitAttribute(): UByte { - // Implementation needs to be added here + return AverageMeasuredValueAttribute(decodedValue) } - suspend fun subscribeMeasurementUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readAverageMeasuredValueWindowAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Averagemeasuredvaluewindow attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readMeasurementMediumAttribute(): UByte { - // Implementation needs to be added here + suspend fun readUncertaintyAttribute(): Float? { + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Uncertainty attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getFloat(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeMeasurementMediumAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readMeasurementUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readLevelValueAttribute(): UByte { - // Implementation needs to be added here + suspend fun readMeasurementMediumAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Measurementmedium attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeLevelValueAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readLevelValueAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Levelvalue attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = + Logger.getLogger( + TotalVolatileOrganicCompoundsConcentrationMeasurementCluster::class.java.name + ) const val CLUSTER_ID: UInt = 1070u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitLocalizationCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitLocalizationCluster.kt index 573489cd5d60bd..4dfcba67bcc99b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitLocalizationCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitLocalizationCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class UnitLocalizationCluster( private val controller: MatterController, @@ -32,80 +39,300 @@ class UnitLocalizationCluster( class AttributeListAttribute(val value: List) - suspend fun readTemperatureUnitAttribute(): UByte { - // Implementation needs to be added here - } + suspend fun readTemperatureUnitAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeTemperatureUnitAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Temperatureunit attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeTemperatureUnitAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeTemperatureUnitAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(UnitLocalizationCluster::class.java.name) const val CLUSTER_ID: UInt = 45u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitTestingCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitTestingCluster.kt index 30cfa97aab4cec..c0ba1fdad157c5 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitTestingCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UnitTestingCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class UnitTestingCluster(private val controller: MatterController, private val endpointId: UShort) { class TestSpecificResponse(val returnValue: UByte) @@ -30,9 +39,9 @@ class UnitTestingCluster(private val controller: MatterController, private val e class TestStructArrayArgumentResponse( val arg1: List, val arg2: List, - val arg3: List, + val arg3: List, val arg4: List, - val arg5: UInt, + val arg5: UByte, val arg6: Boolean ) @@ -40,7 +49,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e class TestListInt8UReverseResponse(val arg1: List) - class TestEnumsResponse(val arg1: UShort, val arg2: UInt) + class TestEnumsResponse(val arg1: UShort, val arg2: UByte) class TestNullableOptionalResponse( val wasPresent: Boolean, @@ -72,12 +81,12 @@ class UnitTestingCluster(private val controller: MatterController, private val e val nullableOptionalStructWasNull: Boolean?, val nullableOptionalStructValue: UnitTestingClusterSimpleStruct?, val nullableListWasNull: Boolean, - val nullableListValue: List?, + val nullableListValue: List?, val optionalListWasPresent: Boolean, - val optionalListValue: List?, + val optionalListValue: List?, val nullableOptionalListWasPresent: Boolean, val nullableOptionalListWasNull: Boolean?, - val nullableOptionalListValue: List? + val nullableOptionalListValue: List? ) class SimpleStructResponse(val arg1: UnitTestingClusterSimpleStruct) @@ -104,11 +113,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e class NullableBooleanAttribute(val value: Boolean?) - class NullableBitmap8Attribute(val value: UInt?) + class NullableBitmap8Attribute(val value: UByte?) - class NullableBitmap16Attribute(val value: UInt?) + class NullableBitmap16Attribute(val value: UShort?) - class NullableBitmap32Attribute(val value: ULong?) + class NullableBitmap32Attribute(val value: UInt?) class NullableBitmap64Attribute(val value: ULong?) @@ -144,9 +153,9 @@ class UnitTestingCluster(private val controller: MatterController, private val e class NullableInt64sAttribute(val value: Long?) - class NullableEnum8Attribute(val value: UInt?) + class NullableEnum8Attribute(val value: UByte?) - class NullableEnum16Attribute(val value: UInt?) + class NullableEnum16Attribute(val value: UShort?) class NullableFloatSingleAttribute(val value: Float?) @@ -156,7 +165,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e class NullableCharStringAttribute(val value: String?) - class NullableEnumAttrAttribute(val value: UInt?) + class NullableEnumAttrAttribute(val value: UByte?) class NullableStructAttribute(val value: UnitTestingClusterSimpleStruct?) @@ -177,43 +186,107 @@ class UnitTestingCluster(private val controller: MatterController, private val e class AttributeListAttribute(val value: List) suspend fun test(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun testNotHandled(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun testSpecific(timedInvokeTimeoutMs: Int? = null): TestSpecificResponse { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_RETURN_VALUE: Int = 0 + var returnValue_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_RETURN_VALUE)) { + returnValue_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (returnValue_decoded == null) { + throw IllegalStateException("returnValue not found in TLV") } + + tlvReader.exitContainer() + + return TestSpecificResponse(returnValue_decoded) } suspend fun testUnknownCommand(timedInvokeTimeoutMs: Int? = null) { - val commandId = 3L + val commandId: UInt = 3u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun testAddArguments( @@ -221,162 +294,828 @@ class UnitTestingCluster(private val controller: MatterController, private val e arg2: UByte, timedInvokeTimeoutMs: Int? = null ): TestAddArgumentsResponse { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) + + val TAG_ARG2_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ARG2_REQ), arg2) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_RETURN_VALUE: Int = 0 + var returnValue_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_RETURN_VALUE)) { + returnValue_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (returnValue_decoded == null) { + throw IllegalStateException("returnValue not found in TLV") } + + tlvReader.exitContainer() + + return TestAddArgumentsResponse(returnValue_decoded) } suspend fun testSimpleArgumentRequest( arg1: Boolean, timedInvokeTimeoutMs: Int? = null ): TestSimpleArgumentResponse { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_RETURN_VALUE: Int = 0 + var returnValue_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_RETURN_VALUE)) { + returnValue_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (returnValue_decoded == null) { + throw IllegalStateException("returnValue not found in TLV") } + + tlvReader.exitContainer() + + return TestSimpleArgumentResponse(returnValue_decoded) } suspend fun testStructArrayArgumentRequest( arg1: List, arg2: List, - arg3: List, + arg3: List, arg4: List, - arg5: UInt, + arg5: UByte, arg6: Boolean, timedInvokeTimeoutMs: Int? = null ): TestStructArrayArgumentResponse { - val commandId = 6L + val commandId: UInt = 6u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG1_REQ)) + for (item in arg1.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val TAG_ARG2_REQ: Int = 1 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG2_REQ)) + for (item in arg2.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val TAG_ARG3_REQ: Int = 2 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG3_REQ)) + for (item in arg3.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + + val TAG_ARG4_REQ: Int = 3 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG4_REQ)) + for (item in arg4.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + + val TAG_ARG5_REQ: Int = 4 + tlvWriter.put(ContextSpecificTag(TAG_ARG5_REQ), arg5) + + val TAG_ARG6_REQ: Int = 5 + tlvWriter.put(ContextSpecificTag(TAG_ARG6_REQ), arg6) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ARG1: Int = 0 + var arg1_decoded: List? = null + + val TAG_ARG2: Int = 1 + var arg2_decoded: List? = null + + val TAG_ARG3: Int = 2 + var arg3_decoded: List? = null + + val TAG_ARG4: Int = 3 + var arg4_decoded: List? = null + + val TAG_ARG5: Int = 4 + var arg5_decoded: UByte? = null + + val TAG_ARG6: Int = 5 + var arg6_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ARG1)) { + arg1_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(UnitTestingClusterNestedStructList.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } + + if (tag == ContextSpecificTag(TAG_ARG2)) { + arg2_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(UnitTestingClusterSimpleStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } + + if (tag == ContextSpecificTag(TAG_ARG3)) { + arg3_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } + + if (tag == ContextSpecificTag(TAG_ARG4)) { + arg4_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getBoolean(AnonymousTag)) + } + tlvReader.exitContainer() + } + } + + if (tag == ContextSpecificTag(TAG_ARG5)) { + arg5_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_ARG6)) { + arg6_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (arg1_decoded == null) { + throw IllegalStateException("arg1 not found in TLV") + } + + if (arg2_decoded == null) { + throw IllegalStateException("arg2 not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (arg3_decoded == null) { + throw IllegalStateException("arg3 not found in TLV") } + + if (arg4_decoded == null) { + throw IllegalStateException("arg4 not found in TLV") + } + + if (arg5_decoded == null) { + throw IllegalStateException("arg5 not found in TLV") + } + + if (arg6_decoded == null) { + throw IllegalStateException("arg6 not found in TLV") + } + + tlvReader.exitContainer() + + return TestStructArrayArgumentResponse( + arg1_decoded, + arg2_decoded, + arg3_decoded, + arg4_decoded, + arg5_decoded, + arg6_decoded + ) } suspend fun testStructArgumentRequest( arg1: UnitTestingClusterSimpleStruct, timedInvokeTimeoutMs: Int? = null ): BooleanResponse { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + arg1.toTlv(ContextSpecificTag(TAG_ARG1_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return BooleanResponse(value_decoded) } suspend fun testNestedStructArgumentRequest( arg1: UnitTestingClusterNestedStruct, timedInvokeTimeoutMs: Int? = null ): BooleanResponse { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + arg1.toTlv(ContextSpecificTag(TAG_ARG1_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return BooleanResponse(value_decoded) } suspend fun testListStructArgumentRequest( arg1: List, timedInvokeTimeoutMs: Int? = null ): BooleanResponse { - val commandId = 9L + val commandId: UInt = 9u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG1_REQ)) + for (item in arg1.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return BooleanResponse(value_decoded) } suspend fun testListInt8UArgumentRequest( arg1: List, timedInvokeTimeoutMs: Int? = null ): BooleanResponse { - val commandId = 10L + val commandId: UInt = 10u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG1_REQ)) + for (item in arg1.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return BooleanResponse(value_decoded) } suspend fun testNestedStructListArgumentRequest( arg1: UnitTestingClusterNestedStructList, timedInvokeTimeoutMs: Int? = null ): BooleanResponse { - val commandId = 11L + val commandId: UInt = 11u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + arg1.toTlv(ContextSpecificTag(TAG_ARG1_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return BooleanResponse(value_decoded) } suspend fun testListNestedStructListArgumentRequest( arg1: List, timedInvokeTimeoutMs: Int? = null ): BooleanResponse { - val commandId = 12L + val commandId: UInt = 12u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG1_REQ)) + for (item in arg1.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: Boolean? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getBoolean(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return BooleanResponse(value_decoded) } suspend fun testListInt8UReverseRequest( arg1: List, timedInvokeTimeoutMs: Int? = null ): TestListInt8UReverseResponse { - val commandId = 13L + val commandId: UInt = 13u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + val TAG_ARG1_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_ARG1_REQ)) + for (item in arg1.iterator()) { + tlvWriter.put(AnonymousTag, item) } + tlvWriter.endArray() + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ARG1: Int = 0 + var arg1_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ARG1)) { + arg1_decoded = + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (arg1_decoded == null) { + throw IllegalStateException("arg1 not found in TLV") + } + + tlvReader.exitContainer() + + return TestListInt8UReverseResponse(arg1_decoded) } suspend fun testEnumsRequest( arg1: UShort, - arg2: UInt, + arg2: UByte, timedInvokeTimeoutMs: Int? = null ): TestEnumsResponse { - val commandId = 14L + val commandId: UInt = 14u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) + + val TAG_ARG2_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ARG2_REQ), arg2) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ARG1: Int = 0 + var arg1_decoded: UShort? = null + + val TAG_ARG2: Int = 1 + var arg2_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ARG1)) { + arg1_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_ARG2)) { + arg2_decoded = tlvReader.getUByte(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (arg1_decoded == null) { + throw IllegalStateException("arg1 not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (arg2_decoded == null) { + throw IllegalStateException("arg2 not found in TLV") } + + tlvReader.exitContainer() + + return TestEnumsResponse(arg1_decoded, arg2_decoded) } suspend fun testNullableOptionalRequest( arg1: UByte?, timedInvokeTimeoutMs: Int? = null ): TestNullableOptionalResponse { - val commandId = 15L + val commandId: UInt = 15u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + arg1?.let { tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_WAS_PRESENT: Int = 0 + var wasPresent_decoded: Boolean? = null + + val TAG_WAS_NULL: Int = 1 + var wasNull_decoded: Boolean? = null + + val TAG_VALUE: Int = 2 + var value_decoded: UByte? = null + + val TAG_ORIGINAL_VALUE: Int = 3 + var originalValue_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_WAS_PRESENT)) { + wasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_WAS_NULL)) { + wasNull_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getBoolean(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_ORIGINAL_VALUE)) { + originalValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUByte(tag) + } else { + null + } + } else { + tlvReader.getNull(tag) + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (wasPresent_decoded == null) { + throw IllegalStateException("wasPresent not found in TLV") } + + tlvReader.exitContainer() + + return TestNullableOptionalResponse( + wasPresent_decoded, + wasNull_decoded, + value_decoded, + originalValue_decoded + ) } suspend fun testComplexNullableOptionalRequest( @@ -389,1603 +1128,7281 @@ class UnitTestingCluster(private val controller: MatterController, private val e nullableStruct: UnitTestingClusterSimpleStruct?, optionalStruct: UnitTestingClusterSimpleStruct?, nullableOptionalStruct: UnitTestingClusterSimpleStruct?, - nullableList: List?, - optionalList: List?, - nullableOptionalList: List?, + nullableList: List?, + optionalList: List?, + nullableOptionalList: List?, timedInvokeTimeoutMs: Int? = null ): TestComplexNullableOptionalResponse { - val commandId = 16L + val commandId: UInt = 16u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NULLABLE_INT_REQ: Int = 0 + nullableInt?.let { tlvWriter.put(ContextSpecificTag(TAG_NULLABLE_INT_REQ), nullableInt) } + + val TAG_OPTIONAL_INT_REQ: Int = 1 + optionalInt?.let { tlvWriter.put(ContextSpecificTag(TAG_OPTIONAL_INT_REQ), optionalInt) } + + val TAG_NULLABLE_OPTIONAL_INT_REQ: Int = 2 + nullableOptionalInt?.let { + tlvWriter.put(ContextSpecificTag(TAG_NULLABLE_OPTIONAL_INT_REQ), nullableOptionalInt) + } + + val TAG_NULLABLE_STRING_REQ: Int = 3 + nullableString?.let { + tlvWriter.put(ContextSpecificTag(TAG_NULLABLE_STRING_REQ), nullableString) + } + + val TAG_OPTIONAL_STRING_REQ: Int = 4 + optionalString?.let { + tlvWriter.put(ContextSpecificTag(TAG_OPTIONAL_STRING_REQ), optionalString) + } + + val TAG_NULLABLE_OPTIONAL_STRING_REQ: Int = 5 + nullableOptionalString?.let { + tlvWriter.put(ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRING_REQ), nullableOptionalString) + } + + val TAG_NULLABLE_STRUCT_REQ: Int = 6 + nullableStruct?.let { + nullableStruct.toTlv(ContextSpecificTag(TAG_NULLABLE_STRUCT_REQ), tlvWriter) + } + + val TAG_OPTIONAL_STRUCT_REQ: Int = 7 + optionalStruct?.let { + optionalStruct.toTlv(ContextSpecificTag(TAG_OPTIONAL_STRUCT_REQ), tlvWriter) + } + + val TAG_NULLABLE_OPTIONAL_STRUCT_REQ: Int = 8 + nullableOptionalStruct?.let { + nullableOptionalStruct.toTlv(ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRUCT_REQ), tlvWriter) + } + + val TAG_NULLABLE_LIST_REQ: Int = 9 + nullableList?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_NULLABLE_LIST_REQ)) + for (item in nullableList.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + } + + val TAG_OPTIONAL_LIST_REQ: Int = 10 + optionalList?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_OPTIONAL_LIST_REQ)) + for (item in optionalList.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + } + + val TAG_NULLABLE_OPTIONAL_LIST_REQ: Int = 11 + nullableOptionalList?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_NULLABLE_OPTIONAL_LIST_REQ)) + for (item in nullableOptionalList.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_NULLABLE_INT_WAS_NULL: Int = 0 + var nullableIntWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_INT_VALUE: Int = 1 + var nullableIntValue_decoded: UShort? = null + + val TAG_OPTIONAL_INT_WAS_PRESENT: Int = 2 + var optionalIntWasPresent_decoded: Boolean? = null + + val TAG_OPTIONAL_INT_VALUE: Int = 3 + var optionalIntValue_decoded: UShort? = null + + val TAG_NULLABLE_OPTIONAL_INT_WAS_PRESENT: Int = 4 + var nullableOptionalIntWasPresent_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_INT_WAS_NULL: Int = 5 + var nullableOptionalIntWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_INT_VALUE: Int = 6 + var nullableOptionalIntValue_decoded: UShort? = null + + val TAG_NULLABLE_STRING_WAS_NULL: Int = 7 + var nullableStringWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_STRING_VALUE: Int = 8 + var nullableStringValue_decoded: String? = null + + val TAG_OPTIONAL_STRING_WAS_PRESENT: Int = 9 + var optionalStringWasPresent_decoded: Boolean? = null + + val TAG_OPTIONAL_STRING_VALUE: Int = 10 + var optionalStringValue_decoded: String? = null + + val TAG_NULLABLE_OPTIONAL_STRING_WAS_PRESENT: Int = 11 + var nullableOptionalStringWasPresent_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_STRING_WAS_NULL: Int = 12 + var nullableOptionalStringWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_STRING_VALUE: Int = 13 + var nullableOptionalStringValue_decoded: String? = null + + val TAG_NULLABLE_STRUCT_WAS_NULL: Int = 14 + var nullableStructWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_STRUCT_VALUE: Int = 15 + var nullableStructValue_decoded: UnitTestingClusterSimpleStruct? = null + + val TAG_OPTIONAL_STRUCT_WAS_PRESENT: Int = 16 + var optionalStructWasPresent_decoded: Boolean? = null + + val TAG_OPTIONAL_STRUCT_VALUE: Int = 17 + var optionalStructValue_decoded: UnitTestingClusterSimpleStruct? = null + + val TAG_NULLABLE_OPTIONAL_STRUCT_WAS_PRESENT: Int = 18 + var nullableOptionalStructWasPresent_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_STRUCT_WAS_NULL: Int = 19 + var nullableOptionalStructWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_STRUCT_VALUE: Int = 20 + var nullableOptionalStructValue_decoded: UnitTestingClusterSimpleStruct? = null + + val TAG_NULLABLE_LIST_WAS_NULL: Int = 21 + var nullableListWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_LIST_VALUE: Int = 22 + var nullableListValue_decoded: List? = null + + val TAG_OPTIONAL_LIST_WAS_PRESENT: Int = 23 + var optionalListWasPresent_decoded: Boolean? = null + + val TAG_OPTIONAL_LIST_VALUE: Int = 24 + var optionalListValue_decoded: List? = null + + val TAG_NULLABLE_OPTIONAL_LIST_WAS_PRESENT: Int = 25 + var nullableOptionalListWasPresent_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_LIST_WAS_NULL: Int = 26 + var nullableOptionalListWasNull_decoded: Boolean? = null + + val TAG_NULLABLE_OPTIONAL_LIST_VALUE: Int = 27 + var nullableOptionalListValue_decoded: List? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_NULLABLE_INT_WAS_NULL)) { + nullableIntWasNull_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_INT_VALUE)) { + nullableIntValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_INT_WAS_PRESENT)) { + optionalIntWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_INT_VALUE)) { + optionalIntValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_INT_WAS_PRESENT)) { + nullableOptionalIntWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_INT_WAS_NULL)) { + nullableOptionalIntWasNull_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getBoolean(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_INT_VALUE)) { + nullableOptionalIntValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_STRING_WAS_NULL)) { + nullableStringWasNull_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_STRING_VALUE)) { + nullableStringValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_STRING_WAS_PRESENT)) { + optionalStringWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_STRING_VALUE)) { + optionalStringValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRING_WAS_PRESENT)) { + nullableOptionalStringWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRING_WAS_NULL)) { + nullableOptionalStringWasNull_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getBoolean(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRING_VALUE)) { + nullableOptionalStringValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_STRUCT_WAS_NULL)) { + nullableStructWasNull_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_STRUCT_VALUE)) { + nullableStructValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + UnitTestingClusterSimpleStruct.fromTlv(tag, tlvReader) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_STRUCT_WAS_PRESENT)) { + optionalStructWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_STRUCT_VALUE)) { + optionalStructValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + UnitTestingClusterSimpleStruct.fromTlv(tag, tlvReader) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRUCT_WAS_PRESENT)) { + nullableOptionalStructWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRUCT_WAS_NULL)) { + nullableOptionalStructWasNull_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getBoolean(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_STRUCT_VALUE)) { + nullableOptionalStructValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + UnitTestingClusterSimpleStruct.fromTlv(tag, tlvReader) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_LIST_WAS_NULL)) { + nullableListWasNull_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_LIST_VALUE)) { + nullableListValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_LIST_WAS_PRESENT)) { + optionalListWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_OPTIONAL_LIST_VALUE)) { + optionalListValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_LIST_WAS_PRESENT)) { + nullableOptionalListWasPresent_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_LIST_WAS_NULL)) { + nullableOptionalListWasNull_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getBoolean(tag) + } else { + null + } + } + } + + if (tag == ContextSpecificTag(TAG_NULLABLE_OPTIONAL_LIST_VALUE)) { + nullableOptionalListValue_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + buildList { + tlvReader.enterArray(tag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + null + } + } + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } + + if (nullableIntWasNull_decoded == null) { + throw IllegalStateException("nullableIntWasNull not found in TLV") + } + + if (optionalIntWasPresent_decoded == null) { + throw IllegalStateException("optionalIntWasPresent not found in TLV") + } + + if (nullableOptionalIntWasPresent_decoded == null) { + throw IllegalStateException("nullableOptionalIntWasPresent not found in TLV") + } + + if (nullableStringWasNull_decoded == null) { + throw IllegalStateException("nullableStringWasNull not found in TLV") + } + + if (optionalStringWasPresent_decoded == null) { + throw IllegalStateException("optionalStringWasPresent not found in TLV") + } + + if (nullableOptionalStringWasPresent_decoded == null) { + throw IllegalStateException("nullableOptionalStringWasPresent not found in TLV") + } + + if (nullableStructWasNull_decoded == null) { + throw IllegalStateException("nullableStructWasNull not found in TLV") + } + + if (optionalStructWasPresent_decoded == null) { + throw IllegalStateException("optionalStructWasPresent not found in TLV") + } + + if (nullableOptionalStructWasPresent_decoded == null) { + throw IllegalStateException("nullableOptionalStructWasPresent not found in TLV") + } + + if (nullableListWasNull_decoded == null) { + throw IllegalStateException("nullableListWasNull not found in TLV") + } + + if (optionalListWasPresent_decoded == null) { + throw IllegalStateException("optionalListWasPresent not found in TLV") + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (nullableOptionalListWasPresent_decoded == null) { + throw IllegalStateException("nullableOptionalListWasPresent not found in TLV") } + + tlvReader.exitContainer() + + return TestComplexNullableOptionalResponse( + nullableIntWasNull_decoded, + nullableIntValue_decoded, + optionalIntWasPresent_decoded, + optionalIntValue_decoded, + nullableOptionalIntWasPresent_decoded, + nullableOptionalIntWasNull_decoded, + nullableOptionalIntValue_decoded, + nullableStringWasNull_decoded, + nullableStringValue_decoded, + optionalStringWasPresent_decoded, + optionalStringValue_decoded, + nullableOptionalStringWasPresent_decoded, + nullableOptionalStringWasNull_decoded, + nullableOptionalStringValue_decoded, + nullableStructWasNull_decoded, + nullableStructValue_decoded, + optionalStructWasPresent_decoded, + optionalStructValue_decoded, + nullableOptionalStructWasPresent_decoded, + nullableOptionalStructWasNull_decoded, + nullableOptionalStructValue_decoded, + nullableListWasNull_decoded, + nullableListValue_decoded, + optionalListWasPresent_decoded, + optionalListValue_decoded, + nullableOptionalListWasPresent_decoded, + nullableOptionalListWasNull_decoded, + nullableOptionalListValue_decoded + ) } suspend fun simpleStructEchoRequest( arg1: UnitTestingClusterSimpleStruct, timedInvokeTimeoutMs: Int? = null ): SimpleStructResponse { - val commandId = 17L + val commandId: UInt = 17u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + arg1.toTlv(ContextSpecificTag(TAG_ARG1_REQ), tlvWriter) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_ARG1: Int = 0 + var arg1_decoded: UnitTestingClusterSimpleStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ARG1)) { + arg1_decoded = UnitTestingClusterSimpleStruct.fromTlv(tag, tlvReader) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (arg1_decoded == null) { + throw IllegalStateException("arg1 not found in TLV") } + + tlvReader.exitContainer() + + return SimpleStructResponse(arg1_decoded) } suspend fun timedInvokeRequest(timedInvokeTimeoutMs: Int) { - val commandId = 18L + val commandId: UInt = 18u + val timeoutMs: Duration = Duration.ofMillis(timedInvokeTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() - // Implementation needs to be added here + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun testSimpleOptionalArgumentRequest(arg1: Boolean?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 19L + val commandId: UInt = 19u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + arg1?.let { tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun testEmitTestEventRequest( arg1: UByte, - arg2: UInt, + arg2: UByte, arg3: Boolean, timedInvokeTimeoutMs: Int? = null ): TestEmitTestEventResponse { - val commandId = 20L + val commandId: UInt = 20u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) + + val TAG_ARG2_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ARG2_REQ), arg2) + + val TAG_ARG3_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_ARG3_REQ), arg3) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: ULong? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getULong(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return TestEmitTestEventResponse(value_decoded) } suspend fun testEmitTestFabricScopedEventRequest( arg1: UByte, timedInvokeTimeoutMs: Int? = null ): TestEmitTestFabricScopedEventResponse { - val commandId = 21L + val commandId: UInt = 21u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARG1_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_ARG1_REQ), arg1) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_VALUE: Int = 0 + var value_decoded: ULong? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_VALUE)) { + value_decoded = tlvReader.getULong(tag) + } else { + // Skip unknown tags + tlvReader.skipElement() + } + } - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs + if (value_decoded == null) { + throw IllegalStateException("value not found in TLV") } + + tlvReader.exitContainer() + + return TestEmitTestFabricScopedEventResponse(value_decoded) } suspend fun readBooleanAttribute(): Boolean { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun writeBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Boolean attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue } - suspend fun subscribeBooleanAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here + suspend fun writeBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBitmap8Attribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun writeBitmap8Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeBitmap8Attribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Bitmap8 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeBitmap8Attribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 1u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBitmap16Attribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeBitmap16Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeBitmap16Attribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Bitmap16 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun writeBitmap16Attribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 2u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBitmap32Attribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun writeBitmap32Attribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeBitmap32Attribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Bitmap32 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun writeBitmap32Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 3u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readBitmap64Attribute(): ULong { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun writeBitmap64Attribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeBitmap64Attribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun readInt8uAttribute(): UByte { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun writeInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeInt8uAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readInt16uAttribute(): UShort { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeInt16uAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Bitmap64 attribute not found in response" } - suspend fun subscribeInt16uAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) - suspend fun readInt24uAttribute(): UInt { - // Implementation needs to be added here + return decodedValue } - suspend fun writeInt24uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeBitmap64Attribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 4u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeInt24uAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + suspend fun readInt8uAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 5u - suspend fun readInt32uAttribute(): UInt { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeInt32uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeInt32uAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readInt40uAttribute(): ULong { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeInt40uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int8u attribute not found in response" } - suspend fun subscribeInt40uAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun readInt48uAttribute(): ULong { - // Implementation needs to be added here + return decodedValue } - suspend fun writeInt48uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeInt48uAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + suspend fun readInt16uAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 6u - suspend fun readInt56uAttribute(): ULong { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeInt56uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeInt56uAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readInt64uAttribute(): ULong { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeInt64uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int16u attribute not found in response" } - suspend fun subscribeInt64uAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun readInt8sAttribute(): Byte { - // Implementation needs to be added here + return decodedValue } - suspend fun writeInt8sAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt16uAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 6u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeInt8sAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here - } + suspend fun readInt24uAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 7u - suspend fun readInt16sAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeInt16sAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeInt16sAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readInt24sAttribute(): Int { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeInt24sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int24u attribute not found in response" } - suspend fun subscribeInt24sAttribute(minInterval: Int, maxInterval: Int): Int { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun readInt32sAttribute(): Int { - // Implementation needs to be added here + return decodedValue } - suspend fun writeInt32sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt24uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 7u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeInt32sAttribute(minInterval: Int, maxInterval: Int): Int { - // Implementation needs to be added here - } + suspend fun readInt32uAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 8u - suspend fun readInt40sAttribute(): Long { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeInt40sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeInt40sAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readInt48sAttribute(): Long { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeInt48sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int32u attribute not found in response" } - suspend fun subscribeInt48sAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun readInt56sAttribute(): Long { - // Implementation needs to be added here + return decodedValue } - suspend fun writeInt56sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt32uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 8u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeInt56sAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + suspend fun readInt40uAttribute(): ULong { + val ATTRIBUTE_ID: UInt = 9u - suspend fun readInt64sAttribute(): Long { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeInt64sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeInt64sAttribute(minInterval: Int, maxInterval: Int): Long { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readEnum8Attribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeEnum8Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int40u attribute not found in response" } - suspend fun subscribeEnum8Attribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) - suspend fun readEnum16Attribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeEnum16Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt40uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 9u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeEnum16Attribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readInt48uAttribute(): ULong { + val ATTRIBUTE_ID: UInt = 10u - suspend fun readFloatSingleAttribute(): Float { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeFloatSingleAttribute(value: Float, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeFloatSingleAttribute(minInterval: Int, maxInterval: Int): Float { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readFloatDoubleAttribute(): Double { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeFloatDoubleAttribute(value: Double, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int48u attribute not found in response" } - suspend fun subscribeFloatDoubleAttribute(minInterval: Int, maxInterval: Int): Double { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) - suspend fun readOctetStringAttribute(): OctetString { - // Implementation needs to be added here + return decodedValue } - suspend fun writeOctetStringAttribute(value: ByteArray, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt48uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 10u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeOctetStringAttribute(minInterval: Int, maxInterval: Int): OctetString { - // Implementation needs to be added here - } + suspend fun readInt56uAttribute(): ULong { + val ATTRIBUTE_ID: UInt = 11u - suspend fun readListInt8uAttribute(): ListInt8uAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeListInt8uAttribute(value: List, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeListInt8uAttribute(minInterval: Int, maxInterval: Int): ListInt8uAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readListOctetStringAttribute(): ListOctetStringAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeListOctetStringAttribute( - value: List, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int56u attribute not found in response" } - suspend fun subscribeListOctetStringAttribute( - minInterval: Int, - maxInterval: Int - ): ListOctetStringAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) - suspend fun readListStructOctetStringAttribute(): ListStructOctetStringAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun writeListStructOctetStringAttribute( - value: List, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt56uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 11u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeListStructOctetStringAttribute( - minInterval: Int, - maxInterval: Int - ): ListStructOctetStringAttribute { - // Implementation needs to be added here - } + suspend fun readInt64uAttribute(): ULong { + val ATTRIBUTE_ID: UInt = 12u - suspend fun readLongOctetStringAttribute(): OctetString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeLongOctetStringAttribute(value: ByteArray, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeLongOctetStringAttribute(minInterval: Int, maxInterval: Int): OctetString { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readCharStringAttribute(): CharString { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeCharStringAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int64u attribute not found in response" } - suspend fun subscribeCharStringAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) - suspend fun readLongCharStringAttribute(): CharString { - // Implementation needs to be added here + return decodedValue } - suspend fun writeLongCharStringAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt64uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 12u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeLongCharStringAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + suspend fun readInt8sAttribute(): Byte { + val ATTRIBUTE_ID: UInt = 13u - suspend fun readEpochUsAttribute(): ULong { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeEpochUsAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeEpochUsAttribute(minInterval: Int, maxInterval: Int): ULong { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readEpochSAttribute(): UInt { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeEpochSAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int8s attribute not found in response" } - suspend fun subscribeEpochSAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte = tlvReader.getByte(AnonymousTag) - suspend fun readVendorIdAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeVendorIdAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt8sAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 13u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeVendorIdAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readInt16sAttribute(): Short { + val ATTRIBUTE_ID: UInt = 14u - suspend fun readListNullablesAndOptionalsStructAttribute(): - ListNullablesAndOptionalsStructAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeListNullablesAndOptionalsStructAttribute( - value: List, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeListNullablesAndOptionalsStructAttribute( - minInterval: Int, - maxInterval: Int - ): ListNullablesAndOptionalsStructAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readEnumAttrAttribute(): UByte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeEnumAttrAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int16s attribute not found in response" } - suspend fun subscribeEnumAttrAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short = tlvReader.getShort(AnonymousTag) - suspend fun readStructAttrAttribute(): StructAttrAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun writeStructAttrAttribute( - value: UnitTestingClusterSimpleStruct, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt16sAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 14u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeStructAttrAttribute( - minInterval: Int, - maxInterval: Int - ): StructAttrAttribute { - // Implementation needs to be added here - } + suspend fun readInt24sAttribute(): Int { + val ATTRIBUTE_ID: UInt = 15u - suspend fun readRangeRestrictedInt8uAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeRangeRestrictedInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeRangeRestrictedInt8uAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readRangeRestrictedInt8sAttribute(): Byte { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeRangeRestrictedInt8sAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int24s attribute not found in response" } - suspend fun subscribeRangeRestrictedInt8sAttribute(minInterval: Int, maxInterval: Int): Byte { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int = tlvReader.getInt(AnonymousTag) - suspend fun readRangeRestrictedInt16uAttribute(): UShort { - // Implementation needs to be added here + return decodedValue } - suspend fun writeRangeRestrictedInt16uAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt24sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 15u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeRangeRestrictedInt16uAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + suspend fun readInt32sAttribute(): Int { + val ATTRIBUTE_ID: UInt = 16u - suspend fun readRangeRestrictedInt16sAttribute(): Short { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeRangeRestrictedInt16sAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeRangeRestrictedInt16sAttribute(minInterval: Int, maxInterval: Int): Short { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readListLongOctetStringAttribute(): ListLongOctetStringAttribute { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Int32s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int = tlvReader.getInt(AnonymousTag) + + return decodedValue } - suspend fun writeListLongOctetStringAttribute( - value: List, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt32sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeListLongOctetStringAttribute( - minInterval: Int, - maxInterval: Int - ): ListLongOctetStringAttribute { - // Implementation needs to be added here - } + suspend fun readInt40sAttribute(): Long { + val ATTRIBUTE_ID: UInt = 17u - suspend fun readListFabricScopedAttribute(): ListFabricScopedAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readListFabricScopedAttributeWithFabricFilter( - isFabricFiltered: Boolean - ): ListFabricScopedAttribute { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeListFabricScopedAttribute( - value: List, - timedWriteTimeoutMs: Int? = null - ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeListFabricScopedAttribute( - minInterval: Int, - maxInterval: Int - ): ListFabricScopedAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readTimedWriteBooleanAttribute(): Boolean { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeTimedWriteBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int) { - // Implementation needs to be added here - } + requireNotNull(attributeData) { "Int40s attribute not found in response" } - suspend fun subscribeTimedWriteBooleanAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun readGeneralErrorBooleanAttribute(): Boolean { - // Implementation needs to be added here + return decodedValue } - suspend fun writeGeneralErrorBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt40sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 17u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeGeneralErrorBooleanAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + suspend fun readInt48sAttribute(): Long { + val ATTRIBUTE_ID: UInt = 18u - suspend fun readClusterErrorBooleanAttribute(): Boolean { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeClusterErrorBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeClusterErrorBooleanAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readUnsupportedAttribute(): Boolean { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeUnsupportedAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int48s attribute not found in response" } - suspend fun subscribeUnsupportedAttribute(minInterval: Int, maxInterval: Int): Boolean { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun writeNullableBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt48sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 18u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableBooleanAttribute( - minInterval: Int, - maxInterval: Int - ): NullableBooleanAttribute { - // Implementation needs to be added here - } + suspend fun readInt56sAttribute(): Long { + val ATTRIBUTE_ID: UInt = 19u - suspend fun readNullableBitmap8Attribute(): NullableBitmap8Attribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableBitmap8Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableBitmap8Attribute( - minInterval: Int, - maxInterval: Int - ): NullableBitmap8Attribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readNullableBitmap16Attribute(): NullableBitmap16Attribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeNullableBitmap16Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int56s attribute not found in response" } - suspend fun subscribeNullableBitmap16Attribute( - minInterval: Int, - maxInterval: Int - ): NullableBitmap16Attribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun readNullableBitmap32Attribute(): NullableBitmap32Attribute { - // Implementation needs to be added here + return decodedValue } - suspend fun writeNullableBitmap32Attribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt56sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 19u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableBitmap32Attribute( - minInterval: Int, - maxInterval: Int - ): NullableBitmap32Attribute { - // Implementation needs to be added here - } + suspend fun readInt64sAttribute(): Long { + val ATTRIBUTE_ID: UInt = 20u - suspend fun readNullableBitmap64Attribute(): NullableBitmap64Attribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableBitmap64Attribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableBitmap64Attribute( - minInterval: Int, - maxInterval: Int - ): NullableBitmap64Attribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readNullableInt8uAttribute(): NullableInt8uAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeNullableInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Int64s attribute not found in response" } - suspend fun subscribeNullableInt8uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt8uAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long = tlvReader.getLong(AnonymousTag) - suspend fun readNullableInt16uAttribute(): NullableInt16uAttribute { - // Implementation needs to be added here + return decodedValue } - suspend fun writeNullableInt16uAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeInt64sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 20u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt16uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt16uAttribute { - // Implementation needs to be added here - } + suspend fun readEnum8Attribute(): UByte { + val ATTRIBUTE_ID: UInt = 21u - suspend fun readNullableInt24uAttribute(): NullableInt24uAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableInt24uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableInt24uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt24uAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enum8 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeEnum8Attribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 21u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun readNullableInt32uAttribute(): NullableInt32uAttribute { - // Implementation needs to be added here - } + suspend fun readEnum16Attribute(): UShort { + val ATTRIBUTE_ID: UInt = 22u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enum16 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun writeEnum16Attribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 22u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readFloatSingleAttribute(): Float { + val ATTRIBUTE_ID: UInt = 23u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Floatsingle attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float = tlvReader.getFloat(AnonymousTag) + + return decodedValue + } + + suspend fun writeFloatSingleAttribute(value: Float, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 23u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readFloatDoubleAttribute(): Double { + val ATTRIBUTE_ID: UInt = 24u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Floatdouble attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Double = tlvReader.getDouble(AnonymousTag) + + return decodedValue + } + + suspend fun writeFloatDoubleAttribute(value: Double, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 24u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readOctetStringAttribute(): ByteArray { + val ATTRIBUTE_ID: UInt = 25u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Octetstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray = tlvReader.getByteArray(AnonymousTag) + + return decodedValue + } + + suspend fun writeOctetStringAttribute(value: ByteArray, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 25u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readListInt8uAttribute(): ListInt8uAttribute { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Listint8u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUByte(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return ListInt8uAttribute(decodedValue) + } + + suspend fun writeListInt8uAttribute(value: List, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 26u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readListOctetStringAttribute(): ListOctetStringAttribute { + val ATTRIBUTE_ID: UInt = 27u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Listoctetstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getByteArray(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return ListOctetStringAttribute(decodedValue) + } + + suspend fun writeListOctetStringAttribute( + value: List, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 27u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readListStructOctetStringAttribute(): ListStructOctetStringAttribute { + val ATTRIBUTE_ID: UInt = 28u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Liststructoctetstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(UnitTestingClusterTestListStructOctet.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return ListStructOctetStringAttribute(decodedValue) + } + + suspend fun writeListStructOctetStringAttribute( + value: List, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 28u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readLongOctetStringAttribute(): ByteArray { + val ATTRIBUTE_ID: UInt = 29u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Longoctetstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray = tlvReader.getByteArray(AnonymousTag) + + return decodedValue + } + + suspend fun writeLongOctetStringAttribute(value: ByteArray, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 29u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readCharStringAttribute(): String { + val ATTRIBUTE_ID: UInt = 30u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Charstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue + } + + suspend fun writeCharStringAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 30u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readLongCharStringAttribute(): String { + val ATTRIBUTE_ID: UInt = 31u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Longcharstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String = tlvReader.getString(AnonymousTag) + + return decodedValue + } + + suspend fun writeLongCharStringAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 31u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readEpochUsAttribute(): ULong { + val ATTRIBUTE_ID: UInt = 32u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Epochus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong = tlvReader.getULong(AnonymousTag) + + return decodedValue + } + + suspend fun writeEpochUsAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 32u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readEpochSAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 33u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Epochs attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun writeEpochSAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 33u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readVendorIdAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 34u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Vendorid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun writeVendorIdAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 34u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readListNullablesAndOptionalsStructAttribute(): + ListNullablesAndOptionalsStructAttribute { + val ATTRIBUTE_ID: UInt = 35u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Listnullablesandoptionalsstruct attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(UnitTestingClusterNullablesAndOptionalsStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return ListNullablesAndOptionalsStructAttribute(decodedValue) + } + + suspend fun writeListNullablesAndOptionalsStructAttribute( + value: List, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 35u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readEnumAttrAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 36u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Enumattr attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeEnumAttrAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 36u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readStructAttrAttribute(): StructAttrAttribute { + val ATTRIBUTE_ID: UInt = 37u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Structattr attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UnitTestingClusterSimpleStruct = + UnitTestingClusterSimpleStruct.fromTlv(AnonymousTag, tlvReader) + + return StructAttrAttribute(decodedValue) + } + + suspend fun writeStructAttrAttribute( + value: UnitTestingClusterSimpleStruct, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 37u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + value.toTlv(AnonymousTag, tlvWriter) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRangeRestrictedInt8uAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 38u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rangerestrictedint8u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeRangeRestrictedInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 38u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRangeRestrictedInt8sAttribute(): Byte { + val ATTRIBUTE_ID: UInt = 39u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rangerestrictedint8s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte = tlvReader.getByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeRangeRestrictedInt8sAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 39u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRangeRestrictedInt16uAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 40u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rangerestrictedint16u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun writeRangeRestrictedInt16uAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 40u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readRangeRestrictedInt16sAttribute(): Short { + val ATTRIBUTE_ID: UInt = 41u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rangerestrictedint16s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short = tlvReader.getShort(AnonymousTag) + + return decodedValue + } + + suspend fun writeRangeRestrictedInt16sAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 41u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readListLongOctetStringAttribute(): ListLongOctetStringAttribute { + val ATTRIBUTE_ID: UInt = 42u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Listlongoctetstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getByteArray(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return ListLongOctetStringAttribute(decodedValue) + } + + suspend fun writeListLongOctetStringAttribute( + value: List, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 42u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readListFabricScopedAttribute(): ListFabricScopedAttribute { + val ATTRIBUTE_ID: UInt = 43u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Listfabricscoped attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(UnitTestingClusterTestFabricScoped.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return ListFabricScopedAttribute(decodedValue) + } + + suspend fun writeListFabricScopedAttribute( + value: List, + timedWriteTimeoutMs: Int? = null + ) { + val ATTRIBUTE_ID: UInt = 43u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readTimedWriteBooleanAttribute(): Boolean { + val ATTRIBUTE_ID: UInt = 48u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Timedwriteboolean attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue + } + + suspend fun writeTimedWriteBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int) { + val ATTRIBUTE_ID: UInt = 48u + val timeoutMs: Duration = Duration.ofMillis(timedWriteTimeoutMs.toLong()) + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readGeneralErrorBooleanAttribute(): Boolean { + val ATTRIBUTE_ID: UInt = 49u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generalerrorboolean attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue + } + + suspend fun writeGeneralErrorBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 49u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readClusterErrorBooleanAttribute(): Boolean { + val ATTRIBUTE_ID: UInt = 50u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clustererrorboolean attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean = tlvReader.getBoolean(AnonymousTag) + + return decodedValue + } + + suspend fun writeClusterErrorBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 50u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readUnsupportedAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 255u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Unsupported attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeUnsupportedAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 255u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { + val ATTRIBUTE_ID: UInt = 16384u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun writeNullableInt32uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableboolean attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (!tlvReader.isNull()) { + tlvReader.getBoolean(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBooleanAttribute(decodedValue) + } + + suspend fun writeNullableBooleanAttribute(value: Boolean, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16384u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt32uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt32uAttribute { - // Implementation needs to be added here + suspend fun readNullableBitmap8Attribute(): NullableBitmap8Attribute { + val ATTRIBUTE_ID: UInt = 16385u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablebitmap8 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap8Attribute(decodedValue) + } + + suspend fun writeNullableBitmap8Attribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16385u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun readNullableInt40uAttribute(): NullableInt40uAttribute { - // Implementation needs to be added here + suspend fun readNullableBitmap16Attribute(): NullableBitmap16Attribute { + val ATTRIBUTE_ID: UInt = 16386u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablebitmap16 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap16Attribute(decodedValue) + } + + suspend fun writeNullableBitmap16Attribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16386u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun writeNullableInt40uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun readNullableBitmap32Attribute(): NullableBitmap32Attribute { + val ATTRIBUTE_ID: UInt = 16387u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablebitmap32 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap32Attribute(decodedValue) + } + + suspend fun writeNullableBitmap32Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16387u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableBitmap64Attribute(): NullableBitmap64Attribute { + val ATTRIBUTE_ID: UInt = 16388u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablebitmap64 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap64Attribute(decodedValue) + } + + suspend fun writeNullableBitmap64Attribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16388u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt8uAttribute(): NullableInt8uAttribute { + val ATTRIBUTE_ID: UInt = 16389u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint8u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt8uAttribute(decodedValue) + } + + suspend fun writeNullableInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16389u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt16uAttribute(): NullableInt16uAttribute { + val ATTRIBUTE_ID: UInt = 16390u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint16u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt16uAttribute(decodedValue) + } + + suspend fun writeNullableInt16uAttribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16390u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt24uAttribute(): NullableInt24uAttribute { + val ATTRIBUTE_ID: UInt = 16391u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint24u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt24uAttribute(decodedValue) + } + + suspend fun writeNullableInt24uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16391u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt32uAttribute(): NullableInt32uAttribute { + val ATTRIBUTE_ID: UInt = 16392u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint32u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt32uAttribute(decodedValue) + } + + suspend fun writeNullableInt32uAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16392u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt40uAttribute(): NullableInt40uAttribute { + val ATTRIBUTE_ID: UInt = 16393u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint40u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt40uAttribute(decodedValue) } - suspend fun subscribeNullableInt40uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt40uAttribute { - // Implementation needs to be added here + suspend fun writeNullableInt40uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16393u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableInt48uAttribute(): NullableInt48uAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16394u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint48u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt48uAttribute(decodedValue) } suspend fun writeNullableInt48uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16394u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt56uAttribute(): NullableInt56uAttribute { + val ATTRIBUTE_ID: UInt = 16395u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint56u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt56uAttribute(decodedValue) + } + + suspend fun writeNullableInt56uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16395u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt64uAttribute(): NullableInt64uAttribute { + val ATTRIBUTE_ID: UInt = 16396u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint64u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt64uAttribute(decodedValue) + } + + suspend fun writeNullableInt64uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16396u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt8sAttribute(): NullableInt8sAttribute { + val ATTRIBUTE_ID: UInt = 16397u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint8s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (!tlvReader.isNull()) { + tlvReader.getByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt8sAttribute(decodedValue) + } + + suspend fun writeNullableInt8sAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16397u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt16sAttribute(): NullableInt16sAttribute { + val ATTRIBUTE_ID: UInt = 16398u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint16s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt16sAttribute(decodedValue) + } + + suspend fun writeNullableInt16sAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16398u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt24sAttribute(): NullableInt24sAttribute { + val ATTRIBUTE_ID: UInt = 16399u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint24s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int? = + if (!tlvReader.isNull()) { + tlvReader.getInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt24sAttribute(decodedValue) + } + + suspend fun writeNullableInt24sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16399u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun readNullableInt32sAttribute(): NullableInt32sAttribute { + val ATTRIBUTE_ID: UInt = 16400u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint32s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Int? = + if (!tlvReader.isNull()) { + tlvReader.getInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableInt32sAttribute(decodedValue) + } + + suspend fun writeNullableInt32sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16400u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt48uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt48uAttribute { - // Implementation needs to be added here - } + suspend fun readNullableInt40sAttribute(): NullableInt40sAttribute { + val ATTRIBUTE_ID: UInt = 16401u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableint40s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (!tlvReader.isNull()) { + tlvReader.getLong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readNullableInt56uAttribute(): NullableInt56uAttribute { - // Implementation needs to be added here + return NullableInt40sAttribute(decodedValue) } - suspend fun writeNullableInt56uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeNullableInt40sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16401u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt56uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt56uAttribute { - // Implementation needs to be added here - } + suspend fun readNullableInt48sAttribute(): NullableInt48sAttribute { + val ATTRIBUTE_ID: UInt = 16402u - suspend fun readNullableInt64uAttribute(): NullableInt64uAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableInt64uAttribute(value: ULong, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableInt64uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt64uAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readNullableInt8sAttribute(): NullableInt8sAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeNullableInt8sAttribute(value: Byte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Nullableint48s attribute not found in response" } - suspend fun subscribeNullableInt8sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt8sAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (!tlvReader.isNull()) { + tlvReader.getLong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readNullableInt16sAttribute(): NullableInt16sAttribute { - // Implementation needs to be added here + return NullableInt48sAttribute(decodedValue) } - suspend fun writeNullableInt16sAttribute(value: Short, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeNullableInt48sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16402u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt16sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt16sAttribute { - // Implementation needs to be added here - } + suspend fun readNullableInt56sAttribute(): NullableInt56sAttribute { + val ATTRIBUTE_ID: UInt = 16403u - suspend fun readNullableInt24sAttribute(): NullableInt24sAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableInt24sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableInt24sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt24sAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readNullableInt32sAttribute(): NullableInt32sAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeNullableInt32sAttribute(value: Int, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Nullableint56s attribute not found in response" } - suspend fun subscribeNullableInt32sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt32sAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (!tlvReader.isNull()) { + tlvReader.getLong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readNullableInt40sAttribute(): NullableInt40sAttribute { - // Implementation needs to be added here + return NullableInt56sAttribute(decodedValue) } - suspend fun writeNullableInt40sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + suspend fun writeNullableInt56sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16403u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt40sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt40sAttribute { - // Implementation needs to be added here - } + suspend fun readNullableInt64sAttribute(): NullableInt64sAttribute { + val ATTRIBUTE_ID: UInt = 16404u - suspend fun readNullableInt48sAttribute(): NullableInt48sAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableInt48sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableInt48sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt48sAttribute { - // Implementation needs to be added here - } + logger.log(Level.FINE, "Read command succeeded") - suspend fun readNullableInt56sAttribute(): NullableInt56sAttribute { - // Implementation needs to be added here - } + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun writeNullableInt56sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs - } - } + requireNotNull(attributeData) { "Nullableint64s attribute not found in response" } - suspend fun subscribeNullableInt56sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt56sAttribute { - // Implementation needs to be added here - } + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Long? = + if (!tlvReader.isNull()) { + tlvReader.getLong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun readNullableInt64sAttribute(): NullableInt64sAttribute { - // Implementation needs to be added here + return NullableInt64sAttribute(decodedValue) } suspend fun writeNullableInt64sAttribute(value: Long, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16404u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableInt64sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableInt64sAttribute { - // Implementation needs to be added here - } - suspend fun readNullableEnum8Attribute(): NullableEnum8Attribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16405u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableEnum8Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableEnum8Attribute( - minInterval: Int, - maxInterval: Int - ): NullableEnum8Attribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableenum8 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableEnum8Attribute(decodedValue) + } + + suspend fun writeNullableEnum8Attribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16405u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableEnum16Attribute(): NullableEnum16Attribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16406u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun writeNullableEnum16Attribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableEnum16Attribute( - minInterval: Int, - maxInterval: Int - ): NullableEnum16Attribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableenum16 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableEnum16Attribute(decodedValue) + } + + suspend fun writeNullableEnum16Attribute(value: UShort, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16406u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableFloatSingleAttribute(): NullableFloatSingleAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16407u - suspend fun writeNullableFloatSingleAttribute(value: Float, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablefloatsingle attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Float? = + if (!tlvReader.isNull()) { + tlvReader.getFloat(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableFloatSingleAttribute(decodedValue) } - suspend fun subscribeNullableFloatSingleAttribute( - minInterval: Int, - maxInterval: Int - ): NullableFloatSingleAttribute { - // Implementation needs to be added here + suspend fun writeNullableFloatSingleAttribute(value: Float, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16407u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableFloatDoubleAttribute(): NullableFloatDoubleAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16408u - suspend fun writeNullableFloatDoubleAttribute(value: Double, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablefloatdouble attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Double? = + if (!tlvReader.isNull()) { + tlvReader.getDouble(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableFloatDoubleAttribute(decodedValue) } - suspend fun subscribeNullableFloatDoubleAttribute( - minInterval: Int, - maxInterval: Int - ): NullableFloatDoubleAttribute { - // Implementation needs to be added here + suspend fun writeNullableFloatDoubleAttribute(value: Double, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16408u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableOctetStringAttribute(): NullableOctetStringAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16409u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableoctetstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableOctetStringAttribute(decodedValue) } suspend fun writeNullableOctetStringAttribute( value: ByteArray, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16409u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableOctetStringAttribute( - minInterval: Int, - maxInterval: Int - ): NullableOctetStringAttribute { - // Implementation needs to be added here - } - suspend fun readNullableCharStringAttribute(): NullableCharStringAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16414u - suspend fun writeNullableCharStringAttribute(value: String, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablecharstring attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (!tlvReader.isNull()) { + tlvReader.getString(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableCharStringAttribute(decodedValue) } - suspend fun subscribeNullableCharStringAttribute( - minInterval: Int, - maxInterval: Int - ): NullableCharStringAttribute { - // Implementation needs to be added here + suspend fun writeNullableCharStringAttribute(value: String, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16414u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableEnumAttrAttribute(): NullableEnumAttrAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 16420u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeNullableEnumAttrAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeNullableEnumAttrAttribute( - minInterval: Int, - maxInterval: Int - ): NullableEnumAttrAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullableenumattr attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableEnumAttrAttribute(decodedValue) + } + + suspend fun writeNullableEnumAttrAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16420u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readNullableStructAttribute(): NullableStructAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16421u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablestruct attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UnitTestingClusterSimpleStruct? = + if (!tlvReader.isNull()) { + UnitTestingClusterSimpleStruct.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableStructAttribute(decodedValue) } suspend fun writeNullableStructAttribute( value: UnitTestingClusterSimpleStruct, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16421u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + value.toTlv(AnonymousTag, tlvWriter) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableStructAttribute( - minInterval: Int, - maxInterval: Int - ): NullableStructAttribute { - // Implementation needs to be added here - } - suspend fun readNullableRangeRestrictedInt8uAttribute(): NullableRangeRestrictedInt8uAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16422u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablerangerestrictedint8u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableRangeRestrictedInt8uAttribute(decodedValue) } suspend fun writeNullableRangeRestrictedInt8uAttribute( value: UByte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16422u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableRangeRestrictedInt8uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableRangeRestrictedInt8uAttribute { - // Implementation needs to be added here - } - suspend fun readNullableRangeRestrictedInt8sAttribute(): NullableRangeRestrictedInt8sAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16423u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Nullablerangerestrictedint8s attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (!tlvReader.isNull()) { + tlvReader.getByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableRangeRestrictedInt8sAttribute(decodedValue) } suspend fun writeNullableRangeRestrictedInt8sAttribute( value: Byte, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16423u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableRangeRestrictedInt8sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableRangeRestrictedInt8sAttribute { - // Implementation needs to be added here - } - suspend fun readNullableRangeRestrictedInt16uAttribute(): NullableRangeRestrictedInt16uAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16424u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Nullablerangerestrictedint16u attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableRangeRestrictedInt16uAttribute(decodedValue) } suspend fun writeNullableRangeRestrictedInt16uAttribute( value: UShort, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16424u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableRangeRestrictedInt16uAttribute( - minInterval: Int, - maxInterval: Int - ): NullableRangeRestrictedInt16uAttribute { - // Implementation needs to be added here - } - suspend fun readNullableRangeRestrictedInt16sAttribute(): NullableRangeRestrictedInt16sAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 16425u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Nullablerangerestrictedint16s attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Short? = + if (!tlvReader.isNull()) { + tlvReader.getShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableRangeRestrictedInt16sAttribute(decodedValue) } suspend fun writeNullableRangeRestrictedInt16sAttribute( value: Short, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 16425u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeNullableRangeRestrictedInt16sAttribute( - minInterval: Int, - maxInterval: Int - ): NullableRangeRestrictedInt16sAttribute { - // Implementation needs to be added here - } + suspend fun readWriteOnlyInt8uAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 16426u - suspend fun readWriteOnlyInt8uAttribute(): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun writeWriteOnlyInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Writeonlyint8u attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeWriteOnlyInt8uAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun writeWriteOnlyInt8uAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 16426u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(UnitTestingCluster::class.java.name) const val CLUSTER_ID: UInt = 4294048773u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UserLabelCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UserLabelCluster.kt index 4b986531f5b412..8d633a8f327d43 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UserLabelCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/UserLabelCluster.kt @@ -17,8 +17,15 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class UserLabelCluster(private val controller: MatterController, private val endpointId: UShort) { class LabelListAttribute(val value: List) @@ -32,82 +39,308 @@ class UserLabelCluster(private val controller: MatterController, private val end class AttributeListAttribute(val value: List) suspend fun readLabelListAttribute(): LabelListAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Labellist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(UserLabelClusterLabelStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return LabelListAttribute(decodedValue) } suspend fun writeLabelListAttribute( value: List, timedWriteTimeoutMs: Int? = null ) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.startArray(AnonymousTag) + for (item in value.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) } - } + tlvWriter.endArray() + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } - suspend fun subscribeLabelListAttribute(minInterval: Int, maxInterval: Int): LabelListAttribute { - // Implementation needs to be added here + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(UserLabelCluster::class.java.name) const val CLUSTER_ID: UInt = 65u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ValveConfigurationAndControlCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ValveConfigurationAndControlCluster.kt index bdcc7781467968..e4f6af0b20c0f2 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ValveConfigurationAndControlCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ValveConfigurationAndControlCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class ValveConfigurationAndControlCluster( private val controller: MatterController, @@ -30,9 +39,9 @@ class ValveConfigurationAndControlCluster( class RemainingDurationAttribute(val value: UInt?) - class CurrentStateAttribute(val value: UInt?) + class CurrentStateAttribute(val value: UByte?) - class TargetStateAttribute(val value: UInt?) + class TargetStateAttribute(val value: UByte?) class CurrentLevelAttribute(val value: UByte?) @@ -49,218 +58,804 @@ class ValveConfigurationAndControlCluster( class AttributeListAttribute(val value: List) suspend fun open(openDuration: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_OPEN_DURATION_REQ: Int = 0 + openDuration?.let { tlvWriter.put(ContextSpecificTag(TAG_OPEN_DURATION_REQ), openDuration) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun close(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun setLevel(level: UByte, openDuration: UInt?, timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LEVEL_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LEVEL_REQ), level) + + val TAG_OPEN_DURATION_REQ: Int = 1 + openDuration?.let { tlvWriter.put(ContextSpecificTag(TAG_OPEN_DURATION_REQ), openDuration) } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readOpenDurationAttribute(): OpenDurationAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun writeOpenDurationAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Openduration attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OpenDurationAttribute(decodedValue) } - suspend fun subscribeOpenDurationAttribute( - minInterval: Int, - maxInterval: Int - ): OpenDurationAttribute { - // Implementation needs to be added here + suspend fun writeOpenDurationAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 0u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readAutoCloseTimeAttribute(): AutoCloseTimeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Autoclosetime attribute not found in response" } - suspend fun subscribeAutoCloseTimeAttribute( - minInterval: Int, - maxInterval: Int - ): AutoCloseTimeAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return AutoCloseTimeAttribute(decodedValue) } suspend fun readRemainingDurationAttribute(): RemainingDurationAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Remainingduration attribute not found in response" } - suspend fun subscribeRemainingDurationAttribute( - minInterval: Int, - maxInterval: Int - ): RemainingDurationAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return RemainingDurationAttribute(decodedValue) } suspend fun readCurrentStateAttribute(): CurrentStateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeCurrentStateAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentStateAttribute { - // Implementation needs to be added here + return CurrentStateAttribute(decodedValue) } suspend fun readTargetStateAttribute(): TargetStateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun subscribeTargetStateAttribute( - minInterval: Int, - maxInterval: Int - ): TargetStateAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readStartUpStateAttribute(): UByte { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeStartUpStateAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Targetstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return TargetStateAttribute(decodedValue) } - suspend fun subscribeStartUpStateAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + suspend fun readStartUpStateAttribute(): UByte? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupstate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun writeStartUpStateAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 5u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } suspend fun readCurrentLevelAttribute(): CurrentLevelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCurrentLevelAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentLevelAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentLevelAttribute(decodedValue) } suspend fun readTargetLevelAttribute(): TargetLevelAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTargetLevelAttribute( - minInterval: Int, - maxInterval: Int - ): TargetLevelAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Targetlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return TargetLevelAttribute(decodedValue) } suspend fun readOpenLevelAttribute(): OpenLevelAttribute { - // Implementation needs to be added here + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Openlevel attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OpenLevelAttribute(decodedValue) } suspend fun writeOpenLevelAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val ATTRIBUTE_ID: UInt = 8u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } } } - suspend fun subscribeOpenLevelAttribute(minInterval: Int, maxInterval: Int): OpenLevelAttribute { - // Implementation needs to be added here - } + suspend fun readValveFaultAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 9u - suspend fun readValveFaultAttribute(): UShort { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeValveFaultAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Valvefault attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(ValveConfigurationAndControlCluster::class.java.name) const val CLUSTER_ID: UInt = 129u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WakeOnLanCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WakeOnLanCluster.kt index b879ef647988c4..eb8631b26c204a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WakeOnLanCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WakeOnLanCluster.kt @@ -17,8 +17,13 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader class WakeOnLanCluster(private val controller: MatterController, private val endpointId: UShort) { class GeneratedCommandListAttribute(val value: List) @@ -29,80 +34,294 @@ class WakeOnLanCluster(private val controller: MatterController, private val end class AttributeListAttribute(val value: List) - suspend fun readMACAddressAttribute(): CharString { - // Implementation needs to be added here - } + suspend fun readMACAddressAttribute(): String? { + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeMACAddressAttribute(minInterval: Int, maxInterval: Int): CharString { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Macaddress attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: String? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getString(AnonymousTag) + } else { + null + } - suspend fun readLinkLocalAddressAttribute(): OctetString { - // Implementation needs to be added here + return decodedValue } - suspend fun subscribeLinkLocalAddressAttribute(minInterval: Int, maxInterval: Int): OctetString { - // Implementation needs to be added here + suspend fun readLinkLocalAddressAttribute(): ByteArray? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Linklocaladdress attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getByteArray(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(WakeOnLanCluster::class.java.name) const val CLUSTER_ID: UInt = 1283u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt index 3bae4cf3db3210..0b5be89ac5d13f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt @@ -17,8 +17,16 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class WiFiNetworkDiagnosticsCluster( private val controller: MatterController, @@ -26,9 +34,9 @@ class WiFiNetworkDiagnosticsCluster( ) { class BssidAttribute(val value: ByteArray?) - class SecurityTypeAttribute(val value: UInt?) + class SecurityTypeAttribute(val value: UByte?) - class WiFiVersionAttribute(val value: UInt?) + class WiFiVersionAttribute(val value: UByte?) class ChannelNumberAttribute(val value: UShort?) @@ -59,210 +67,754 @@ class WiFiNetworkDiagnosticsCluster( class AttributeListAttribute(val value: List) suspend fun resetCounts(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readBssidAttribute(): BssidAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Bssid attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ByteArray? = + if (!tlvReader.isNull()) { + tlvReader.getByteArray(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeBssidAttribute(minInterval: Int, maxInterval: Int): BssidAttribute { - // Implementation needs to be added here + return BssidAttribute(decodedValue) } suspend fun readSecurityTypeAttribute(): SecurityTypeAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeSecurityTypeAttribute( - minInterval: Int, - maxInterval: Int - ): SecurityTypeAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Securitytype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SecurityTypeAttribute(decodedValue) } suspend fun readWiFiVersionAttribute(): WiFiVersionAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeWiFiVersionAttribute( - minInterval: Int, - maxInterval: Int - ): WiFiVersionAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Wifiversion attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return WiFiVersionAttribute(decodedValue) } suspend fun readChannelNumberAttribute(): ChannelNumberAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeChannelNumberAttribute( - minInterval: Int, - maxInterval: Int - ): ChannelNumberAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Channelnumber attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ChannelNumberAttribute(decodedValue) } suspend fun readRssiAttribute(): RssiAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeRssiAttribute(minInterval: Int, maxInterval: Int): RssiAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Rssi attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Byte? = + if (!tlvReader.isNull()) { + tlvReader.getByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return RssiAttribute(decodedValue) } suspend fun readBeaconLostCountAttribute(): BeaconLostCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeBeaconLostCountAttribute( - minInterval: Int, - maxInterval: Int - ): BeaconLostCountAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Beaconlostcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return BeaconLostCountAttribute(decodedValue) } suspend fun readBeaconRxCountAttribute(): BeaconRxCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Beaconrxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeBeaconRxCountAttribute( - minInterval: Int, - maxInterval: Int - ): BeaconRxCountAttribute { - // Implementation needs to be added here + return BeaconRxCountAttribute(decodedValue) } suspend fun readPacketMulticastRxCountAttribute(): PacketMulticastRxCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePacketMulticastRxCountAttribute( - minInterval: Int, - maxInterval: Int - ): PacketMulticastRxCountAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Packetmulticastrxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PacketMulticastRxCountAttribute(decodedValue) } suspend fun readPacketMulticastTxCountAttribute(): PacketMulticastTxCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribePacketMulticastTxCountAttribute( - minInterval: Int, - maxInterval: Int - ): PacketMulticastTxCountAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Packetmulticasttxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PacketMulticastTxCountAttribute(decodedValue) } suspend fun readPacketUnicastRxCountAttribute(): PacketUnicastRxCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribePacketUnicastRxCountAttribute( - minInterval: Int, - maxInterval: Int - ): PacketUnicastRxCountAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Packetunicastrxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PacketUnicastRxCountAttribute(decodedValue) } suspend fun readPacketUnicastTxCountAttribute(): PacketUnicastTxCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribePacketUnicastTxCountAttribute( - minInterval: Int, - maxInterval: Int - ): PacketUnicastTxCountAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Packetunicasttxcount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PacketUnicastTxCountAttribute(decodedValue) } suspend fun readCurrentMaxRateAttribute(): CurrentMaxRateAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeCurrentMaxRateAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentMaxRateAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { "Currentmaxrate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentMaxRateAttribute(decodedValue) } suspend fun readOverrunCountAttribute(): OverrunCountAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Overruncount attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeOverrunCountAttribute( - minInterval: Int, - maxInterval: Int - ): OverrunCountAttribute { - // Implementation needs to be added here + return OverrunCountAttribute(decodedValue) } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(WiFiNetworkDiagnosticsCluster::class.java.name) const val CLUSTER_ID: UInt = 54u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WindowCoveringCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WindowCoveringCluster.kt index 644a365b3c2440..c7c7b621e07b7c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WindowCoveringCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/WindowCoveringCluster.kt @@ -17,8 +17,17 @@ package matter.devicecontroller.cluster.clusters -import matter.controller.MatterController +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import matter.controller.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath import matter.devicecontroller.cluster.structs.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter class WindowCoveringCluster( private val controller: MatterController, @@ -49,363 +58,1244 @@ class WindowCoveringCluster( class AttributeListAttribute(val value: List) suspend fun upOrOpen(timedInvokeTimeoutMs: Int? = null) { - val commandId = 0L + val commandId: UInt = 0u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun downOrClose(timedInvokeTimeoutMs: Int? = null) { - val commandId = 1L + val commandId: UInt = 1u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun stopMotion(timedInvokeTimeoutMs: Int? = null) { - val commandId = 2L + val commandId: UInt = 2u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun goToLiftValue(liftValue: UShort, timedInvokeTimeoutMs: Int? = null) { - val commandId = 4L + val commandId: UInt = 4u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LIFT_VALUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LIFT_VALUE_REQ), liftValue) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun goToLiftPercentage( liftPercent100thsValue: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 5L + val commandId: UInt = 5u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_LIFT_PERCENT100THS_VALUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_LIFT_PERCENT100THS_VALUE_REQ), liftPercent100thsValue) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun goToTiltValue(tiltValue: UShort, timedInvokeTimeoutMs: Int? = null) { - val commandId = 7L + val commandId: UInt = 7u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TILT_VALUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TILT_VALUE_REQ), tiltValue) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun goToTiltPercentage( tiltPercent100thsValue: UShort, timedInvokeTimeoutMs: Int? = null ) { - val commandId = 8L + val commandId: UInt = 8u + val timeoutMs: Duration = + timedInvokeTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO - if (timedInvokeTimeoutMs != null) { - // Do the action with timedInvokeTimeoutMs - } else { - // Do the action without timedInvokeTimeoutMs - } + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_TILT_PERCENT100THS_VALUE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_TILT_PERCENT100THS_VALUE_REQ), tiltPercent100thsValue) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timeoutMs + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") } suspend fun readTypeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 0u - suspend fun subscribeTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readPhysicalClosedLimitLiftAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribePhysicalClosedLimitLiftAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Type attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } - suspend fun readPhysicalClosedLimitTiltAttribute(): UShort { - // Implementation needs to be added here + suspend fun readPhysicalClosedLimitLiftAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Physicalclosedlimitlift attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribePhysicalClosedLimitTiltAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readPhysicalClosedLimitTiltAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Physicalclosedlimittilt attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readCurrentPositionLiftAttribute(): CurrentPositionLiftAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCurrentPositionLiftAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPositionLiftAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentpositionlift attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPositionLiftAttribute(decodedValue) } suspend fun readCurrentPositionTiltAttribute(): CurrentPositionTiltAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 4u - suspend fun subscribeCurrentPositionTiltAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPositionTiltAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readNumberOfActuationsLiftAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeNumberOfActuationsLiftAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentpositiontilt attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPositionTiltAttribute(decodedValue) } - suspend fun readNumberOfActuationsTiltAttribute(): UShort { - // Implementation needs to be added here + suspend fun readNumberOfActuationsLiftAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofactuationslift attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeNumberOfActuationsTiltAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readNumberOfActuationsTiltAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 6u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Numberofactuationstilt attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readConfigStatusAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 7u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeConfigStatusAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Configstatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readCurrentPositionLiftPercentageAttribute(): CurrentPositionLiftPercentageAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 8u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Currentpositionliftpercentage attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } - suspend fun subscribeCurrentPositionLiftPercentageAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPositionLiftPercentageAttribute { - // Implementation needs to be added here + return CurrentPositionLiftPercentageAttribute(decodedValue) } suspend fun readCurrentPositionTiltPercentageAttribute(): CurrentPositionTiltPercentageAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 9u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Currentpositiontiltpercentage attribute not found in response" + } - suspend fun subscribeCurrentPositionTiltPercentageAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPositionTiltPercentageAttribute { - // Implementation needs to be added here + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPositionTiltPercentageAttribute(decodedValue) } suspend fun readOperationalStatusAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 10u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeOperationalStatusAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + requireNotNull(attributeData) { "Operationalstatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue } suspend fun readTargetPositionLiftPercent100thsAttribute(): TargetPositionLiftPercent100thsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 11u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } - suspend fun subscribeTargetPositionLiftPercent100thsAttribute( - minInterval: Int, - maxInterval: Int - ): TargetPositionLiftPercent100thsAttribute { - // Implementation needs to be added here + requireNotNull(attributeData) { + "Targetpositionliftpercent100ths attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return TargetPositionLiftPercent100thsAttribute(decodedValue) } suspend fun readTargetPositionTiltPercent100thsAttribute(): TargetPositionTiltPercent100thsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 12u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } - suspend fun subscribeTargetPositionTiltPercent100thsAttribute( - minInterval: Int, - maxInterval: Int - ): TargetPositionTiltPercent100thsAttribute { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Targetpositiontiltpercent100ths attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return TargetPositionTiltPercent100thsAttribute(decodedValue) } suspend fun readEndProductTypeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 13u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Endproducttype attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - suspend fun subscribeEndProductTypeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + return decodedValue } suspend fun readCurrentPositionLiftPercent100thsAttribute(): CurrentPositionLiftPercent100thsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 14u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeCurrentPositionLiftPercent100thsAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPositionLiftPercent100thsAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Currentpositionliftpercent100ths attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPositionLiftPercent100thsAttribute(decodedValue) } suspend fun readCurrentPositionTiltPercent100thsAttribute(): CurrentPositionTiltPercent100thsAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 15u - suspend fun subscribeCurrentPositionTiltPercent100thsAttribute( - minInterval: Int, - maxInterval: Int - ): CurrentPositionTiltPercent100thsAttribute { - // Implementation needs to be added here - } + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun readInstalledOpenLimitLiftAttribute(): UShort { - // Implementation needs to be added here - } + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeInstalledOpenLimitLiftAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here - } + val response = controller.read(readRequest) - suspend fun readInstalledClosedLimitLiftAttribute(): UShort { - // Implementation needs to be added here - } + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") - suspend fun subscribeInstalledClosedLimitLiftAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { + "Currentpositiontiltpercent100ths attribute not found in response" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentPositionTiltPercent100thsAttribute(decodedValue) } - suspend fun readInstalledOpenLimitTiltAttribute(): UShort { - // Implementation needs to be added here + suspend fun readInstalledOpenLimitLiftAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 16u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Installedopenlimitlift attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeInstalledOpenLimitTiltAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + suspend fun readInstalledClosedLimitLiftAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 17u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Installedclosedlimitlift attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun readInstalledClosedLimitTiltAttribute(): UShort { - // Implementation needs to be added here + suspend fun readInstalledOpenLimitTiltAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 18u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Installedopenlimittilt attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } - suspend fun subscribeInstalledClosedLimitTiltAttribute( - minInterval: Int, - maxInterval: Int - ): UShort { - // Implementation needs to be added here + suspend fun readInstalledClosedLimitTiltAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 19u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Installedclosedlimittilt attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readModeAttribute(): UByte { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 23u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun writeModeAttribute(value: UInt, timedWriteTimeoutMs: Int? = null) { - if (timedWriteTimeoutMs != null) { - // Do the action with timedWriteTimeoutMs - } else { - // Do the action without timedWriteTimeoutMs + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") } - } - suspend fun subscribeModeAttribute(minInterval: Int, maxInterval: Int): UByte { - // Implementation needs to be added here + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Mode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun writeModeAttribute(value: UByte, timedWriteTimeoutMs: Int? = null) { + val ATTRIBUTE_ID: UInt = 23u + val timeoutMs: Duration = + timedWriteTimeoutMs?.let { Duration.ofMillis(it.toLong()) } ?: Duration.ZERO + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded() + ) + ), + timedRequest = timeoutMs + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } } - suspend fun readSafetyStatusAttribute(): UShort { - // Implementation needs to be added here - } + suspend fun readSafetyStatusAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 26u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) - suspend fun subscribeSafetyStatusAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Safetystatus attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUShort(AnonymousTag) + } else { + null + } + + return decodedValue } suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeGeneratedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): GeneratedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) } suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - suspend fun subscribeAcceptedCommandListAttribute( - minInterval: Int, - maxInterval: Int - ): AcceptedCommandListAttribute { - // Implementation needs to be added here + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) } suspend fun readEventListAttribute(): EventListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) } suspend fun readAttributeListAttribute(): AttributeListAttribute { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - suspend fun subscribeAttributeListAttribute( - minInterval: Int, - maxInterval: Int - ): AttributeListAttribute { - // Implementation needs to be added here + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) } suspend fun readFeatureMapAttribute(): UInt { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65532u - suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue } suspend fun readClusterRevisionAttribute(): UShort { - // Implementation needs to be added here - } + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) - suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { - // Implementation needs to be added here + return decodedValue } companion object { + private val logger = Logger.getLogger(WindowCoveringCluster::class.java.name) const val CLUSTER_ID: UInt = 258u } } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt index 50ec0a54a8ec73..ae83ff0c00f101 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class AccessControlClusterAccessControlEntryChangedEvent( val adminNodeID: ULong?, val adminPasscodeID: UShort?, - val changeType: UInt, + val changeType: UByte, val latestValue: matter.devicecontroller.cluster.structs.AccessControlClusterAccessControlEntryStruct?, val fabricIndex: UByte @@ -90,7 +90,7 @@ class AccessControlClusterAccessControlEntryChangedEvent( tlvReader.getNull(ContextSpecificTag(TAG_ADMIN_PASSCODE_I_D)) null } - val changeType = tlvReader.getUInt(ContextSpecificTag(TAG_CHANGE_TYPE)) + val changeType = tlvReader.getUByte(ContextSpecificTag(TAG_CHANGE_TYPE)) val latestValue = if (!tlvReader.isNull()) { matter.devicecontroller.cluster.structs.AccessControlClusterAccessControlEntryStruct diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt index c6721f29f88959..1a7a6ad43ad966 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class AccessControlClusterAccessControlExtensionChangedEvent( val adminNodeID: ULong?, val adminPasscodeID: UShort?, - val changeType: UInt, + val changeType: UByte, val latestValue: matter.devicecontroller.cluster.structs.AccessControlClusterAccessControlExtensionStruct?, val fabricIndex: UByte @@ -90,7 +90,7 @@ class AccessControlClusterAccessControlExtensionChangedEvent( tlvReader.getNull(ContextSpecificTag(TAG_ADMIN_PASSCODE_I_D)) null } - val changeType = tlvReader.getUInt(ContextSpecificTag(TAG_CHANGE_TYPE)) + val changeType = tlvReader.getUByte(ContextSpecificTag(TAG_CHANGE_TYPE)) val latestValue = if (!tlvReader.isNull()) { matter.devicecontroller.cluster.structs.AccessControlClusterAccessControlExtensionStruct diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt index 7def1a047e9a3a..0c9b1d4e9c2466 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt @@ -25,8 +25,8 @@ import matter.tlv.TlvWriter class ActionsClusterActionFailedEvent( val actionID: UShort, val invokeID: UInt, - val newState: UInt, - val error: UInt + val newState: UByte, + val error: UByte ) { override fun toString(): String = buildString { append("ActionsClusterActionFailedEvent {\n") @@ -58,8 +58,8 @@ class ActionsClusterActionFailedEvent( tlvReader.enterStructure(tlvTag) val actionID = tlvReader.getUShort(ContextSpecificTag(TAG_ACTION_I_D)) val invokeID = tlvReader.getUInt(ContextSpecificTag(TAG_INVOKE_I_D)) - val newState = tlvReader.getUInt(ContextSpecificTag(TAG_NEW_STATE)) - val error = tlvReader.getUInt(ContextSpecificTag(TAG_ERROR)) + val newState = tlvReader.getUByte(ContextSpecificTag(TAG_NEW_STATE)) + val error = tlvReader.getUByte(ContextSpecificTag(TAG_ERROR)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterStateChangedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterStateChangedEvent.kt index 81ed599b956c26..48f10a0c82a017 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterStateChangedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ActionsClusterStateChangedEvent.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class ActionsClusterStateChangedEvent( val actionID: UShort, val invokeID: UInt, - val newState: UInt + val newState: UByte ) { override fun toString(): String = buildString { append("ActionsClusterStateChangedEvent {\n") @@ -54,7 +54,7 @@ class ActionsClusterStateChangedEvent( tlvReader.enterStructure(tlvTag) val actionID = tlvReader.getUShort(ContextSpecificTag(TAG_ACTION_I_D)) val invokeID = tlvReader.getUInt(ContextSpecificTag(TAG_INVOKE_I_D)) - val newState = tlvReader.getUInt(ContextSpecificTag(TAG_NEW_STATE)) + val newState = tlvReader.getUByte(ContextSpecificTag(TAG_NEW_STATE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/BooleanSensorConfigurationClusterAlarmsStateChangedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/BooleanSensorConfigurationClusterAlarmsStateChangedEvent.kt index bf64761f255688..f5e2a6707832e7 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/BooleanSensorConfigurationClusterAlarmsStateChangedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/BooleanSensorConfigurationClusterAlarmsStateChangedEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class BooleanSensorConfigurationClusterAlarmsStateChangedEvent( - val alarmsActive: UInt, - val alarmsSuppressed: Optional + val alarmsActive: UByte, + val alarmsSuppressed: Optional ) { override fun toString(): String = buildString { append("BooleanSensorConfigurationClusterAlarmsStateChangedEvent {\n") @@ -55,10 +55,10 @@ class BooleanSensorConfigurationClusterAlarmsStateChangedEvent( tlvReader: TlvReader ): BooleanSensorConfigurationClusterAlarmsStateChangedEvent { tlvReader.enterStructure(tlvTag) - val alarmsActive = tlvReader.getUInt(ContextSpecificTag(TAG_ALARMS_ACTIVE)) + val alarmsActive = tlvReader.getUByte(ContextSpecificTag(TAG_ALARMS_ACTIVE)) val alarmsSuppressed = if (tlvReader.isNextTag(ContextSpecificTag(TAG_ALARMS_SUPPRESSED))) { - Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_ALARMS_SUPPRESSED))) + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_ALARMS_SUPPRESSED))) } else { Optional.empty() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt index 92b680ff01eb05..5ed08f5c60d89a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent.kt @@ -26,9 +26,9 @@ import matter.tlv.TlvWriter class DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent( val eventID: ByteArray, val transitionIndex: UByte?, - val status: UInt, - val criticality: UInt, - val control: UInt, + val status: UByte, + val criticality: UByte, + val control: UShort, val temperatureControl: Optional< matter.devicecontroller.cluster.structs.DemandResponseLoadControlClusterTemperatureControlStruct @@ -146,9 +146,9 @@ class DemandResponseLoadControlClusterLoadControlEventStatusChangeEvent( tlvReader.getNull(ContextSpecificTag(TAG_TRANSITION_INDEX)) null } - val status = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS)) - val criticality = tlvReader.getUInt(ContextSpecificTag(TAG_CRITICALITY)) - val control = tlvReader.getUInt(ContextSpecificTag(TAG_CONTROL)) + val status = tlvReader.getUByte(ContextSpecificTag(TAG_STATUS)) + val criticality = tlvReader.getUByte(ContextSpecificTag(TAG_CRITICALITY)) + val control = tlvReader.getUShort(ContextSpecificTag(TAG_CONTROL)) val temperatureControl = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(ContextSpecificTag(TAG_TEMPERATURE_CONTROL))) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt index dd7ac4d986fd58..62c61f40848056 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DeviceEnergyManagementClusterPowerAdjustEndEvent.kt @@ -23,7 +23,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class DeviceEnergyManagementClusterPowerAdjustEndEvent( - val cause: UInt, + val cause: UByte, val duration: UInt, val energyUse: Long ) { @@ -55,7 +55,7 @@ class DeviceEnergyManagementClusterPowerAdjustEndEvent( tlvReader: TlvReader ): DeviceEnergyManagementClusterPowerAdjustEndEvent { tlvReader.enterStructure(tlvTag) - val cause = tlvReader.getUInt(ContextSpecificTag(TAG_CAUSE)) + val cause = tlvReader.getUByte(ContextSpecificTag(TAG_CAUSE)) val duration = tlvReader.getUInt(ContextSpecificTag(TAG_DURATION)) val energyUse = tlvReader.getLong(ContextSpecificTag(TAG_ENERGY_USE)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DishwasherAlarmClusterNotifyEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DishwasherAlarmClusterNotifyEvent.kt index 3b0bd74a1fd5c7..37ee871d6ab829 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DishwasherAlarmClusterNotifyEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DishwasherAlarmClusterNotifyEvent.kt @@ -23,10 +23,10 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class DishwasherAlarmClusterNotifyEvent( - val active: ULong, - val inactive: ULong, - val state: ULong, - val mask: ULong + val active: UInt, + val inactive: UInt, + val state: UInt, + val mask: UInt ) { override fun toString(): String = buildString { append("DishwasherAlarmClusterNotifyEvent {\n") @@ -56,10 +56,10 @@ class DishwasherAlarmClusterNotifyEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DishwasherAlarmClusterNotifyEvent { tlvReader.enterStructure(tlvTag) - val active = tlvReader.getULong(ContextSpecificTag(TAG_ACTIVE)) - val inactive = tlvReader.getULong(ContextSpecificTag(TAG_INACTIVE)) - val state = tlvReader.getULong(ContextSpecificTag(TAG_STATE)) - val mask = tlvReader.getULong(ContextSpecificTag(TAG_MASK)) + val active = tlvReader.getUInt(ContextSpecificTag(TAG_ACTIVE)) + val inactive = tlvReader.getUInt(ContextSpecificTag(TAG_INACTIVE)) + val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) + val mask = tlvReader.getUInt(ContextSpecificTag(TAG_MASK)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorLockAlarmEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorLockAlarmEvent.kt index 5acde4acb5f40d..47cea2ef35fd1e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorLockAlarmEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorLockAlarmEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class DoorLockClusterDoorLockAlarmEvent(val alarmCode: UInt) { +class DoorLockClusterDoorLockAlarmEvent(val alarmCode: UByte) { override fun toString(): String = buildString { append("DoorLockClusterDoorLockAlarmEvent {\n") append("\talarmCode : $alarmCode\n") @@ -42,7 +42,7 @@ class DoorLockClusterDoorLockAlarmEvent(val alarmCode: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DoorLockClusterDoorLockAlarmEvent { tlvReader.enterStructure(tlvTag) - val alarmCode = tlvReader.getUInt(ContextSpecificTag(TAG_ALARM_CODE)) + val alarmCode = tlvReader.getUByte(ContextSpecificTag(TAG_ALARM_CODE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorStateChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorStateChangeEvent.kt index cc693ce9d5d390..000d434dcbcba0 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorStateChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterDoorStateChangeEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class DoorLockClusterDoorStateChangeEvent(val doorState: UInt) { +class DoorLockClusterDoorStateChangeEvent(val doorState: UByte) { override fun toString(): String = buildString { append("DoorLockClusterDoorStateChangeEvent {\n") append("\tdoorState : $doorState\n") @@ -42,7 +42,7 @@ class DoorLockClusterDoorStateChangeEvent(val doorState: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DoorLockClusterDoorStateChangeEvent { tlvReader.enterStructure(tlvTag) - val doorState = tlvReader.getUInt(ContextSpecificTag(TAG_DOOR_STATE)) + val doorState = tlvReader.getUByte(ContextSpecificTag(TAG_DOOR_STATE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationErrorEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationErrorEvent.kt index 84b682fc2d55bb..e5c5c43e8f47ee 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationErrorEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationErrorEvent.kt @@ -25,9 +25,9 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class DoorLockClusterLockOperationErrorEvent( - val lockOperationType: UInt, - val operationSource: UInt, - val operationError: UInt, + val lockOperationType: UByte, + val operationSource: UByte, + val operationError: UByte, val userIndex: UShort?, val fabricIndex: UByte?, val sourceNode: ULong?, @@ -94,9 +94,9 @@ class DoorLockClusterLockOperationErrorEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DoorLockClusterLockOperationErrorEvent { tlvReader.enterStructure(tlvTag) - val lockOperationType = tlvReader.getUInt(ContextSpecificTag(TAG_LOCK_OPERATION_TYPE)) - val operationSource = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATION_SOURCE)) - val operationError = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATION_ERROR)) + val lockOperationType = tlvReader.getUByte(ContextSpecificTag(TAG_LOCK_OPERATION_TYPE)) + val operationSource = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATION_SOURCE)) + val operationError = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATION_ERROR)) val userIndex = if (!tlvReader.isNull()) { tlvReader.getUShort(ContextSpecificTag(TAG_USER_INDEX)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationEvent.kt index 4708017ff6fcae..1f612414dec2db 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockOperationEvent.kt @@ -25,8 +25,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class DoorLockClusterLockOperationEvent( - val lockOperationType: UInt, - val operationSource: UInt, + val lockOperationType: UByte, + val operationSource: UByte, val userIndex: UShort?, val fabricIndex: UByte?, val sourceNode: ULong?, @@ -90,8 +90,8 @@ class DoorLockClusterLockOperationEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DoorLockClusterLockOperationEvent { tlvReader.enterStructure(tlvTag) - val lockOperationType = tlvReader.getUInt(ContextSpecificTag(TAG_LOCK_OPERATION_TYPE)) - val operationSource = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATION_SOURCE)) + val lockOperationType = tlvReader.getUByte(ContextSpecificTag(TAG_LOCK_OPERATION_TYPE)) + val operationSource = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATION_SOURCE)) val userIndex = if (!tlvReader.isNull()) { tlvReader.getUShort(ContextSpecificTag(TAG_USER_INDEX)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockUserChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockUserChangeEvent.kt index 81814e6393b670..f47ba130cd754a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockUserChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/DoorLockClusterLockUserChangeEvent.kt @@ -23,9 +23,9 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class DoorLockClusterLockUserChangeEvent( - val lockDataType: UInt, - val dataOperationType: UInt, - val operationSource: UInt, + val lockDataType: UByte, + val dataOperationType: UByte, + val operationSource: UByte, val userIndex: UShort?, val fabricIndex: UByte?, val sourceNode: ULong?, @@ -84,9 +84,9 @@ class DoorLockClusterLockUserChangeEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DoorLockClusterLockUserChangeEvent { tlvReader.enterStructure(tlvTag) - val lockDataType = tlvReader.getUInt(ContextSpecificTag(TAG_LOCK_DATA_TYPE)) - val dataOperationType = tlvReader.getUInt(ContextSpecificTag(TAG_DATA_OPERATION_TYPE)) - val operationSource = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATION_SOURCE)) + val lockDataType = tlvReader.getUByte(ContextSpecificTag(TAG_LOCK_DATA_TYPE)) + val dataOperationType = tlvReader.getUByte(ContextSpecificTag(TAG_DATA_OPERATION_TYPE)) + val operationSource = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATION_SOURCE)) val userIndex = if (!tlvReader.isNull()) { tlvReader.getUShort(ContextSpecificTag(TAG_USER_INDEX)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEVNotDetectedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEVNotDetectedEvent.kt index 8f38fc18fdbacf..92cf65ea0afe8a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEVNotDetectedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEVNotDetectedEvent.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class EnergyEvseClusterEVNotDetectedEvent( val sessionID: UInt, - val state: UInt, + val state: UByte, val sessionDuration: UInt, val sessionEnergyCharged: Long, val sessionEnergyDischarged: Optional @@ -65,7 +65,7 @@ class EnergyEvseClusterEVNotDetectedEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEVNotDetectedEvent { tlvReader.enterStructure(tlvTag) val sessionID = tlvReader.getUInt(ContextSpecificTag(TAG_SESSION_I_D)) - val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) + val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) val sessionDuration = tlvReader.getUInt(ContextSpecificTag(TAG_SESSION_DURATION)) val sessionEnergyCharged = tlvReader.getLong(ContextSpecificTag(TAG_SESSION_ENERGY_CHARGED)) val sessionEnergyDischarged = diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt index 14630d9043c38d..ae7aeb6550e009 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStartedEvent.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvWriter class EnergyEvseClusterEnergyTransferStartedEvent( val sessionID: UInt, - val state: UInt, + val state: UByte, val maximumCurrent: Long ) { override fun toString(): String = buildString { @@ -53,7 +53,7 @@ class EnergyEvseClusterEnergyTransferStartedEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEnergyTransferStartedEvent { tlvReader.enterStructure(tlvTag) val sessionID = tlvReader.getUInt(ContextSpecificTag(TAG_SESSION_I_D)) - val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) + val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) val maximumCurrent = tlvReader.getLong(ContextSpecificTag(TAG_MAXIMUM_CURRENT)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt index 8ce39cc2ccef2c..1bb4fdc73af266 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterEnergyTransferStoppedEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvWriter class EnergyEvseClusterEnergyTransferStoppedEvent( val sessionID: UInt, - val state: UInt, - val reason: UInt, + val state: UByte, + val reason: UByte, val energyTransferred: Long ) { override fun toString(): String = buildString { @@ -57,8 +57,8 @@ class EnergyEvseClusterEnergyTransferStoppedEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterEnergyTransferStoppedEvent { tlvReader.enterStructure(tlvTag) val sessionID = tlvReader.getUInt(ContextSpecificTag(TAG_SESSION_I_D)) - val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) - val reason = tlvReader.getUInt(ContextSpecificTag(TAG_REASON)) + val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) + val reason = tlvReader.getUByte(ContextSpecificTag(TAG_REASON)) val energyTransferred = tlvReader.getLong(ContextSpecificTag(TAG_ENERGY_TRANSFERRED)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterFaultEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterFaultEvent.kt index 71cdcae9dc193f..e45f41025d3dfb 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterFaultEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/EnergyEvseClusterFaultEvent.kt @@ -24,9 +24,9 @@ import matter.tlv.TlvWriter class EnergyEvseClusterFaultEvent( val sessionID: UInt, - val state: UInt, - val faultStatePreviousState: UInt, - val faultStateCurrentState: UInt + val state: UByte, + val faultStatePreviousState: UByte, + val faultStateCurrentState: UByte ) { override fun toString(): String = buildString { append("EnergyEvseClusterFaultEvent {\n") @@ -57,11 +57,11 @@ class EnergyEvseClusterFaultEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EnergyEvseClusterFaultEvent { tlvReader.enterStructure(tlvTag) val sessionID = tlvReader.getUInt(ContextSpecificTag(TAG_SESSION_I_D)) - val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) + val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) val faultStatePreviousState = - tlvReader.getUInt(ContextSpecificTag(TAG_FAULT_STATE_PREVIOUS_STATE)) + tlvReader.getUByte(ContextSpecificTag(TAG_FAULT_STATE_PREVIOUS_STATE)) val faultStateCurrentState = - tlvReader.getUInt(ContextSpecificTag(TAG_FAULT_STATE_CURRENT_STATE)) + tlvReader.getUByte(ContextSpecificTag(TAG_FAULT_STATE_CURRENT_STATE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterBootReasonEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterBootReasonEvent.kt index 39205bf4badbef..32a8a069c52415 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterBootReasonEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterBootReasonEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class GeneralDiagnosticsClusterBootReasonEvent(val bootReason: UInt) { +class GeneralDiagnosticsClusterBootReasonEvent(val bootReason: UByte) { override fun toString(): String = buildString { append("GeneralDiagnosticsClusterBootReasonEvent {\n") append("\tbootReason : $bootReason\n") @@ -42,7 +42,7 @@ class GeneralDiagnosticsClusterBootReasonEvent(val bootReason: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): GeneralDiagnosticsClusterBootReasonEvent { tlvReader.enterStructure(tlvTag) - val bootReason = tlvReader.getUInt(ContextSpecificTag(TAG_BOOT_REASON)) + val bootReason = tlvReader.getUByte(ContextSpecificTag(TAG_BOOT_REASON)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterHardwareFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterHardwareFaultChangeEvent.kt index b24c90d6904e36..47f191bc6d642b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterHardwareFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterHardwareFaultChangeEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class GeneralDiagnosticsClusterHardwareFaultChangeEvent( - val current: List, - val previous: List + val current: List, + val previous: List ) { override fun toString(): String = buildString { append("GeneralDiagnosticsClusterHardwareFaultChangeEvent {\n") @@ -61,18 +61,18 @@ class GeneralDiagnosticsClusterHardwareFaultChangeEvent( ): GeneralDiagnosticsClusterHardwareFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterNetworkFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterNetworkFaultChangeEvent.kt index f4423fa23b3783..c792a2ceae94c5 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterNetworkFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterNetworkFaultChangeEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class GeneralDiagnosticsClusterNetworkFaultChangeEvent( - val current: List, - val previous: List + val current: List, + val previous: List ) { override fun toString(): String = buildString { append("GeneralDiagnosticsClusterNetworkFaultChangeEvent {\n") @@ -61,18 +61,18 @@ class GeneralDiagnosticsClusterNetworkFaultChangeEvent( ): GeneralDiagnosticsClusterNetworkFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterRadioFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterRadioFaultChangeEvent.kt index f42f34f9689d63..fa15b5c2d71781 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterRadioFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/GeneralDiagnosticsClusterRadioFaultChangeEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class GeneralDiagnosticsClusterRadioFaultChangeEvent( - val current: List, - val previous: List + val current: List, + val previous: List ) { override fun toString(): String = buildString { append("GeneralDiagnosticsClusterRadioFaultChangeEvent {\n") @@ -58,18 +58,18 @@ class GeneralDiagnosticsClusterRadioFaultChangeEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): GeneralDiagnosticsClusterRadioFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/MediaPlaybackClusterStateChangedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/MediaPlaybackClusterStateChangedEvent.kt index f024905661f04f..ebef487d41894d 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/MediaPlaybackClusterStateChangedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/MediaPlaybackClusterStateChangedEvent.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class MediaPlaybackClusterStateChangedEvent( - val currentState: UInt, + val currentState: UByte, val startTime: ULong, val duration: ULong, val sampledPosition: @@ -81,7 +81,7 @@ class MediaPlaybackClusterStateChangedEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): MediaPlaybackClusterStateChangedEvent { tlvReader.enterStructure(tlvTag) - val currentState = tlvReader.getUInt(ContextSpecificTag(TAG_CURRENT_STATE)) + val currentState = tlvReader.getUByte(ContextSpecificTag(TAG_CURRENT_STATE)) val startTime = tlvReader.getULong(ContextSpecificTag(TAG_START_TIME)) val duration = tlvReader.getULong(ContextSpecificTag(TAG_DURATION)) val sampledPosition = diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OperationalStateClusterOperationCompletionEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OperationalStateClusterOperationCompletionEvent.kt index f2f65bc0d0e509..79c063e1f2a560 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OperationalStateClusterOperationCompletionEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OperationalStateClusterOperationCompletionEvent.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OperationalStateClusterOperationCompletionEvent( - val completionErrorCode: UInt, + val completionErrorCode: UByte, val totalOperationalTime: Optional?, val pausedTime: Optional? ) { @@ -70,7 +70,7 @@ class OperationalStateClusterOperationCompletionEvent( tlvReader: TlvReader ): OperationalStateClusterOperationCompletionEvent { tlvReader.enterStructure(tlvTag) - val completionErrorCode = tlvReader.getUInt(ContextSpecificTag(TAG_COMPLETION_ERROR_CODE)) + val completionErrorCode = tlvReader.getUByte(ContextSpecificTag(TAG_COMPLETION_ERROR_CODE)) val totalOperationalTime = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OtaSoftwareUpdateRequestorClusterStateTransitionEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OtaSoftwareUpdateRequestorClusterStateTransitionEvent.kt index 993efa8e9c93fc..218394cae4d8f5 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OtaSoftwareUpdateRequestorClusterStateTransitionEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OtaSoftwareUpdateRequestorClusterStateTransitionEvent.kt @@ -23,9 +23,9 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OtaSoftwareUpdateRequestorClusterStateTransitionEvent( - val previousState: UInt, - val newState: UInt, - val reason: UInt, + val previousState: UByte, + val newState: UByte, + val reason: UByte, val targetSoftwareVersion: UInt? ) { override fun toString(): String = buildString { @@ -63,9 +63,9 @@ class OtaSoftwareUpdateRequestorClusterStateTransitionEvent( tlvReader: TlvReader ): OtaSoftwareUpdateRequestorClusterStateTransitionEvent { tlvReader.enterStructure(tlvTag) - val previousState = tlvReader.getUInt(ContextSpecificTag(TAG_PREVIOUS_STATE)) - val newState = tlvReader.getUInt(ContextSpecificTag(TAG_NEW_STATE)) - val reason = tlvReader.getUInt(ContextSpecificTag(TAG_REASON)) + val previousState = tlvReader.getUByte(ContextSpecificTag(TAG_PREVIOUS_STATE)) + val newState = tlvReader.getUByte(ContextSpecificTag(TAG_NEW_STATE)) + val reason = tlvReader.getUByte(ContextSpecificTag(TAG_REASON)) val targetSoftwareVersion = if (!tlvReader.isNull()) { tlvReader.getUInt(ContextSpecificTag(TAG_TARGET_SOFTWARE_VERSION)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OvenCavityOperationalStateClusterOperationCompletionEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OvenCavityOperationalStateClusterOperationCompletionEvent.kt index ea444f0c055c3f..88611aa3823d61 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OvenCavityOperationalStateClusterOperationCompletionEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/OvenCavityOperationalStateClusterOperationCompletionEvent.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OvenCavityOperationalStateClusterOperationCompletionEvent( - val completionErrorCode: UInt, + val completionErrorCode: UByte, val totalOperationalTime: Optional?, val pausedTime: Optional? ) { @@ -70,7 +70,7 @@ class OvenCavityOperationalStateClusterOperationCompletionEvent( tlvReader: TlvReader ): OvenCavityOperationalStateClusterOperationCompletionEvent { tlvReader.enterStructure(tlvTag) - val completionErrorCode = tlvReader.getUInt(ContextSpecificTag(TAG_COMPLETION_ERROR_CODE)) + val completionErrorCode = tlvReader.getUByte(ContextSpecificTag(TAG_COMPLETION_ERROR_CODE)) val totalOperationalTime = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatChargeFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatChargeFaultChangeEvent.kt index 21cdcf674fa338..64d9215f4f01cc 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatChargeFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatChargeFaultChangeEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class PowerSourceClusterBatChargeFaultChangeEvent( - val current: List, - val previous: List + val current: List, + val previous: List ) { override fun toString(): String = buildString { append("PowerSourceClusterBatChargeFaultChangeEvent {\n") @@ -58,18 +58,18 @@ class PowerSourceClusterBatChargeFaultChangeEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): PowerSourceClusterBatChargeFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatFaultChangeEvent.kt index d1fd41e582dc94..4cf458476ddfb1 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterBatFaultChangeEvent.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class PowerSourceClusterBatFaultChangeEvent(val current: List, val previous: List) { +class PowerSourceClusterBatFaultChangeEvent(val current: List, val previous: List) { override fun toString(): String = buildString { append("PowerSourceClusterBatFaultChangeEvent {\n") append("\tcurrent : $current\n") @@ -55,18 +55,18 @@ class PowerSourceClusterBatFaultChangeEvent(val current: List, val previou fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): PowerSourceClusterBatFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterWiredFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterWiredFaultChangeEvent.kt index 8aaacc0cb49fc4..18dc33dfc82909 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterWiredFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/PowerSourceClusterWiredFaultChangeEvent.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class PowerSourceClusterWiredFaultChangeEvent(val current: List, val previous: List) { +class PowerSourceClusterWiredFaultChangeEvent(val current: List, val previous: List) { override fun toString(): String = buildString { append("PowerSourceClusterWiredFaultChangeEvent {\n") append("\tcurrent : $current\n") @@ -55,18 +55,18 @@ class PowerSourceClusterWiredFaultChangeEvent(val current: List, val previ fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): PowerSourceClusterWiredFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RefrigeratorAlarmClusterNotifyEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RefrigeratorAlarmClusterNotifyEvent.kt index ee7c9b8ebfaae6..4dfb6b68cf188c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RefrigeratorAlarmClusterNotifyEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RefrigeratorAlarmClusterNotifyEvent.kt @@ -23,10 +23,10 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class RefrigeratorAlarmClusterNotifyEvent( - val active: ULong, - val inactive: ULong, - val state: ULong, - val mask: ULong + val active: UInt, + val inactive: UInt, + val state: UInt, + val mask: UInt ) { override fun toString(): String = buildString { append("RefrigeratorAlarmClusterNotifyEvent {\n") @@ -56,10 +56,10 @@ class RefrigeratorAlarmClusterNotifyEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): RefrigeratorAlarmClusterNotifyEvent { tlvReader.enterStructure(tlvTag) - val active = tlvReader.getULong(ContextSpecificTag(TAG_ACTIVE)) - val inactive = tlvReader.getULong(ContextSpecificTag(TAG_INACTIVE)) - val state = tlvReader.getULong(ContextSpecificTag(TAG_STATE)) - val mask = tlvReader.getULong(ContextSpecificTag(TAG_MASK)) + val active = tlvReader.getUInt(ContextSpecificTag(TAG_ACTIVE)) + val inactive = tlvReader.getUInt(ContextSpecificTag(TAG_INACTIVE)) + val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) + val mask = tlvReader.getUInt(ContextSpecificTag(TAG_MASK)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RvcOperationalStateClusterOperationCompletionEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RvcOperationalStateClusterOperationCompletionEvent.kt index 3004686f8b67d8..7fa1bbd343847d 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RvcOperationalStateClusterOperationCompletionEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/RvcOperationalStateClusterOperationCompletionEvent.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class RvcOperationalStateClusterOperationCompletionEvent( - val completionErrorCode: UInt, + val completionErrorCode: UByte, val totalOperationalTime: Optional?, val pausedTime: Optional? ) { @@ -70,7 +70,7 @@ class RvcOperationalStateClusterOperationCompletionEvent( tlvReader: TlvReader ): RvcOperationalStateClusterOperationCompletionEvent { tlvReader.enterStructure(tlvTag) - val completionErrorCode = tlvReader.getUInt(ContextSpecificTag(TAG_COMPLETION_ERROR_CODE)) + val completionErrorCode = tlvReader.getUByte(ContextSpecificTag(TAG_COMPLETION_ERROR_CODE)) val totalOperationalTime = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterCOAlarmEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterCOAlarmEvent.kt index e70b19a92636d3..c6ec37cce173d5 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterCOAlarmEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterCOAlarmEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class SmokeCoAlarmClusterCOAlarmEvent(val alarmSeverityLevel: UInt) { +class SmokeCoAlarmClusterCOAlarmEvent(val alarmSeverityLevel: UByte) { override fun toString(): String = buildString { append("SmokeCoAlarmClusterCOAlarmEvent {\n") append("\talarmSeverityLevel : $alarmSeverityLevel\n") @@ -42,7 +42,7 @@ class SmokeCoAlarmClusterCOAlarmEvent(val alarmSeverityLevel: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): SmokeCoAlarmClusterCOAlarmEvent { tlvReader.enterStructure(tlvTag) - val alarmSeverityLevel = tlvReader.getUInt(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) + val alarmSeverityLevel = tlvReader.getUByte(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectCOAlarmEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectCOAlarmEvent.kt index 51aa58966bfd4c..99b4a72813f633 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectCOAlarmEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectCOAlarmEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class SmokeCoAlarmClusterInterconnectCOAlarmEvent(val alarmSeverityLevel: UInt) { +class SmokeCoAlarmClusterInterconnectCOAlarmEvent(val alarmSeverityLevel: UByte) { override fun toString(): String = buildString { append("SmokeCoAlarmClusterInterconnectCOAlarmEvent {\n") append("\talarmSeverityLevel : $alarmSeverityLevel\n") @@ -42,7 +42,7 @@ class SmokeCoAlarmClusterInterconnectCOAlarmEvent(val alarmSeverityLevel: UInt) fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): SmokeCoAlarmClusterInterconnectCOAlarmEvent { tlvReader.enterStructure(tlvTag) - val alarmSeverityLevel = tlvReader.getUInt(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) + val alarmSeverityLevel = tlvReader.getUByte(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectSmokeAlarmEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectSmokeAlarmEvent.kt index 4f2f7187caaa90..50d269f1630962 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectSmokeAlarmEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterInterconnectSmokeAlarmEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class SmokeCoAlarmClusterInterconnectSmokeAlarmEvent(val alarmSeverityLevel: UInt) { +class SmokeCoAlarmClusterInterconnectSmokeAlarmEvent(val alarmSeverityLevel: UByte) { override fun toString(): String = buildString { append("SmokeCoAlarmClusterInterconnectSmokeAlarmEvent {\n") append("\talarmSeverityLevel : $alarmSeverityLevel\n") @@ -42,7 +42,7 @@ class SmokeCoAlarmClusterInterconnectSmokeAlarmEvent(val alarmSeverityLevel: UIn fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): SmokeCoAlarmClusterInterconnectSmokeAlarmEvent { tlvReader.enterStructure(tlvTag) - val alarmSeverityLevel = tlvReader.getUInt(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) + val alarmSeverityLevel = tlvReader.getUByte(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterLowBatteryEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterLowBatteryEvent.kt index 0fd098880eddcf..18fed7cd73a497 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterLowBatteryEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterLowBatteryEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class SmokeCoAlarmClusterLowBatteryEvent(val alarmSeverityLevel: UInt) { +class SmokeCoAlarmClusterLowBatteryEvent(val alarmSeverityLevel: UByte) { override fun toString(): String = buildString { append("SmokeCoAlarmClusterLowBatteryEvent {\n") append("\talarmSeverityLevel : $alarmSeverityLevel\n") @@ -42,7 +42,7 @@ class SmokeCoAlarmClusterLowBatteryEvent(val alarmSeverityLevel: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): SmokeCoAlarmClusterLowBatteryEvent { tlvReader.enterStructure(tlvTag) - val alarmSeverityLevel = tlvReader.getUInt(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) + val alarmSeverityLevel = tlvReader.getUByte(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterSmokeAlarmEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterSmokeAlarmEvent.kt index f2b985b06eb48f..59ce0a0efae6c0 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterSmokeAlarmEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/SmokeCoAlarmClusterSmokeAlarmEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class SmokeCoAlarmClusterSmokeAlarmEvent(val alarmSeverityLevel: UInt) { +class SmokeCoAlarmClusterSmokeAlarmEvent(val alarmSeverityLevel: UByte) { override fun toString(): String = buildString { append("SmokeCoAlarmClusterSmokeAlarmEvent {\n") append("\talarmSeverityLevel : $alarmSeverityLevel\n") @@ -42,7 +42,7 @@ class SmokeCoAlarmClusterSmokeAlarmEvent(val alarmSeverityLevel: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): SmokeCoAlarmClusterSmokeAlarmEvent { tlvReader.enterStructure(tlvTag) - val alarmSeverityLevel = tlvReader.getUInt(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) + val alarmSeverityLevel = tlvReader.getUByte(ContextSpecificTag(TAG_ALARM_SEVERITY_LEVEL)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt index b771bd2b0f402c..87fdaff01533c8 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterConnectionStatusEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ThreadNetworkDiagnosticsClusterConnectionStatusEvent(val connectionStatus: UInt) { +class ThreadNetworkDiagnosticsClusterConnectionStatusEvent(val connectionStatus: UByte) { override fun toString(): String = buildString { append("ThreadNetworkDiagnosticsClusterConnectionStatusEvent {\n") append("\tconnectionStatus : $connectionStatus\n") @@ -45,7 +45,7 @@ class ThreadNetworkDiagnosticsClusterConnectionStatusEvent(val connectionStatus: tlvReader: TlvReader ): ThreadNetworkDiagnosticsClusterConnectionStatusEvent { tlvReader.enterStructure(tlvTag) - val connectionStatus = tlvReader.getUInt(ContextSpecificTag(TAG_CONNECTION_STATUS)) + val connectionStatus = tlvReader.getUByte(ContextSpecificTag(TAG_CONNECTION_STATUS)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt index 827abfa1377c6a..de061b2c233d91 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent( - val current: List, - val previous: List + val current: List, + val previous: List ) { override fun toString(): String = buildString { append("ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent {\n") @@ -61,18 +61,18 @@ class ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent( ): ThreadNetworkDiagnosticsClusterNetworkFaultChangeEvent { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/UnitTestingClusterTestEventEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/UnitTestingClusterTestEventEvent.kt index 2993e43dedc6cd..a9b8b2454bb502 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/UnitTestingClusterTestEventEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/UnitTestingClusterTestEventEvent.kt @@ -25,11 +25,11 @@ import matter.tlv.TlvWriter class UnitTestingClusterTestEventEvent( val arg1: UByte, - val arg2: UInt, + val arg2: UByte, val arg3: Boolean, val arg4: matter.devicecontroller.cluster.structs.UnitTestingClusterSimpleStruct, val arg5: List, - val arg6: List + val arg6: List ) { override fun toString(): String = buildString { append("UnitTestingClusterTestEventEvent {\n") @@ -74,7 +74,7 @@ class UnitTestingClusterTestEventEvent( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterTestEventEvent { tlvReader.enterStructure(tlvTag) val arg1 = tlvReader.getUByte(ContextSpecificTag(TAG_ARG1)) - val arg2 = tlvReader.getUInt(ContextSpecificTag(TAG_ARG2)) + val arg2 = tlvReader.getUByte(ContextSpecificTag(TAG_ARG2)) val arg3 = tlvReader.getBoolean(ContextSpecificTag(TAG_ARG3)) val arg4 = matter.devicecontroller.cluster.structs.UnitTestingClusterSimpleStruct.fromTlv( @@ -95,10 +95,10 @@ class UnitTestingClusterTestEventEvent( tlvReader.exitContainer() } val arg6 = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_ARG6)) while (!tlvReader.isEndOfContainer()) { - this.add(tlvReader.getUInt(AnonymousTag)) + this.add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveFaultEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveFaultEvent.kt index 6aa0f2c8ea44bf..5ba4afdca9e52b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveFaultEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveFaultEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ValveConfigurationAndControlClusterValveFaultEvent(val valveFault: UInt) { +class ValveConfigurationAndControlClusterValveFaultEvent(val valveFault: UShort) { override fun toString(): String = buildString { append("ValveConfigurationAndControlClusterValveFaultEvent {\n") append("\tvalveFault : $valveFault\n") @@ -45,7 +45,7 @@ class ValveConfigurationAndControlClusterValveFaultEvent(val valveFault: UInt) { tlvReader: TlvReader ): ValveConfigurationAndControlClusterValveFaultEvent { tlvReader.enterStructure(tlvTag) - val valveFault = tlvReader.getUInt(ContextSpecificTag(TAG_VALVE_FAULT)) + val valveFault = tlvReader.getUShort(ContextSpecificTag(TAG_VALVE_FAULT)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt index 37e58c25cea495..d75afd26bd341a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/ValveConfigurationAndControlClusterValveStateChangedEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: UInt) { +class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: UByte) { override fun toString(): String = buildString { append("ValveConfigurationAndControlClusterValveStateChangedEvent {\n") append("\tvalveState : $valveState\n") @@ -45,7 +45,7 @@ class ValveConfigurationAndControlClusterValveStateChangedEvent(val valveState: tlvReader: TlvReader ): ValveConfigurationAndControlClusterValveStateChangedEvent { tlvReader.enterStructure(tlvTag) - val valveState = tlvReader.getUInt(ContextSpecificTag(TAG_VALVE_STATE)) + val valveState = tlvReader.getUByte(ContextSpecificTag(TAG_VALVE_STATE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt index 04b408b87c41c2..cf0b6ad90b982b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt @@ -23,7 +23,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class WiFiNetworkDiagnosticsClusterAssociationFailureEvent( - val associationFailureCause: UInt, + val associationFailureCause: UByte, val status: UShort ) { override fun toString(): String = buildString { @@ -52,7 +52,7 @@ class WiFiNetworkDiagnosticsClusterAssociationFailureEvent( ): WiFiNetworkDiagnosticsClusterAssociationFailureEvent { tlvReader.enterStructure(tlvTag) val associationFailureCause = - tlvReader.getUInt(ContextSpecificTag(TAG_ASSOCIATION_FAILURE_CAUSE)) + tlvReader.getUByte(ContextSpecificTag(TAG_ASSOCIATION_FAILURE_CAUSE)) val status = tlvReader.getUShort(ContextSpecificTag(TAG_STATUS)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterConnectionStatusEvent.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterConnectionStatusEvent.kt index 653e02a013159d..09010454a1741c 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterConnectionStatusEvent.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterConnectionStatusEvent.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class WiFiNetworkDiagnosticsClusterConnectionStatusEvent(val connectionStatus: UInt) { +class WiFiNetworkDiagnosticsClusterConnectionStatusEvent(val connectionStatus: UByte) { override fun toString(): String = buildString { append("WiFiNetworkDiagnosticsClusterConnectionStatusEvent {\n") append("\tconnectionStatus : $connectionStatus\n") @@ -45,7 +45,7 @@ class WiFiNetworkDiagnosticsClusterConnectionStatusEvent(val connectionStatus: U tlvReader: TlvReader ): WiFiNetworkDiagnosticsClusterConnectionStatusEvent { tlvReader.enterStructure(tlvTag) - val connectionStatus = tlvReader.getUInt(ContextSpecificTag(TAG_CONNECTION_STATUS)) + val connectionStatus = tlvReader.getUByte(ContextSpecificTag(TAG_CONNECTION_STATUS)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AccessControlClusterAccessControlEntryStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AccessControlClusterAccessControlEntryStruct.kt index 7160b776b170fb..524ee0ea8d6e0a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AccessControlClusterAccessControlEntryStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AccessControlClusterAccessControlEntryStruct.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class AccessControlClusterAccessControlEntryStruct( - val privilege: UInt, - val authMode: UInt, + val privilege: UByte, + val authMode: UByte, val subjects: List?, val targets: List?, val fabricIndex: UByte @@ -77,8 +77,8 @@ class AccessControlClusterAccessControlEntryStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): AccessControlClusterAccessControlEntryStruct { tlvReader.enterStructure(tlvTag) - val privilege = tlvReader.getUInt(ContextSpecificTag(TAG_PRIVILEGE)) - val authMode = tlvReader.getUInt(ContextSpecificTag(TAG_AUTH_MODE)) + val privilege = tlvReader.getUByte(ContextSpecificTag(TAG_PRIVILEGE)) + val authMode = tlvReader.getUByte(ContextSpecificTag(TAG_AUTH_MODE)) val subjects = if (!tlvReader.isNull()) { buildList { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterActionStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterActionStruct.kt index 43a6ed963d8b52..862ff33b5505c9 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterActionStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterActionStruct.kt @@ -25,10 +25,10 @@ import matter.tlv.TlvWriter class ActionsClusterActionStruct( val actionID: UShort, val name: String, - val type: UInt, + val type: UByte, val endpointListID: UShort, - val supportedCommands: UInt, - val state: UInt + val supportedCommands: UShort, + val state: UByte ) { override fun toString(): String = buildString { append("ActionsClusterActionStruct {\n") @@ -66,10 +66,10 @@ class ActionsClusterActionStruct( tlvReader.enterStructure(tlvTag) val actionID = tlvReader.getUShort(ContextSpecificTag(TAG_ACTION_I_D)) val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) - val type = tlvReader.getUInt(ContextSpecificTag(TAG_TYPE)) + val type = tlvReader.getUByte(ContextSpecificTag(TAG_TYPE)) val endpointListID = tlvReader.getUShort(ContextSpecificTag(TAG_ENDPOINT_LIST_I_D)) - val supportedCommands = tlvReader.getUInt(ContextSpecificTag(TAG_SUPPORTED_COMMANDS)) - val state = tlvReader.getUInt(ContextSpecificTag(TAG_STATE)) + val supportedCommands = tlvReader.getUShort(ContextSpecificTag(TAG_SUPPORTED_COMMANDS)) + val state = tlvReader.getUByte(ContextSpecificTag(TAG_STATE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterEndpointListStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterEndpointListStruct.kt index 7b0f6a5616f52f..82648d5de25703 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterEndpointListStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActionsClusterEndpointListStruct.kt @@ -26,7 +26,7 @@ import matter.tlv.TlvWriter class ActionsClusterEndpointListStruct( val endpointListID: UShort, val name: String, - val type: UInt, + val type: UByte, val endpoints: List ) { override fun toString(): String = buildString { @@ -63,7 +63,7 @@ class ActionsClusterEndpointListStruct( tlvReader.enterStructure(tlvTag) val endpointListID = tlvReader.getUShort(ContextSpecificTag(TAG_ENDPOINT_LIST_I_D)) val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) - val type = tlvReader.getUInt(ContextSpecificTag(TAG_TYPE)) + val type = tlvReader.getUByte(ContextSpecificTag(TAG_TYPE)) val endpoints = buildList { tlvReader.enterArray(ContextSpecificTag(TAG_ENDPOINTS)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.kt index 3f3b66764532b4..d6b1ed9c39a38e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class ActivatedCarbonFilterMonitoringClusterReplacementProductStruct( - val productIdentifierType: UInt, + val productIdentifierType: UByte, val productIdentifierValue: String ) { override fun toString(): String = buildString { @@ -51,7 +51,8 @@ class ActivatedCarbonFilterMonitoringClusterReplacementProductStruct( tlvReader: TlvReader ): ActivatedCarbonFilterMonitoringClusterReplacementProductStruct { tlvReader.enterStructure(tlvTag) - val productIdentifierType = tlvReader.getUInt(ContextSpecificTag(TAG_PRODUCT_IDENTIFIER_TYPE)) + val productIdentifierType = + tlvReader.getUByte(ContextSpecificTag(TAG_PRODUCT_IDENTIFIER_TYPE)) val productIdentifierValue = tlvReader.getString(ContextSpecificTag(TAG_PRODUCT_IDENTIFIER_VALUE)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AudioOutputClusterOutputInfoStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AudioOutputClusterOutputInfoStruct.kt index 07c6c02e0e16af..dbb7159ed96c22 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AudioOutputClusterOutputInfoStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/AudioOutputClusterOutputInfoStruct.kt @@ -22,7 +22,11 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class AudioOutputClusterOutputInfoStruct(val index: UByte, val outputType: UInt, val name: String) { +class AudioOutputClusterOutputInfoStruct( + val index: UByte, + val outputType: UByte, + val name: String +) { override fun toString(): String = buildString { append("AudioOutputClusterOutputInfoStruct {\n") append("\tindex : $index\n") @@ -49,7 +53,7 @@ class AudioOutputClusterOutputInfoStruct(val index: UByte, val outputType: UInt, fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): AudioOutputClusterOutputInfoStruct { tlvReader.enterStructure(tlvTag) val index = tlvReader.getUByte(ContextSpecificTag(TAG_INDEX)) - val outputType = tlvReader.getUInt(ContextSpecificTag(TAG_OUTPUT_TYPE)) + val outputType = tlvReader.getUByte(ContextSpecificTag(TAG_OUTPUT_TYPE)) val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BasicInformationClusterProductAppearanceStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BasicInformationClusterProductAppearanceStruct.kt index b1bd7ea2c5599b..cbce32fd9ec3b5 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BasicInformationClusterProductAppearanceStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BasicInformationClusterProductAppearanceStruct.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class BasicInformationClusterProductAppearanceStruct(val finish: UInt, val primaryColor: UInt?) { +class BasicInformationClusterProductAppearanceStruct(val finish: UByte, val primaryColor: UByte?) { override fun toString(): String = buildString { append("BasicInformationClusterProductAppearanceStruct {\n") append("\tfinish : $finish\n") @@ -49,10 +49,10 @@ class BasicInformationClusterProductAppearanceStruct(val finish: UInt, val prima fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): BasicInformationClusterProductAppearanceStruct { tlvReader.enterStructure(tlvTag) - val finish = tlvReader.getUInt(ContextSpecificTag(TAG_FINISH)) + val finish = tlvReader.getUByte(ContextSpecificTag(TAG_FINISH)) val primaryColor = if (!tlvReader.isNull()) { - tlvReader.getUInt(ContextSpecificTag(TAG_PRIMARY_COLOR)) + tlvReader.getUByte(ContextSpecificTag(TAG_PRIMARY_COLOR)) } else { tlvReader.getNull(ContextSpecificTag(TAG_PRIMARY_COLOR)) null diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BridgedDeviceBasicInformationClusterProductAppearanceStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BridgedDeviceBasicInformationClusterProductAppearanceStruct.kt index c6b0dea505512d..ef01f0a7492883 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BridgedDeviceBasicInformationClusterProductAppearanceStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/BridgedDeviceBasicInformationClusterProductAppearanceStruct.kt @@ -23,8 +23,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class BridgedDeviceBasicInformationClusterProductAppearanceStruct( - val finish: UInt, - val primaryColor: UInt? + val finish: UByte, + val primaryColor: UByte? ) { override fun toString(): String = buildString { append("BridgedDeviceBasicInformationClusterProductAppearanceStruct {\n") @@ -55,10 +55,10 @@ class BridgedDeviceBasicInformationClusterProductAppearanceStruct( tlvReader: TlvReader ): BridgedDeviceBasicInformationClusterProductAppearanceStruct { tlvReader.enterStructure(tlvTag) - val finish = tlvReader.getUInt(ContextSpecificTag(TAG_FINISH)) + val finish = tlvReader.getUByte(ContextSpecificTag(TAG_FINISH)) val primaryColor = if (!tlvReader.isNull()) { - tlvReader.getUInt(ContextSpecificTag(TAG_PRIMARY_COLOR)) + tlvReader.getUByte(ContextSpecificTag(TAG_PRIMARY_COLOR)) } else { tlvReader.getNull(ContextSpecificTag(TAG_PRIMARY_COLOR)) null diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterChannelInfoStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterChannelInfoStruct.kt index 140a9efa1979ba..4a310305a89541 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterChannelInfoStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterChannelInfoStruct.kt @@ -30,7 +30,7 @@ class ChannelClusterChannelInfoStruct( val callSign: Optional, val affiliateCallSign: Optional, val identifier: Optional, - val type: Optional + val type: Optional ) { override fun toString(): String = buildString { append("ChannelClusterChannelInfoStruct {\n") @@ -112,7 +112,7 @@ class ChannelClusterChannelInfoStruct( } val type = if (tlvReader.isNextTag(ContextSpecificTag(TAG_TYPE))) { - Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_TYPE))) + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_TYPE))) } else { Optional.empty() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterLineupInfoStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterLineupInfoStruct.kt index cb1ab50c1e95db..5b1fd59a37ddda 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterLineupInfoStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterLineupInfoStruct.kt @@ -27,7 +27,7 @@ class ChannelClusterLineupInfoStruct( val operatorName: String, val lineupName: Optional, val postalCode: Optional, - val lineupInfoType: UInt + val lineupInfoType: UByte ) { override fun toString(): String = buildString { append("ChannelClusterLineupInfoStruct {\n") @@ -76,7 +76,7 @@ class ChannelClusterLineupInfoStruct( } else { Optional.empty() } - val lineupInfoType = tlvReader.getUInt(ContextSpecificTag(TAG_LINEUP_INFO_TYPE)) + val lineupInfoType = tlvReader.getUByte(ContextSpecificTag(TAG_LINEUP_INFO_TYPE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterProgramStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterProgramStruct.kt index 434d64c9bc8ad4..0912c5cffa1f2b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterProgramStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ChannelClusterProgramStruct.kt @@ -39,7 +39,7 @@ class ChannelClusterProgramStruct( val dvbiUrl: Optional, val releaseDate: Optional, val parentalGuidanceText: Optional, - val recordingFlag: Optional, + val recordingFlag: Optional, val seriesInfo: Optional?, val categoryList: Optional>, val castList: Optional>, @@ -262,7 +262,7 @@ class ChannelClusterProgramStruct( } val recordingFlag = if (tlvReader.isNextTag(ContextSpecificTag(TAG_RECORDING_FLAG))) { - Optional.of(tlvReader.getULong(ContextSpecificTag(TAG_RECORDING_FLAG))) + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_RECORDING_FLAG))) } else { Optional.empty() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterDimensionStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterDimensionStruct.kt index 02b1322f5f9f17..657df17fecccf1 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterDimensionStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterDimensionStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class ContentLauncherClusterDimensionStruct( val width: Double, val height: Double, - val metric: UInt + val metric: UByte ) { override fun toString(): String = buildString { append("ContentLauncherClusterDimensionStruct {\n") @@ -54,7 +54,7 @@ class ContentLauncherClusterDimensionStruct( tlvReader.enterStructure(tlvTag) val width = tlvReader.getDouble(ContextSpecificTag(TAG_WIDTH)) val height = tlvReader.getDouble(ContextSpecificTag(TAG_HEIGHT)) - val metric = tlvReader.getUInt(ContextSpecificTag(TAG_METRIC)) + val metric = tlvReader.getUByte(ContextSpecificTag(TAG_METRIC)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterParameterStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterParameterStruct.kt index ee1efa7365917b..ac3c1e2859eb36 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterParameterStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterParameterStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class ContentLauncherClusterParameterStruct( - val type: UInt, + val type: UByte, val value: String, val externalIDList: Optional> ) { @@ -61,7 +61,7 @@ class ContentLauncherClusterParameterStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ContentLauncherClusterParameterStruct { tlvReader.enterStructure(tlvTag) - val type = tlvReader.getUInt(ContextSpecificTag(TAG_TYPE)) + val type = tlvReader.getUByte(ContextSpecificTag(TAG_TYPE)) val value = tlvReader.getString(ContextSpecificTag(TAG_VALUE)) val externalIDList = if (tlvReader.isNextTag(ContextSpecificTag(TAG_EXTERNAL_I_D_LIST))) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterTrackPreferenceStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterTrackPreferenceStruct.kt index 3dc13d4aed478e..b7d3dae5ba607d 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterTrackPreferenceStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ContentLauncherClusterTrackPreferenceStruct.kt @@ -26,7 +26,7 @@ import matter.tlv.TlvWriter class ContentLauncherClusterTrackPreferenceStruct( val languageCode: String, - val characteristics: Optional>, + val characteristics: Optional>, val audioOutputIndex: UByte ) { override fun toString(): String = buildString { @@ -65,10 +65,10 @@ class ContentLauncherClusterTrackPreferenceStruct( val characteristics = if (tlvReader.isNextTag(ContextSpecificTag(TAG_CHARACTERISTICS))) { Optional.of( - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CHARACTERISTICS)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterHeatingSourceControlStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterHeatingSourceControlStruct.kt index 0be25f2696b61c..fffee64fff287b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterHeatingSourceControlStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterHeatingSourceControlStruct.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class DemandResponseLoadControlClusterHeatingSourceControlStruct(val heatingSource: UInt) { +class DemandResponseLoadControlClusterHeatingSourceControlStruct(val heatingSource: UByte) { override fun toString(): String = buildString { append("DemandResponseLoadControlClusterHeatingSourceControlStruct {\n") append("\theatingSource : $heatingSource\n") @@ -45,7 +45,7 @@ class DemandResponseLoadControlClusterHeatingSourceControlStruct(val heatingSour tlvReader: TlvReader ): DemandResponseLoadControlClusterHeatingSourceControlStruct { tlvReader.enterStructure(tlvTag) - val heatingSource = tlvReader.getUInt(ContextSpecificTag(TAG_HEATING_SOURCE)) + val heatingSource = tlvReader.getUByte(ContextSpecificTag(TAG_HEATING_SOURCE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventStruct.kt index fff221a680f729..ba36b9d1312ed9 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventStruct.kt @@ -27,10 +27,10 @@ import matter.tlv.TlvWriter class DemandResponseLoadControlClusterLoadControlEventStruct( val eventID: ByteArray, val programID: ByteArray?, - val control: UInt, - val deviceClass: ULong, + val control: UShort, + val deviceClass: UInt, val enrollmentGroup: Optional, - val criticality: UInt, + val criticality: UByte, val startTime: UInt?, val transitions: List ) { @@ -100,15 +100,15 @@ class DemandResponseLoadControlClusterLoadControlEventStruct( tlvReader.getNull(ContextSpecificTag(TAG_PROGRAM_I_D)) null } - val control = tlvReader.getUInt(ContextSpecificTag(TAG_CONTROL)) - val deviceClass = tlvReader.getULong(ContextSpecificTag(TAG_DEVICE_CLASS)) + val control = tlvReader.getUShort(ContextSpecificTag(TAG_CONTROL)) + val deviceClass = tlvReader.getUInt(ContextSpecificTag(TAG_DEVICE_CLASS)) val enrollmentGroup = if (tlvReader.isNextTag(ContextSpecificTag(TAG_ENROLLMENT_GROUP))) { Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_ENROLLMENT_GROUP))) } else { Optional.empty() } - val criticality = tlvReader.getUInt(ContextSpecificTag(TAG_CRITICALITY)) + val criticality = tlvReader.getUByte(ContextSpecificTag(TAG_CRITICALITY)) val startTime = if (!tlvReader.isNull()) { tlvReader.getUInt(ContextSpecificTag(TAG_START_TIME)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventTransitionStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventTransitionStruct.kt index 46c70edba6e5c8..609288f5772213 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventTransitionStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DemandResponseLoadControlClusterLoadControlEventTransitionStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class DemandResponseLoadControlClusterLoadControlEventTransitionStruct( val duration: UShort, - val control: UInt, + val control: UShort, val temperatureControl: Optional, val averageLoadControl: Optional, val dutyCycleControl: Optional, @@ -88,7 +88,7 @@ class DemandResponseLoadControlClusterLoadControlEventTransitionStruct( ): DemandResponseLoadControlClusterLoadControlEventTransitionStruct { tlvReader.enterStructure(tlvTag) val duration = tlvReader.getUShort(ContextSpecificTag(TAG_DURATION)) - val control = tlvReader.getUInt(ContextSpecificTag(TAG_CONTROL)) + val control = tlvReader.getUShort(ContextSpecificTag(TAG_CONTROL)) val temperatureControl = if (tlvReader.isNextTag(ContextSpecificTag(TAG_TEMPERATURE_CONTROL))) { Optional.of( diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DescriptorClusterSemanticTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DescriptorClusterSemanticTagStruct.kt index 2dd5869528c27f..67a8e878c70058 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DescriptorClusterSemanticTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DescriptorClusterSemanticTagStruct.kt @@ -25,8 +25,8 @@ import matter.tlv.TlvWriter class DescriptorClusterSemanticTagStruct( val mfgCode: UShort?, - val namespaceID: UInt, - val tag: UInt, + val namespaceID: UByte, + val tag: UByte, val label: Optional? ) { override fun toString(): String = buildString { @@ -75,8 +75,8 @@ class DescriptorClusterSemanticTagStruct( tlvReader.getNull(ContextSpecificTag(TAG_MFG_CODE)) null } - val namespaceID = tlvReader.getUInt(ContextSpecificTag(TAG_NAMESPACE_I_D)) - val tag = tlvReader.getUInt(ContextSpecificTag(TAG_TAG)) + val namespaceID = tlvReader.getUByte(ContextSpecificTag(TAG_NAMESPACE_I_D)) + val tag = tlvReader.getUByte(ContextSpecificTag(TAG_TAG)) val label = if (!tlvReader.isNull()) { if (tlvReader.isNextTag(ContextSpecificTag(TAG_LABEL))) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DeviceEnergyManagementClusterCostStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DeviceEnergyManagementClusterCostStruct.kt index 58f037e4bfe968..d0266796945f42 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DeviceEnergyManagementClusterCostStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DeviceEnergyManagementClusterCostStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class DeviceEnergyManagementClusterCostStruct( - val costType: UInt, + val costType: UByte, val value: Int, val decimalPoints: UByte, val currency: Optional @@ -60,7 +60,7 @@ class DeviceEnergyManagementClusterCostStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DeviceEnergyManagementClusterCostStruct { tlvReader.enterStructure(tlvTag) - val costType = tlvReader.getUInt(ContextSpecificTag(TAG_COST_TYPE)) + val costType = tlvReader.getUByte(ContextSpecificTag(TAG_COST_TYPE)) val value = tlvReader.getInt(ContextSpecificTag(TAG_VALUE)) val decimalPoints = tlvReader.getUByte(ContextSpecificTag(TAG_DECIMAL_POINTS)) val currency = diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DishwasherModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DishwasherModeClusterModeTagStruct.kt index 7e3d6bbe24ecdb..ef408485ddea6b 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DishwasherModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DishwasherModeClusterModeTagStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class DishwasherModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { +class DishwasherModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { override fun toString(): String = buildString { append("DishwasherModeClusterModeTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -55,7 +55,7 @@ class DishwasherModeClusterModeTagStruct(val mfgCode: Optional, val valu } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DoorLockClusterCredentialStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DoorLockClusterCredentialStruct.kt index 4ee0122fa76b0c..5c04ebe8a52e1f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DoorLockClusterCredentialStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/DoorLockClusterCredentialStruct.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class DoorLockClusterCredentialStruct(val credentialType: UInt, val credentialIndex: UShort) { +class DoorLockClusterCredentialStruct(val credentialType: UByte, val credentialIndex: UShort) { override fun toString(): String = buildString { append("DoorLockClusterCredentialStruct {\n") append("\tcredentialType : $credentialType\n") @@ -45,7 +45,7 @@ class DoorLockClusterCredentialStruct(val credentialType: UInt, val credentialIn fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): DoorLockClusterCredentialStruct { tlvReader.enterStructure(tlvTag) - val credentialType = tlvReader.getUInt(ContextSpecificTag(TAG_CREDENTIAL_TYPE)) + val credentialType = tlvReader.getUByte(ContextSpecificTag(TAG_CREDENTIAL_TYPE)) val credentialIndex = tlvReader.getUShort(ContextSpecificTag(TAG_CREDENTIAL_INDEX)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GeneralDiagnosticsClusterNetworkInterface.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GeneralDiagnosticsClusterNetworkInterface.kt index 900e71adea7c6d..841585a07be118 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GeneralDiagnosticsClusterNetworkInterface.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GeneralDiagnosticsClusterNetworkInterface.kt @@ -31,7 +31,7 @@ class GeneralDiagnosticsClusterNetworkInterface( val hardwareAddress: ByteArray, val IPv4Addresses: List, val IPv6Addresses: List, - val type: UInt + val type: UByte ) { override fun toString(): String = buildString { append("GeneralDiagnosticsClusterNetworkInterface {\n") @@ -128,7 +128,7 @@ class GeneralDiagnosticsClusterNetworkInterface( } tlvReader.exitContainer() } - val type = tlvReader.getUInt(ContextSpecificTag(TAG_TYPE)) + val type = tlvReader.getUByte(ContextSpecificTag(TAG_TYPE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GroupKeyManagementClusterGroupKeySetStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GroupKeyManagementClusterGroupKeySetStruct.kt index 2c8d334a4cffd9..d624fed8ef7308 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GroupKeyManagementClusterGroupKeySetStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/GroupKeyManagementClusterGroupKeySetStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvWriter class GroupKeyManagementClusterGroupKeySetStruct( val groupKeySetID: UShort, - val groupKeySecurityPolicy: UInt, + val groupKeySecurityPolicy: UByte, val epochKey0: ByteArray?, val epochStartTime0: ULong?, val epochKey1: ByteArray?, @@ -98,7 +98,7 @@ class GroupKeyManagementClusterGroupKeySetStruct( tlvReader.enterStructure(tlvTag) val groupKeySetID = tlvReader.getUShort(ContextSpecificTag(TAG_GROUP_KEY_SET_I_D)) val groupKeySecurityPolicy = - tlvReader.getUInt(ContextSpecificTag(TAG_GROUP_KEY_SECURITY_POLICY)) + tlvReader.getUByte(ContextSpecificTag(TAG_GROUP_KEY_SECURITY_POLICY)) val epochKey0 = if (!tlvReader.isNull()) { tlvReader.getByteArray(ContextSpecificTag(TAG_EPOCH_KEY0)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/HepaFilterMonitoringClusterReplacementProductStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/HepaFilterMonitoringClusterReplacementProductStruct.kt index 32ce0e6298f485..8d3aeb5d887cbe 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/HepaFilterMonitoringClusterReplacementProductStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/HepaFilterMonitoringClusterReplacementProductStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class HepaFilterMonitoringClusterReplacementProductStruct( - val productIdentifierType: UInt, + val productIdentifierType: UByte, val productIdentifierValue: String ) { override fun toString(): String = buildString { @@ -51,7 +51,8 @@ class HepaFilterMonitoringClusterReplacementProductStruct( tlvReader: TlvReader ): HepaFilterMonitoringClusterReplacementProductStruct { tlvReader.enterStructure(tlvTag) - val productIdentifierType = tlvReader.getUInt(ContextSpecificTag(TAG_PRODUCT_IDENTIFIER_TYPE)) + val productIdentifierType = + tlvReader.getUByte(ContextSpecificTag(TAG_PRODUCT_IDENTIFIER_TYPE)) val productIdentifierValue = tlvReader.getString(ContextSpecificTag(TAG_PRODUCT_IDENTIFIER_VALUE)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/LaundryWasherModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/LaundryWasherModeClusterModeTagStruct.kt index 0284a239b9b610..1d8d1c84b81a8e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/LaundryWasherModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/LaundryWasherModeClusterModeTagStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class LaundryWasherModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { +class LaundryWasherModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { override fun toString(): String = buildString { append("LaundryWasherModeClusterModeTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -55,7 +55,7 @@ class LaundryWasherModeClusterModeTagStruct(val mfgCode: Optional, val v } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MediaInputClusterInputInfoStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MediaInputClusterInputInfoStruct.kt index ef3a028b680b8a..2960b70a6751d4 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MediaInputClusterInputInfoStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MediaInputClusterInputInfoStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvWriter class MediaInputClusterInputInfoStruct( val index: UByte, - val inputType: UInt, + val inputType: UByte, val name: String, val description: String ) { @@ -57,7 +57,7 @@ class MediaInputClusterInputInfoStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): MediaInputClusterInputInfoStruct { tlvReader.enterStructure(tlvTag) val index = tlvReader.getUByte(ContextSpecificTag(TAG_INDEX)) - val inputType = tlvReader.getUInt(ContextSpecificTag(TAG_INPUT_TYPE)) + val inputType = tlvReader.getUByte(ContextSpecificTag(TAG_INPUT_TYPE)) val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) val description = tlvReader.getString(ContextSpecificTag(TAG_DESCRIPTION)) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt index d0d088a1d77b42..49d0d496c4ed98 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class MicrowaveOvenModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { +class MicrowaveOvenModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { override fun toString(): String = buildString { append("MicrowaveOvenModeClusterModeTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -55,7 +55,7 @@ class MicrowaveOvenModeClusterModeTagStruct(val mfgCode: Optional, val v } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ModeSelectClusterSemanticTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ModeSelectClusterSemanticTagStruct.kt index 5b6d1ae0fb71f0..ba8e6dfa38e45d 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ModeSelectClusterSemanticTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ModeSelectClusterSemanticTagStruct.kt @@ -22,7 +22,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ModeSelectClusterSemanticTagStruct(val mfgCode: UShort, val value: UInt) { +class ModeSelectClusterSemanticTagStruct(val mfgCode: UShort, val value: UShort) { override fun toString(): String = buildString { append("ModeSelectClusterSemanticTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -46,7 +46,7 @@ class ModeSelectClusterSemanticTagStruct(val mfgCode: UShort, val value: UInt) { fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ModeSelectClusterSemanticTagStruct { tlvReader.enterStructure(tlvTag) val mfgCode = tlvReader.getUShort(ContextSpecificTag(TAG_MFG_CODE)) - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/NetworkCommissioningClusterWiFiInterfaceScanResultStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/NetworkCommissioningClusterWiFiInterfaceScanResultStruct.kt index 3d2c8ea65a32bd..eeff78c81dc6ab 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/NetworkCommissioningClusterWiFiInterfaceScanResultStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/NetworkCommissioningClusterWiFiInterfaceScanResultStruct.kt @@ -23,11 +23,11 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class NetworkCommissioningClusterWiFiInterfaceScanResultStruct( - val security: UInt, + val security: UByte, val ssid: ByteArray, val bssid: ByteArray, val channel: UShort, - val wiFiBand: UInt, + val wiFiBand: UByte, val rssi: Byte ) { override fun toString(): String = buildString { @@ -67,11 +67,11 @@ class NetworkCommissioningClusterWiFiInterfaceScanResultStruct( tlvReader: TlvReader ): NetworkCommissioningClusterWiFiInterfaceScanResultStruct { tlvReader.enterStructure(tlvTag) - val security = tlvReader.getUInt(ContextSpecificTag(TAG_SECURITY)) + val security = tlvReader.getUByte(ContextSpecificTag(TAG_SECURITY)) val ssid = tlvReader.getByteArray(ContextSpecificTag(TAG_SSID)) val bssid = tlvReader.getByteArray(ContextSpecificTag(TAG_BSSID)) val channel = tlvReader.getUShort(ContextSpecificTag(TAG_CHANNEL)) - val wiFiBand = tlvReader.getUInt(ContextSpecificTag(TAG_WI_FI_BAND)) + val wiFiBand = tlvReader.getUByte(ContextSpecificTag(TAG_WI_FI_BAND)) val rssi = tlvReader.getByte(ContextSpecificTag(TAG_RSSI)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterErrorStateStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterErrorStateStruct.kt index f49646d015d186..a482cb456d182a 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterErrorStateStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterErrorStateStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OperationalStateClusterErrorStateStruct( - val errorStateID: UInt, + val errorStateID: UByte, val errorStateLabel: Optional, val errorStateDetails: Optional ) { @@ -59,7 +59,7 @@ class OperationalStateClusterErrorStateStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): OperationalStateClusterErrorStateStruct { tlvReader.enterStructure(tlvTag) - val errorStateID = tlvReader.getUInt(ContextSpecificTag(TAG_ERROR_STATE_I_D)) + val errorStateID = tlvReader.getUByte(ContextSpecificTag(TAG_ERROR_STATE_I_D)) val errorStateLabel = if (tlvReader.isNextTag(ContextSpecificTag(TAG_ERROR_STATE_LABEL))) { Optional.of(tlvReader.getString(ContextSpecificTag(TAG_ERROR_STATE_LABEL))) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterOperationalStateStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterOperationalStateStruct.kt index 238035d38a060e..897a6be2a25e74 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterOperationalStateStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OperationalStateClusterOperationalStateStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OperationalStateClusterOperationalStateStruct( - val operationalStateID: UInt, + val operationalStateID: UByte, val operationalStateLabel: Optional ) { override fun toString(): String = buildString { @@ -52,7 +52,7 @@ class OperationalStateClusterOperationalStateStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): OperationalStateClusterOperationalStateStruct { tlvReader.enterStructure(tlvTag) - val operationalStateID = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATIONAL_STATE_I_D)) + val operationalStateID = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATIONAL_STATE_I_D)) val operationalStateLabel = if (tlvReader.isNextTag(ContextSpecificTag(TAG_OPERATIONAL_STATE_LABEL))) { Optional.of(tlvReader.getString(ContextSpecificTag(TAG_OPERATIONAL_STATE_LABEL))) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterErrorStateStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterErrorStateStruct.kt index 5b98278cda9aa4..256e91b13a5d72 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterErrorStateStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterErrorStateStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OvenCavityOperationalStateClusterErrorStateStruct( - val errorStateID: UInt, + val errorStateID: UByte, val errorStateLabel: Optional, val errorStateDetails: Optional ) { @@ -62,7 +62,7 @@ class OvenCavityOperationalStateClusterErrorStateStruct( tlvReader: TlvReader ): OvenCavityOperationalStateClusterErrorStateStruct { tlvReader.enterStructure(tlvTag) - val errorStateID = tlvReader.getUInt(ContextSpecificTag(TAG_ERROR_STATE_I_D)) + val errorStateID = tlvReader.getUByte(ContextSpecificTag(TAG_ERROR_STATE_I_D)) val errorStateLabel = if (tlvReader.isNextTag(ContextSpecificTag(TAG_ERROR_STATE_LABEL))) { Optional.of(tlvReader.getString(ContextSpecificTag(TAG_ERROR_STATE_LABEL))) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterOperationalStateStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterOperationalStateStruct.kt index 51b2811215e0cc..123785b715eaa5 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterOperationalStateStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenCavityOperationalStateClusterOperationalStateStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class OvenCavityOperationalStateClusterOperationalStateStruct( - val operationalStateID: UInt, + val operationalStateID: UByte, val operationalStateLabel: Optional ) { override fun toString(): String = buildString { @@ -55,7 +55,7 @@ class OvenCavityOperationalStateClusterOperationalStateStruct( tlvReader: TlvReader ): OvenCavityOperationalStateClusterOperationalStateStruct { tlvReader.enterStructure(tlvTag) - val operationalStateID = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATIONAL_STATE_I_D)) + val operationalStateID = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATIONAL_STATE_I_D)) val operationalStateLabel = if (tlvReader.isNextTag(ContextSpecificTag(TAG_OPERATIONAL_STATE_LABEL))) { Optional.of(tlvReader.getString(ContextSpecificTag(TAG_OPERATIONAL_STATE_LABEL))) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenModeClusterModeTagStruct.kt index f957f7073fa77a..debd205eba661d 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/OvenModeClusterModeTagStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class OvenModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { +class OvenModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { override fun toString(): String = buildString { append("OvenModeClusterModeTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -55,7 +55,7 @@ class OvenModeClusterModeTagStruct(val mfgCode: Optional, val value: UIn } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatChargeFaultChangeType.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatChargeFaultChangeType.kt index b052cd4bd801ed..72d0b3b199bb1e 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatChargeFaultChangeType.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatChargeFaultChangeType.kt @@ -24,8 +24,8 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class PowerSourceClusterBatChargeFaultChangeType( - val current: List, - val previous: List + val current: List, + val previous: List ) { override fun toString(): String = buildString { append("PowerSourceClusterBatChargeFaultChangeType {\n") @@ -58,18 +58,18 @@ class PowerSourceClusterBatChargeFaultChangeType( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): PowerSourceClusterBatChargeFaultChangeType { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatFaultChangeType.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatFaultChangeType.kt index e6ed2093eea21a..3afee70ed3d114 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatFaultChangeType.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterBatFaultChangeType.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class PowerSourceClusterBatFaultChangeType(val current: List, val previous: List) { +class PowerSourceClusterBatFaultChangeType(val current: List, val previous: List) { override fun toString(): String = buildString { append("PowerSourceClusterBatFaultChangeType {\n") append("\tcurrent : $current\n") @@ -55,18 +55,18 @@ class PowerSourceClusterBatFaultChangeType(val current: List, val previous fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): PowerSourceClusterBatFaultChangeType { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterWiredFaultChangeType.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterWiredFaultChangeType.kt index e2849017a263c9..c86eb436270883 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterWiredFaultChangeType.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/PowerSourceClusterWiredFaultChangeType.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class PowerSourceClusterWiredFaultChangeType(val current: List, val previous: List) { +class PowerSourceClusterWiredFaultChangeType(val current: List, val previous: List) { override fun toString(): String = buildString { append("PowerSourceClusterWiredFaultChangeType {\n") append("\tcurrent : $current\n") @@ -55,18 +55,18 @@ class PowerSourceClusterWiredFaultChangeType(val current: List, val previo fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): PowerSourceClusterWiredFaultChangeType { tlvReader.enterStructure(tlvTag) val current = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_CURRENT)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } val previous = - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_PREVIOUS)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct.kt index 66ac75104984a2..848b34bdf5c266 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct( val mfgCode: Optional, - val value: UInt + val value: UShort ) { override fun toString(): String = buildString { append("RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct {\n") @@ -61,7 +61,7 @@ class RefrigeratorAndTemperatureControlledCabinetModeClusterModeTagStruct( } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcCleanModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcCleanModeClusterModeTagStruct.kt index b6670bdcd7b955..17f618ec21b03f 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcCleanModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcCleanModeClusterModeTagStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class RvcCleanModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { +class RvcCleanModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { override fun toString(): String = buildString { append("RvcCleanModeClusterModeTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -55,7 +55,7 @@ class RvcCleanModeClusterModeTagStruct(val mfgCode: Optional, val value: } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterErrorStateStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterErrorStateStruct.kt index 4907820103b662..e15763269e6b40 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterErrorStateStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterErrorStateStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class RvcOperationalStateClusterErrorStateStruct( - val errorStateID: UInt, + val errorStateID: UByte, val errorStateLabel: Optional, val errorStateDetails: Optional ) { @@ -59,7 +59,7 @@ class RvcOperationalStateClusterErrorStateStruct( fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): RvcOperationalStateClusterErrorStateStruct { tlvReader.enterStructure(tlvTag) - val errorStateID = tlvReader.getUInt(ContextSpecificTag(TAG_ERROR_STATE_I_D)) + val errorStateID = tlvReader.getUByte(ContextSpecificTag(TAG_ERROR_STATE_I_D)) val errorStateLabel = if (tlvReader.isNextTag(ContextSpecificTag(TAG_ERROR_STATE_LABEL))) { Optional.of(tlvReader.getString(ContextSpecificTag(TAG_ERROR_STATE_LABEL))) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterOperationalStateStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterOperationalStateStruct.kt index 1e5548ff7677a9..903605a498ab74 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterOperationalStateStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcOperationalStateClusterOperationalStateStruct.kt @@ -24,7 +24,7 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class RvcOperationalStateClusterOperationalStateStruct( - val operationalStateID: UInt, + val operationalStateID: UByte, val operationalStateLabel: Optional ) { override fun toString(): String = buildString { @@ -55,7 +55,7 @@ class RvcOperationalStateClusterOperationalStateStruct( tlvReader: TlvReader ): RvcOperationalStateClusterOperationalStateStruct { tlvReader.enterStructure(tlvTag) - val operationalStateID = tlvReader.getUInt(ContextSpecificTag(TAG_OPERATIONAL_STATE_I_D)) + val operationalStateID = tlvReader.getUByte(ContextSpecificTag(TAG_OPERATIONAL_STATE_I_D)) val operationalStateLabel = if (tlvReader.isNextTag(ContextSpecificTag(TAG_OPERATIONAL_STATE_LABEL))) { Optional.of(tlvReader.getString(ContextSpecificTag(TAG_OPERATIONAL_STATE_LABEL))) diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcRunModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcRunModeClusterModeTagStruct.kt index 055336e7a1e250..188c215beb4f69 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcRunModeClusterModeTagStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/RvcRunModeClusterModeTagStruct.kt @@ -23,7 +23,7 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class RvcRunModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { +class RvcRunModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { override fun toString(): String = buildString { append("RvcRunModeClusterModeTagStruct {\n") append("\tmfgCode : $mfgCode\n") @@ -55,7 +55,7 @@ class RvcRunModeClusterModeTagStruct(val mfgCode: Optional, val value: U } else { Optional.empty() } - val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt index 5098411f07e58d..3507426f426404 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt @@ -34,9 +34,9 @@ class UnitTestingClusterNullablesAndOptionalsStruct( val nullableStruct: UnitTestingClusterSimpleStruct?, val optionalStruct: Optional, val nullableOptionalStruct: Optional?, - val nullableList: List?, - val optionalList: Optional>, - val nullableOptionalList: Optional>? + val nullableList: List?, + val optionalList: Optional>, + val nullableOptionalList: Optional>? ) { override fun toString(): String = buildString { append("UnitTestingClusterNullablesAndOptionalsStruct {\n") @@ -242,10 +242,10 @@ class UnitTestingClusterNullablesAndOptionalsStruct( } val nullableList = if (!tlvReader.isNull()) { - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_NULLABLE_LIST)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } @@ -256,10 +256,10 @@ class UnitTestingClusterNullablesAndOptionalsStruct( val optionalList = if (tlvReader.isNextTag(ContextSpecificTag(TAG_OPTIONAL_LIST))) { Optional.of( - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_OPTIONAL_LIST)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } @@ -271,10 +271,10 @@ class UnitTestingClusterNullablesAndOptionalsStruct( if (!tlvReader.isNull()) { if (tlvReader.isNextTag(ContextSpecificTag(TAG_NULLABLE_OPTIONAL_LIST))) { Optional.of( - buildList { + buildList { tlvReader.enterArray(ContextSpecificTag(TAG_NULLABLE_OPTIONAL_LIST)) while (!tlvReader.isEndOfContainer()) { - add(tlvReader.getUInt(AnonymousTag)) + add(tlvReader.getUByte(AnonymousTag)) } tlvReader.exitContainer() } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt index 4c1dfe9e93b76e..aba051d40f9516 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt @@ -25,10 +25,10 @@ import matter.tlv.TlvWriter class UnitTestingClusterSimpleStruct( val a: UByte, val b: Boolean, - val c: UInt, + val c: UByte, val d: ByteArray, val e: String, - val f: UInt, + val f: UByte, val g: Float, val h: Double ) { @@ -74,10 +74,10 @@ class UnitTestingClusterSimpleStruct( tlvReader.enterStructure(tlvTag) val a = tlvReader.getUByte(ContextSpecificTag(TAG_A)) val b = tlvReader.getBoolean(ContextSpecificTag(TAG_B)) - val c = tlvReader.getUInt(ContextSpecificTag(TAG_C)) + val c = tlvReader.getUByte(ContextSpecificTag(TAG_C)) val d = tlvReader.getByteArray(ContextSpecificTag(TAG_D)) val e = tlvReader.getString(ContextSpecificTag(TAG_E)) - val f = tlvReader.getUInt(ContextSpecificTag(TAG_F)) + val f = tlvReader.getUByte(ContextSpecificTag(TAG_F)) val g = tlvReader.getFloat(ContextSpecificTag(TAG_G)) val h = tlvReader.getDouble(ContextSpecificTag(TAG_H))