تتيح واجهات برمجة التطبيقات لمنزل Google استخدام السمات الخاصة بالشركة المصنّعة (MS) في
Android، ويُشار إليها باسم السمات الخاصة بالشركة المصنّعة
في واجهات برمجة التطبيقات لأنّها تتيح وظائف إضافية تتجاوز السمات
العادية في Android. يجب تحديدها بتنسيق .matter IDL العادي، ثم تحويلها إلى حزمة Android يمكن استيرادها إلى تطبيقك.
استخدِم أداة إنشاء الرموز البرمجية المجمّعة التي توفّرها Google لإجراء هذا التحويل. بالإضافة إلى ذلك، إذا لزم الأمر، يمكن أيضًا إنشاء سمات مؤقتة باستخدام منشئ الرموز.
المتطلبات الأساسية
لاستخدام أداة إنشاء الرموز، يجب توفّر ما يلي:
- جهاز يعمل بنظام التشغيل Linux ومزوّد بالإصدار 3.10 من Python أو إصدار أحدث
- ملف
.matterIDL يتضمّن تعريف سمات MS يجب أن يحتوي هذا الملف على تعريفاتclient clusterفقط. يمكنك إنشاء مفتاح يدويًا أو استخدام المفاتيح التي تم إنشاؤها كجزء من Matter عملية إنشاء حزمة تطوير البرامج (SDK) لنظام التشغيل الثابت في جهازك.
لمزيد من المعلومات حول تنسيق IDL، يُرجى الاطّلاع على matter/idl على GitHub. يحتوي الدليل /tests/inputs على عدد من نماذج ملفات IDL.
إنشاء حزمة
احصل على منشئ الرموز البرمجية المجمّع:
تنزيل أداة إنشاء الرموز البرمجية المجمّعة
- اختَر اسم حزمة Java لإنشاء رمز السمة فيها. على سبيل المثال:
com.mycompany.matter.cluster. يجب أن يتطابق هذا الاسم مع معرّف تطبيقك. لمزيد من المعلومات حول اصطلاحات تسمية الحِزم، يُرجى الاطّلاع على أسماء الحِزم. - استخرِج الملفات واضبط إعدادات أداة الإنشاء:
mkdir -p ~/tmp/codegencd ~/tmp/codegentar xfvz ~/tmp/matter_codegen.tar.gzcd matter_codegen/matter_codegenpython3 -m venv .venv.venv/bin/pip install . - شغِّل أداة الإنشاء:
.venv/bin/python3 google_home_codegen.py \ --lang kotlin \ --output-dir ./generated/com/mycompany/matter/cluster \ --option package:com.mycompany.matter.cluster \ custom-cluster-idl.matter
ملاحظة حول خيارات إنشاء الرموز البرمجية
بدلاً من توفير الخيارات كـ --option key:value في سطر الأوامر، يمكنك
تحديد خيارات إنشاء الرموز في تعليقات pragma في أعلى ملف IDL.
على سبيل المثال:
// pragma kotlin(package=com.mycompany.matter.cluster, generate_namespace=true)
// pragma swift(package=MyCompany, generate_namespace=true)
client cluster SimpleCustom = 4294048768 {
attribute int16u clusterAttr = 1;
// Global Attributes
readonly attribute command_id generatedCommandList[] = 65528;
readonly attribute command_id acceptedCommandList[] = 65529;
readonly attribute event_id eventList[] = 65530;
readonly attribute attrib_id attributeList[] = 65531;
readonly attribute bitmap32 featureMap = 65532;
readonly attribute int16u clusterRevision = 65533;
}
استخدام الحزمة
لاستخدام حزمة سمات MS، عليك استيرادها إلى تطبيقك:
import <var>com.mycompany.matter.cluster</var>
بعد ذلك، من المفترض أن تصبح سمات MS متاحة من خلال Home APIs بالطريقة نفسها التي تتوفر بها سمات Matter العادية، طالما أنّ سمات MS هذه محدّدة في البرامج الثابتة لـ Matter. ما عليك سوى استبدال اسم السمة العادية باسم سمة MS.
على سبيل المثال، إذا كانت سمة MS تحمل الاسم CustomTrait، فإنّ الطلب التالي
يعرض جميع سمات CustomTrait:
val device = devices().get(id)?
val deviceType = devices().get(id)?.type?.value
val trait = device?.type(deviceType)?.map{it.trait(CustomTrait)}.firstOrNull()
التبعيات الإضافية
بالنسبة إلى التطبيقات التي تستخدم سمات MS للتجميع، قد تحتاج أيضًا إلى إضافة التبعيات التالية إلى ملف build.gradle الخاص بتطبيقك:
implementation 'com.google.errorprone:error_prone_annotations:2.35.1'
مثال
إذا لم تكن على دراية بتنسيق IDL، يمكنك الاطّلاع على أدلة matter/idl/tests/inputs للحصول على نماذج من الملفات.
إدخال IDL
يمكن تحديد سمة MS بسيطة جدًا في IDL على النحو التالي:
// mycustom.matter
// pragma kotlin(package=com.mycompany.matter.cluster, generate_namespace=true)
// pragma swift(package=MyCompany, generate_namespace=true)
client cluster MyCustom = 4294048768 {
attribute int16u clusterAttr = 1;
// Global Attributes
readonly attribute command_id generatedCommandList[] = 65528;
readonly attribute command_id acceptedCommandList[] = 65529;
readonly attribute event_id eventList[] = 65530;
readonly attribute attrib_id attributeList[] = 65531;
readonly attribute bitmap32 featureMap = 65532;
readonly attribute int16u clusterRevision = 65533;
}
في هذا المثال، يتوافق معرّف السمة 4294048768 مع 0xFFF1FC00 في نظام العد الستة عشري، حيث تمثّل البادئة 0xFFF1 معرّف مورّد اختباري واللاحقة 0xFC00 هي قيمة محجوزة للسمات الخاصة بالشركة المصنّعة. يُرجى الاطّلاع على قسم المعرّف القابل للتوسيع للشركة المصنّعة (MEI) في مواصفات Matter للحصول على مزيد من المعلومات. احرص على استخدام معرّف سمة عشري مناسب لكل سمة MS في ملف IDL.
إذا كانت سمات MS مستخدمة في جهازك اليوم، فمن المحتمل أن تكون قد حددتها بهذا التنسيق بالفعل.
تشغيل منشئ الرموز
بعد وضع ملف mycustom.matter في الدليل نفسه الذي يحتوي على أداة إنشاء الرموز، شغِّل
الأداة:
google_home_codegen.py \
--lang kotlin \
--output-dir ./generated/com/mycompany/matter/cluster \
mycustom.matter2024-09-03 19:00:09 INFO Parsing idl from mycustom.matter 2024-09-03 19:00:09 INFO Using CustomGenerator at plugin path ..kotlin 2024-09-03 19:00:09 INFO Running code generator CUSTOM 2024-09-03 19:00:10 INFO File to be generated: MyCustomTrait.kt 2024-09-03 19:00:10 INFO Template path: ClusterSerialization.kt.jinja, CWD: /usr/local/google/home/username/codegen 2024-09-03 19:00:11 INFO Creating output directory: ./generated/com/mycompany/matter/cluster 2024-09-03 19:00:11 INFO Writing new data to: ./generated/com/mycompany/matter/cluster/MyCustomTrait.kt 2024-09-03 19:00:11 INFO File to be generated: MyCustom.kt 2024-09-03 19:00:11 INFO Template path: Cluster.kt.jinja, CWD: /usr/local/google/home/username/codegen 2024-09-03 19:00:11 INFO Writing new data to: ./generated/com/mycompany/matter/cluster/MyCustom.kt 2024-09-03 19:00:11 INFO Done
ناتج Kotlin
يمكن الآن العثور على ملفَّي Kotlin، MyCustom.kt وMyCustomTrait.kt، في دليل الإخراج المحدّد. تم تنسيق هذه الملفات خصيصًا للاستخدام مع واجهات برمجة التطبيقات Home API.
بعد توفّرها (مثلاً في مشروع Android Studio الخاص بتطبيقك)، يمكن استخدامها كما هو موضّح في قسم استخدام الحزمة.
MyCustom.kt
// This file contains machine-generated code.
@file:Suppress("PackageName")
package com.mycompany.matter.cluster
import com.google.home.ClusterStruct
import com.google.home.Descriptor as HomeDescriptor
import com.google.home.DescriptorMap
import com.google.home.Field
import com.google.home.Id
import com.google.home.NoOpDescriptor
import com.google.home.StructDescriptor
import com.google.home.Trait
import com.google.home.TraitFactory
import com.google.home.Type as FieldType
import com.google.home.Updatable
import com.google.home.automation.Attribute as AutomationAttribute
import com.google.home.automation.AttributeToUpdate
import com.google.home.automation.TypedExpression
import com.google.home.automation.Updater
import com.google.home.automation.fieldSelect
import com.google.home.matter.MatterTrait
import com.google.home.matter.MatterTraitClient
import com.google.home.matter.MatterTraitFactory
import com.google.home.matter.MatterTraitImpl
import com.google.home.matter.serialization.BitmapAdapter
import com.google.home.matter.serialization.EnumAdapter
import com.google.home.toDescriptorMap
import com.mycompany.matter.cluster.MyCustomTrait.Attributes
import com.mycompany.matter.cluster.MyCustomTrait.AttributesImpl
import com.mycompany.matter.cluster.MyCustomTrait.Feature
import com.mycompany.matter.cluster.MyCustomTrait.MutableAttributes
import javax.annotation.processing.Generated
/*
* This file was machine generated via the code generator
* in `codegen.clusters.kotlin.CustomGenerator`
*
*/
/**
* @suppress
*
* Commands for the MyCustom trait.
*/
/** API for the MyCustom trait. */
@Generated("GoogleHomePlatformCodegen")
interface MyCustom : Attributes, MatterTrait, Updatable<MyCustom, MutableAttributes> {
/** Descriptor enum for this trait's attributes. */
enum class Attribute(
override val fieldName: String,
override val tag: UInt,
override val typeName: String,
override val typeEnum: FieldType,
override val isList: Boolean,
override val descriptor: HomeDescriptor,
val isNullable: Boolean,
) : Field {
/** The [clusterAttr][MyCustomTrait.Attributes.clusterAttr] trait attribute. */
clusterAttr("clusterAttr", 1u, "UShort", FieldType.UShort, false, NoOpDescriptor, false),
/**
* The [generatedCommandList][MyCustomTrait.Attributes.generatedCommandList] trait attribute.
*/
generatedCommandList(
"generatedCommandList",
65528u,
"UInt",
FieldType.UInt,
false,
NoOpDescriptor,
false,
),
/** The [acceptedCommandList][MyCustomTrait.Attributes.acceptedCommandList] trait attribute. */
acceptedCommandList(
"acceptedCommandList",
65529u,
"UInt",
FieldType.UInt,
false,
NoOpDescriptor,
false,
),
/** The [attributeList][MyCustomTrait.Attributes.attributeList] trait attribute. */
attributeList("attributeList", 65531u, "UInt", FieldType.UInt, false, NoOpDescriptor, false),
/** The [featureMap][MyCustomTrait.Attributes.featureMap] trait attribute. */
featureMap(
"featureMap",
65532u,
"Feature",
FieldType.Bitmap,
false,
Feature.BitmapDescriptor,
false,
),
/** The [clusterRevision][MyCustomTrait.Attributes.clusterRevision] trait attribute. */
clusterRevision(
"clusterRevision",
65533u,
"UShort",
FieldType.UShort,
false,
NoOpDescriptor,
false,
);
companion object {
val StructDescriptor =
object : StructDescriptor {
@Suppress("Immutable") override val fields: DescriptorMap = entries.toDescriptorMap()
override fun toStruct(fields: Map<Field, Any?>): ClusterStruct {
return AttributesImpl(
clusterAttr = fields[clusterAttr] as UShort?,
generatedCommandList = fields[generatedCommandList] as List<UInt>,
acceptedCommandList = fields[acceptedCommandList] as List<UInt>,
attributeList = fields[attributeList] as List<UInt>,
featureMap = fields[featureMap] as Feature,
clusterRevision = fields[clusterRevision] as UShort,
)
}
}
}
}
fun supports(attribute: Attribute): Boolean
/** @suppress */
companion object :
TraitFactory<MyCustom>(
MatterTraitFactory(
clusterId = MyCustomTrait.Id,
adapter = Attributes.Adapter,
traitDescriptor = Attribute.StructDescriptor,
// Map of enum type name string -> EnumAdapter
enumAdapters = mapOf<String, EnumAdapter<*>>(),
bitmapAdapters =
mapOf<String, BitmapAdapter<*>>("Feature" to MyCustomTrait.Feature.Adapter),
creator = ::MyCustomImpl,
supportedEvents = mapOf(),
// All Trait Commands
commands = mapOf(),
)
) {
val clusterAttr: AutomationAttribute<UShort?>
get() =
AutomationAttribute<UShort?>(MyCustomTrait.Id.traitId, MyCustom.Attribute.clusterAttr.tag)
val generatedCommandList: AutomationAttribute<List<UInt>>
get() =
AutomationAttribute<List<UInt>>(
MyCustomTrait.Id.traitId,
MyCustom.Attribute.generatedCommandList.tag,
)
val acceptedCommandList: AutomationAttribute<List<UInt>>
get() =
AutomationAttribute<List<UInt>>(
MyCustomTrait.Id.traitId,
MyCustom.Attribute.acceptedCommandList.tag,
)
val attributeList: AutomationAttribute<List<UInt>>
get() =
AutomationAttribute<List<UInt>>(
MyCustomTrait.Id.traitId,
MyCustom.Attribute.attributeList.tag,
)
val featureMap: AutomationAttribute<Feature>
get() =
AutomationAttribute<Feature>(MyCustomTrait.Id.traitId, MyCustom.Attribute.featureMap.tag)
val clusterRevision: AutomationAttribute<UShort>
get() =
AutomationAttribute<UShort>(
MyCustomTrait.Id.traitId,
MyCustom.Attribute.clusterRevision.tag,
)
val TypedExpression<out MyCustom?>.clusterAttr: TypedExpression<UShort?>
get() = fieldSelect<MyCustom, UShort?>(this, MyCustom.Attribute.clusterAttr)
val TypedExpression<out MyCustom?>.generatedCommandList: TypedExpression<List<UInt>>
get() = fieldSelect<MyCustom, List<UInt>>(this, MyCustom.Attribute.generatedCommandList)
val TypedExpression<out MyCustom?>.acceptedCommandList: TypedExpression<List<UInt>>
get() = fieldSelect<MyCustom, List<UInt>>(this, MyCustom.Attribute.acceptedCommandList)
val TypedExpression<out MyCustom?>.attributeList: TypedExpression<List<UInt>>
get() = fieldSelect<MyCustom, List<UInt>>(this, MyCustom.Attribute.attributeList)
val TypedExpression<out MyCustom?>.featureMap: TypedExpression<Feature>
get() = fieldSelect<MyCustom, Feature>(this, MyCustom.Attribute.featureMap)
val TypedExpression<out MyCustom?>.clusterRevision: TypedExpression<UShort>
get() = fieldSelect<MyCustom, UShort>(this, MyCustom.Attribute.clusterRevision)
fun Updater<MyCustom>.setClusterAttr(value: UShort) {
attributesToUpdate.add(AttributeToUpdate(Attribute.clusterAttr, value))
}
override fun getAttributeById(tagId: UInt): Field? {
return Attribute.values().firstOrNull { it.tag == tagId }
}
override fun getAttributeByName(name: String): Field? {
return Attribute.values().firstOrNull { it.name == name }
}
override fun toString() = "MyCustom"
}
override val factory: TraitFactory<MyCustom>
get() = Companion
}
/** @suppress */
class MyCustomImpl
constructor(
override val metadata: Trait.TraitMetadata,
client: MatterTraitClient,
internal val attributes: Attributes,
) :
MyCustom,
MatterTraitImpl(metadata, client),
Attributes by attributes,
Updatable<MyCustom, MutableAttributes> {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is MyCustomImpl) return false
if (metadata != other.metadata) return false
if (attributes != other.attributes) return false
return true
}
/**
* Checks if the trait supports an attribute. Some devices might not implement all attributes in a
* Trait definition.
*
* @param attribute The attribute to check for.
* @return True if the attribute is supported by the trait, false if it is not.
*/
override fun supports(attribute: MyCustom.Attribute) =
attributes.attributeList.contains(attribute.tag)
// Commands
/** @suppress */
override suspend fun update(
optimisticReturn: (MyCustom) -> Unit,
init: MutableAttributes.() -> Unit,
): MyCustom {
val newVal = MutableAttributes(attributes).apply(init)
val returnVal = MyCustomImpl(metadata, client, newVal)
optimisticReturn(returnVal)
write(MutableAttributes, newVal, useTimedInteraction = false)
return returnVal
}
override fun toString() = attributes.toString()
}
MyCustomTrait.kt
// This file contains machine-generated code.
@file:Suppress("PackageName")
package com.mycompany.matter.cluster
import com.google.home.BitmapDescriptor
import com.google.home.ClusterStruct
import com.google.home.EnumEntry
import com.google.home.HomeException
import com.google.home.StructDescriptor
import com.google.home.TagId
import com.google.home.matter.serialization.Bitmap
import com.google.home.matter.serialization.BitmapAdapter
import com.google.home.matter.serialization.CanMutate
import com.google.home.matter.serialization.ClusterBitmap
import com.google.home.matter.serialization.ClusterId
import com.google.home.matter.serialization.ClusterPayloadReader
import com.google.home.matter.serialization.ClusterPayloadWriter
import com.google.home.matter.serialization.MutableBitmap
import com.google.home.matter.serialization.StructAdapter
import com.google.home.matter.serialization.unwrapPayload
import com.google.home.matter.serialization.wrapPayload
import javax.annotation.processing.Generated
/*
* Serialization object for MyCustomTrait.
*
* This file was machine generate via the code generator
* in `codegen.clusters.kotlin.CustomGenerator`
*
*/
/** Attributes for MyCustomTrait. */
@Generated("GoogleHomePlatformCodegen")
object MyCustomTrait {
val Id = ClusterId(4294048768u, "MyCustom")
// Enums
// Bitmaps
class Feature : ClusterBitmap(traitId = ClusterId(4294048768u).traitId, bitmapName = "Feature") {
override fun toRaw(): ULong = 0u
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Feature) return false
return true
}
override fun hashCode(): Int {
return 1
}
override fun toString(): String {
return "Feature()"
}
/** @suppress */
companion object {
val Adapter =
object : BitmapAdapter<Feature> {
override fun toRaw(value: Feature): Bitmap = MutableBitmap()
override fun toRuntime(value: Bitmap): Feature = Feature()
}
val BitmapDescriptor =
object : BitmapDescriptor {
override val name: String = "Feature"
@Suppress("Immutable") override val values: Map<ULong, EnumEntry> = emptyMap()
}
}
}
// Events
// Structs
/** Attributes for the MyCustom cluster. */
@Generated("GoogleHomePlatformCodegen")
interface Attributes : ClusterStruct {
val clusterAttr: UShort?
/**
* A list of server-generated commands (server to client) which are supported by this cluster
* server instance.
*/
val generatedCommandList: List<UInt>
/** A list of client-generated commands which are supported by this cluster server instance. */
val acceptedCommandList: List<UInt>
/** A list of the attribute IDs of the attributes supported by the cluster instance. */
val attributeList: List<UInt>
/**
* Whether the server supports zero or more optional cluster features. A cluster feature is a
* set of cluster elements that are mandatory or optional for a defined feature of the cluster.
* If a cluster feature is supported by the cluster instance, then the corresponding bit is set
* to 1, otherwise the bit is set to 0 (zero).
*/
val featureMap: Feature
/** The revision of the server cluster specification supported by the cluster instance. */
val clusterRevision: UShort
override fun getDescriptor(): StructDescriptor = MyCustom.Attribute.StructDescriptor
override fun getFieldValueById(tagId: TagId): Any? {
return when (tagId) {
MyCustom.Attribute.clusterAttr.tag -> clusterAttr
MyCustom.Attribute.generatedCommandList.tag -> generatedCommandList
MyCustom.Attribute.acceptedCommandList.tag -> acceptedCommandList
MyCustom.Attribute.attributeList.tag -> attributeList
MyCustom.Attribute.featureMap.tag -> featureMap
MyCustom.Attribute.clusterRevision.tag -> clusterRevision
else -> null
}
}
/** @suppress */
companion object Adapter : StructAdapter<Attributes> {
override fun write(writer: ClusterPayloadWriter, value: Attributes) {
if (value is MutableAttributes) {
MutableAttributes.Adapter.write(writer, value)
return
}
writer.wrapPayload(id = Id)
if (!writer.strictOperationValidation || value.attributeList.contains(1u)) {
writer.ushort.write(1u, value.clusterAttr)
}
writer.uint.writeList(65528u, value.generatedCommandList)
writer.uint.writeList(65529u, value.acceptedCommandList)
writer.uint.writeList(65531u, value.attributeList)
writer.bitmap(Feature.Adapter).write(65532u, value.featureMap)
writer.ushort.write(65533u, value.clusterRevision)
}
override fun read(reader: ClusterPayloadReader): Attributes {
reader.unwrapPayload(id = Id)
val data = reader.readPayload()
val attributeList = mutableListOf<UInt>()
return AttributesImpl(
data.ushort
.getOptionalNullable(1u, "ClusterAttr")
.also { if (it.isPresent && it.value != null) attributeList.add(1u) }
.getOrNull(),
data.uint.getList(65528u, "GeneratedCommandList").also { attributeList.add(65528u) },
data.uint.getList(65529u, "AcceptedCommandList").also { attributeList.add(65529u) },
attributeList.also { attributeList.add(65531u) },
data.bitmap(Feature.Adapter).get(65532u, "FeatureMap").also { attributeList.add(65532u) },
data.ushort.get(65533u, "ClusterRevision").also { attributeList.add(65533u) },
)
}
}
}
/** @suppress */
open class AttributesImpl(
override val clusterAttr: UShort? = null,
override val generatedCommandList: List<UInt> = emptyList(),
override val acceptedCommandList: List<UInt> = emptyList(),
override val attributeList: List<UInt> = listOf(1u, 65528u, 65529u, 65531u, 65532u, 65533u),
override val featureMap: Feature = Feature(),
override val clusterRevision: UShort = 0u,
) : Attributes, CanMutate<Attributes, MutableAttributes> {
constructor(
other: Attributes
) : this(
clusterAttr = other.clusterAttr,
generatedCommandList = other.generatedCommandList,
acceptedCommandList = other.acceptedCommandList,
attributeList = other.attributeList,
featureMap = other.featureMap,
clusterRevision = other.clusterRevision,
)
override fun mutate(init: MutableAttributes.() -> Unit): Attributes =
AttributesImpl(MutableAttributes(this).apply(init))
companion object {
val Adapter = Attributes.Adapter
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Attributes) return false
if (clusterAttr != other.clusterAttr) {
return false
}
if (generatedCommandList != other.generatedCommandList) {
return false
}
if (acceptedCommandList != other.acceptedCommandList) {
return false
}
if (attributeList != other.attributeList) {
return false
}
if (featureMap != other.featureMap) {
return false
}
if (clusterRevision != other.clusterRevision) {
return false
}
return true
}
override fun hashCode(): Int {
var result = 1
result = 31 * result + (clusterAttr?.hashCode() ?: 0)
result = 31 * result + generatedCommandList.hashCode()
result = 31 * result + acceptedCommandList.hashCode()
result = 31 * result + attributeList.hashCode()
result = 31 * result + featureMap.hashCode()
result = 31 * result + clusterRevision.hashCode()
return result
}
override fun toString(): String {
return "MyCustom(clusterAttr=$clusterAttr, generatedCommandList=$generatedCommandList, acceptedCommandList=$acceptedCommandList, attributeList=$attributeList, featureMap=$featureMap, clusterRevision=$clusterRevision)"
}
fun copy(
clusterAttr: UShort? = this.clusterAttr,
generatedCommandList: List<UInt> = this.generatedCommandList,
acceptedCommandList: List<UInt> = this.acceptedCommandList,
attributeList: List<UInt> = this.attributeList,
featureMap: Feature = this.featureMap,
clusterRevision: UShort = this.clusterRevision,
) =
AttributesImpl(
clusterAttr = clusterAttr,
generatedCommandList = generatedCommandList,
acceptedCommandList = acceptedCommandList,
attributeList = attributeList,
featureMap = featureMap,
clusterRevision = clusterRevision,
)
}
/** @suppress */
class MutableAttributes(attributes: Attributes) :
AttributesImpl(
clusterAttr = attributes.clusterAttr,
generatedCommandList = attributes.generatedCommandList,
acceptedCommandList = attributes.acceptedCommandList,
attributeList = attributes.attributeList,
featureMap = attributes.featureMap,
clusterRevision = attributes.clusterRevision,
) {
internal var _clusterAttr: UShort? = null
override val clusterAttr: UShort?
get() {
return _clusterAttr ?: super.clusterAttr
}
fun setClusterAttr(value: UShort) {
_clusterAttr = value
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is MutableAttributes) return false
return super.equals(other)
}
override fun toString(): String {
return "MyCustom.MutableAttributes(${super.toString()})"
}
companion object Adapter : StructAdapter<MutableAttributes> {
override fun write(writer: ClusterPayloadWriter, value: MutableAttributes) {
writer.wrapPayload(id = Id)
if (value._clusterAttr != null) {
if (!writer.strictOperationValidation || value.attributeList.contains(1u)) {
writer.ushort.write(1u, value._clusterAttr)
} else {
throw HomeException.invalidArgument("clusterAttr")
}
}
}
override fun read(reader: ClusterPayloadReader): MutableAttributes =
MutableAttributes(Attributes.Adapter.read(reader))
}
}
// Commands
}