diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index e2dbd5f707334a..21e59ee10dd87f 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -202,6 +202,7 @@ jobs:
src/app/zap-templates/zcl/data-model/chip/sample-mei-cluster.xml \
src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml \
src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml \
+ src/app/zap-templates/zcl/data-model/chip/meter-identification-cluster.xml \
"
- name: Build Apps
run: |
diff --git a/data_model/clusters/MeterIdentification.xml b/data_model/clusters/MeterIdentification.xml
new file mode 100644
index 00000000000000..87f1589234ae40
--- /dev/null
+++ b/data_model/clusters/MeterIdentification.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md
index 9033fff4101de9..e14c868462c97c 100644
--- a/docs/zap_clusters.md
+++ b/docs/zap_clusters.md
@@ -129,6 +129,7 @@ Generally regenerate using one of:
| 1294 | 0x50E | AccountLogin |
| 1295 | 0x50F | ContentControl |
| 1296 | 0x510 | ContentAppObserver |
+| 2817 | 0xB01 | MeterIdentification |
| 2820 | 0xB04 | ElectricalMeasurement |
| 4294048773 | 0xFFF1FC05 | UnitTesting |
| 4294048774 | 0xFFF1FC06 | FaultInjection |
diff --git a/examples/all-clusters-app/all-clusters-common/src/meter-identification-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/meter-identification-stub.cpp
new file mode 100644
index 00000000000000..2dd49c1c82de37
--- /dev/null
+++ b/examples/all-clusters-app/all-clusters-common/src/meter-identification-stub.cpp
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+
+using namespace chip;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::MeterIdentification;
+using Feature = chip::app::Clusters::MeterIdentification::Feature;
+
+static std::unique_ptr gMIDelegate;
+static std::unique_ptr gMIInstance;
+
+void emberAfMeterIdentificationClusterInitCallback(chip::EndpointId endpointId)
+{
+ VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1.
+ VerifyOrDie(!gMIInstance);
+
+ gMIDelegate = std::make_unique();
+ if (gMIDelegate)
+ {
+ gMIInstance = std::make_unique(endpointId, *gMIDelegate,
+ BitMask(Feature::kPowerThreshold));
+
+ gMIInstance->Init();
+ }
+}
diff --git a/examples/energy-management-app/energy-management-common/include/MeterIdentificationDelegate.h b/examples/energy-management-app/energy-management-common/include/MeterIdentificationDelegate.h
new file mode 100644
index 00000000000000..2ace7835fd7e7b
--- /dev/null
+++ b/examples/energy-management-app/energy-management-common/include/MeterIdentificationDelegate.h
@@ -0,0 +1,88 @@
+/*
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include
+#include
+#include
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace MeterIdentification {
+
+class MeterIdentificationDelegate : public MeterIdentification::Delegate
+{
+public:
+ ~MeterIdentificationDelegate() = default;
+
+ // Attribute Accessors
+
+ DataModel::Nullable GetMeterType() override { return mMeterType; };
+ CharSpan GetCustomerName() override { return mCustomerName; };
+ CharSpan GetUtilityName() override { return mUtilityName; };
+ CharSpan GetPointOfDelivery() override { return mPointOfDelivery; };
+ DataModel::Nullable GetPowerThreshold() override { return mPowerThreshold; };
+ DataModel::Nullable GetPowerThresholdSource() override { return mPowerThresholdSource; };
+
+ CHIP_ERROR SetCustomerName(CharSpan & value) override;
+
+ // Internal Application API to set attribute values
+ CHIP_ERROR SetMeterType(DataModel::Nullable);
+ CHIP_ERROR SetUtilityName(CharSpan & value);
+ CHIP_ERROR SetPointOfDelivery(CharSpan & value);
+ CHIP_ERROR SetPowerThreshold(DataModel::Nullable);
+ CHIP_ERROR SetPowerThresholdSource(DataModel::Nullable);
+
+private:
+ // Attribute storage
+ DataModel::Nullable mMeterType;
+ CharSpan mCustomerName;
+ CharSpan mUtilityName;
+ CharSpan mPointOfDelivery;
+ DataModel::Nullable mPowerThreshold;
+ DataModel::Nullable mPowerThresholdSource;
+};
+
+class MeterIdentificationInstance : public Instance
+{
+public:
+ MeterIdentificationInstance(EndpointId aEndpointId, MeterIdentificationDelegate & aDelegate, Feature aFeature) :
+ MeterIdentification::Instance(aEndpointId, aDelegate, aFeature)
+ {
+ mDelegate = &aDelegate;
+ }
+
+ // Delete copy constructor and assignment operator.
+ MeterIdentificationInstance(const MeterIdentificationInstance &) = delete;
+ MeterIdentificationInstance(const MeterIdentificationInstance &&) = delete;
+ MeterIdentificationInstance & operator=(const MeterIdentificationInstance &) = delete;
+
+ CHIP_ERROR Init();
+ void Shutdown();
+
+ MeterIdentificationDelegate * GetDelegate() { return mDelegate; };
+
+private:
+ MeterIdentificationDelegate * mDelegate;
+};
+
+} // namespace MeterIdentification
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/examples/energy-management-app/energy-management-common/src/MeterIdentificationDelegate.cpp b/examples/energy-management-app/energy-management-common/src/MeterIdentificationDelegate.cpp
new file mode 100644
index 00000000000000..e2c0cbb84c919c
--- /dev/null
+++ b/examples/energy-management-app/energy-management-common/src/MeterIdentificationDelegate.cpp
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+
+#include
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::DataModel;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::MeterIdentification;
+using namespace chip::app::Clusters::MeterIdentification::Attributes;
+
+using chip::app::Clusters::MeterIdentification::MeterTypeEnum;
+using chip::app::Clusters::MeterIdentification::PowerThresholdSourceEnum;
+
+CHIP_ERROR MeterIdentificationInstance::Init()
+{
+ return Instance::Init();
+}
+
+void MeterIdentificationInstance::Shutdown()
+{
+ Instance::Shutdown();
+}
+
+// --------------- Internal Attribute Set APIs
+
+CHIP_ERROR MeterIdentificationDelegate::SetMeterType(DataModel::Nullable newValue)
+{
+ DataModel::Nullable oldValue = mMeterType;
+
+ mMeterType = newValue;
+ if (oldValue != newValue)
+ {
+ // We won't log raw values since these could change frequently
+ MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, MeterType::Id);
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR MeterIdentificationDelegate::SetCustomerName(CharSpan & newValue)
+{
+ CharSpan oldValue = mCustomerName;
+
+ mCustomerName = newValue;
+ if (!oldValue.data_equal(newValue))
+ {
+ // We won't log raw values since these could change frequently
+ MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, CustomerName::Id);
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR MeterIdentificationDelegate::SetUtilityName(CharSpan & newValue)
+{
+ CharSpan oldValue = mUtilityName;
+
+ mUtilityName = newValue;
+ if (!oldValue.data_equal(newValue))
+ {
+ // We won't log raw values since these could change frequently
+ MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, UtilityName::Id);
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR MeterIdentificationDelegate::SetPointOfDelivery(CharSpan & newValue)
+{
+ CharSpan oldValue = mPointOfDelivery;
+
+ mPointOfDelivery = newValue;
+ if (!oldValue.data_equal(newValue))
+ {
+ // We won't log raw values since these could change frequently
+ MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, PointOfDelivery::Id);
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR MeterIdentificationDelegate::SetPowerThreshold(DataModel::Nullable newValue)
+{
+ DataModel::Nullable oldValue = mPowerThreshold;
+
+ mPowerThreshold = newValue;
+ if (oldValue != newValue)
+ {
+ // We won't log raw values since these could change frequently
+ MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, PowerThreshold::Id);
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR MeterIdentificationDelegate::SetPowerThresholdSource(DataModel::Nullable newValue)
+{
+ DataModel::Nullable oldValue = mPowerThresholdSource;
+
+ mPowerThresholdSource = newValue;
+ if (oldValue != newValue)
+ {
+ // We won't log raw values since these could change frequently
+ MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, PowerThresholdSource::Id);
+ }
+
+ return CHIP_NO_ERROR;
+}
diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint
index 76e9d8df313d63..206c9f8d938a18 100644
--- a/scripts/rules.matterlint
+++ b/scripts/rules.matterlint
@@ -107,6 +107,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.x
load "../src/app/zap-templates/zcl/data-model/chip/sample-mei-cluster.xml";
load "../src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml";
load "../src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml";
+load "../src/app/zap-templates/zcl/data-model/chip/meter-identification-cluster.xml";
load "../src/app/zap-templates/zcl/data-model/draft/barrier-control-cluster.xml";
load "../src/app/zap-templates/zcl/data-model/draft/electrical-measurement-cluster.xml";
load "../src/app/zap-templates/zcl/data-model/draft/input-output-value-clusters.xml";
diff --git a/src/app/clusters/meter-identification-server/meter-identification-server.cpp b/src/app/clusters/meter-identification-server/meter-identification-server.cpp
new file mode 100644
index 00000000000000..e2d136c2de05d1
--- /dev/null
+++ b/src/app/clusters/meter-identification-server/meter-identification-server.cpp
@@ -0,0 +1,121 @@
+/*
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "meter-identification-server.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::DataModel;
+using namespace chip::app::Clusters;
+using namespace chip::app::Clusters::MeterIdentification;
+using namespace chip::app::Clusters::MeterIdentification::Attributes;
+using namespace chip::app::Clusters::MeterIdentification::Structs;
+
+using chip::Protocols::InteractionModel::Status;
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace MeterIdentification {
+
+CHIP_ERROR Instance::Init()
+{
+ VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE);
+ return CHIP_NO_ERROR;
+}
+
+void Instance::Shutdown()
+{
+ unregisterAttributeAccessOverride(this);
+}
+
+bool Instance::HasFeature(Feature aFeature) const
+{
+ return mFeature.Has(aFeature);
+}
+
+static CHIP_ERROR EncodeStringOnSuccess(CHIP_ERROR status, AttributeValueEncoder & encoder, const char * buf, size_t maxBufSize)
+{
+ ReturnErrorOnFailure(status);
+ return encoder.Encode(chip::CharSpan(buf, strnlen(buf, maxBufSize)));
+}
+
+// AttributeAccessInterface
+CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
+{
+ switch (aPath.mAttributeId)
+ {
+ case FeatureMap::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mFeature));
+ break;
+ case MeterType::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetMeterType()));
+ break;
+
+ case CustomerName::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetCustomerName()));
+ break;
+
+ case UtilityName::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetUtilityName()));
+ break;
+
+ case PointOfDelivery::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPointOfDelivery()));
+ break;
+
+ case PowerThreshold::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPowerThreshold()));
+ break;
+
+ case PowerThresholdSource::Id:
+ ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPowerThresholdSource()));
+ break;
+ }
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR Instance::Write(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
+{
+ CharSpan str;
+
+ switch (aPath.mAttributeId)
+ {
+ case CustomerName::Id:
+ ReturnErrorOnFailure(aDecoder.Decode(str));
+ status = mDelegate.SetCustomerName(str);
+ break;
+
+ default:
+ break;
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+} // namespace MeterIdentification
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/clusters/meter-identification-server/meter-identification-server.h b/src/app/clusters/meter-identification-server/meter-identification-server.h
new file mode 100644
index 00000000000000..7574af94c3bd59
--- /dev/null
+++ b/src/app/clusters/meter-identification-server/meter-identification-server.h
@@ -0,0 +1,87 @@
+/**
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+using chip::app::Clusters::MeterIdentification::MeterTypeEnum;
+using chip::app::Clusters::MeterIdentification::PowerThresholdSourceEnum;
+using Feature = chip::app::Clusters::MeterIdentification::Feature;
+
+namespace chip {
+namespace app {
+namespace Clusters {
+namespace MeterIdentification {
+
+struct Delegate
+{
+public:
+ virtual ~Delegate() = default;
+
+ void SetEndpointId(EndpointId aEndpoint) { mEndpointId = aEndpoint; }
+
+ virtual DataModel::Nullable GetMeterType() = 0;
+ virtual CharSpan GetCustomerName() = 0;
+ virtual CharSpan GetUtilityName() = 0;
+ virtual CharSpan GetPointOfDelivery() = 0;
+ virtual DataModel::Nullable GetPowerThreshold() = 0;
+ virtual DataModel::Nullable GetPowerThresholdSource() = 0;
+
+ virtual CHIP_ERROR SetCustomerName(CharSpan & value) = 0;
+
+protected:
+ EndpointId mEndpointId = 0;
+};
+
+class Instance : public AttributeAccessInterface
+{
+public:
+ Instance(EndpointId aEndpointId, Delegate & aDelegate, BitMask aFeature) :
+ AttributeAccessInterface(MakeOptional(aEndpointId), Id), mDelegate(aDelegate), mFeature(aFeature)
+ {
+ /* set the base class delegates endpointId */
+ mDelegate.SetEndpointId(aEndpointId);
+ }
+ ~Instance() { Shutdown(); }
+
+ CHIP_ERROR Init();
+ void Shutdown();
+
+ bool HasFeature(Feature aFeature) const;
+
+private:
+ Delegate & mDelegate;
+ BitMask mFeature;
+
+ // AttributeAccessInterface
+ CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
+ CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override;
+};
+
+} // namespace MeterIdentification
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml
index 83d1b682153ed7..7d94cedfab9a66 100644
--- a/src/app/common/templates/config-data.yaml
+++ b/src/app/common/templates/config-data.yaml
@@ -36,6 +36,7 @@ CommandHandlerInterfaceOnlyClusters:
- Microwave Oven Control
- Energy EVSE
- Energy EVSE Mode
+ - Meter Identification
- Device Energy Management
- Device Energy Management Mode
- Electrical Power Measurement
diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml
index e523acb886541d..e448805c68a9d9 100644
--- a/src/app/zap-templates/zcl/data-model/all.xml
+++ b/src/app/zap-templates/zcl/data-model/all.xml
@@ -111,6 +111,7 @@
+
diff --git a/src/app/zap-templates/zcl/data-model/chip/meter-identification-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/meter-identification-cluster.xml
new file mode 100644
index 00000000000000..9bfb90fc13a6c5
--- /dev/null
+++ b/src/app/zap-templates/zcl/data-model/chip/meter-identification-cluster.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Meter Identification
+ Energy Management
+ 0x0B01
+ METER_IDENTIFICATION_CLUSTER
+ true
+ true
+ This cluster provides attributes for determining advanced information about utility metering device.
+
+
+
+
+
+
+
+ MeterType
+
+
+
+ CustomerName
+
+ UtilityName
+ PointOfDelivery
+ PowerThreshold
+ PowerThresholdSource
+
+
+
diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json
index 0c1e2c2b5a715f..abd646840758a7 100644
--- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json
+++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json
@@ -131,6 +131,7 @@
"window-covering.xml",
"matter-devices.xml",
"sample-mei-cluster.xml",
+ "meter-identification-cluster.xml",
"types/door-lock.xml",
"types/occupancy-sensing.xml",
"types/thermostat-user-interface-configuration.xml"
diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json
index 0d99e3f865463c..787e3f42f3d696 100644
--- a/src/app/zap-templates/zcl/zcl.json
+++ b/src/app/zap-templates/zcl/zcl.json
@@ -129,6 +129,7 @@
"window-covering.xml",
"matter-devices.xml",
"sample-mei-cluster.xml",
+ "meter-identification-cluster.xml",
"types/door-lock.xml",
"types/occupancy-sensing.xml",
"types/thermostat-user-interface-configuration.xml"
diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json
index 4c7757224b1a7d..7209eff52efe58 100644
--- a/src/app/zap_cluster_list.json
+++ b/src/app/zap_cluster_list.json
@@ -131,6 +131,8 @@
"LAUNDRY_DRYER_CONTROLS_CLUSTER": [],
"WIFI_NETWORK_DIAGNOSTICS_CLUSTER": [],
"WINDOW_COVERING_CLUSTER": [],
+ "METER_INDENTIFICATION_CLUSTER": [],
+ "METER_IDENTIFICATION_CLUSTER": [],
"ZLL_COMMISSIONING_CLUSTER": []
},
"ServerDirectories": {
@@ -311,6 +313,7 @@
"WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"],
"WIFI_NETWORK_MANAGEMENT_CLUSTER": ["wifi-network-management-server"],
"WINDOW_COVERING_CLUSTER": ["window-covering-server"],
+ "METER_IDENTIFICATION_CLUSTER": ["meter-identification-server"],
"ZLL_COMMISSIONING_CLUSTER": []
}
}
diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter
index 14f6587b5461d0..4da2c4fa3efff5 100644
--- a/src/controller/data_model/controller-clusters.matter
+++ b/src/controller/data_model/controller-clusters.matter
@@ -8810,6 +8810,40 @@ provisional cluster ContentAppObserver = 1296 {
command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0;
}
+/** This cluster provides attributes for determining advanced information about utility metering device. */
+cluster MeterIdentification = 2817 {
+ revision 1; // NOTE: Default/not specifically set
+
+ enum MeterTypeEnum : enum8 {
+ kUtility = 0;
+ kPrivate = 1;
+ kGeneric = 2;
+ }
+
+ enum PowerThresholdSourceEnum : enum8 {
+ kContract = 0;
+ kRegulator = 1;
+ kEquipment = 2;
+ }
+
+ bitmap Feature : bitmap32 {
+ kPowerThreshold = 0x1;
+ }
+
+ readonly attribute nullable MeterTypeEnum meterType = 0;
+ attribute nullable char_string<64> customerName = 1;
+ readonly attribute nullable char_string<16> utilityName = 2;
+ readonly attribute nullable char_string<16> pointOfDelivery = 3;
+ readonly attribute nullable power_mw powerThreshold = 4;
+ readonly attribute nullable PowerThresholdSourceEnum powerThresholdSource = 5;
+ 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;
+}
+
/** Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster.. */
deprecated cluster ElectricalMeasurement = 2820 {
revision 3;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
index 40725b1dfba8fe..0f59372170514c 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java
@@ -59219,6 +59219,394 @@ public void onSuccess(byte[] tlv) {
}
}
+ public static class MeterIdentificationCluster extends BaseChipCluster {
+ public static final long CLUSTER_ID = 2817L;
+
+ private static final long METER_TYPE_ATTRIBUTE_ID = 0L;
+ private static final long CUSTOMER_NAME_ATTRIBUTE_ID = 1L;
+ private static final long UTILITY_NAME_ATTRIBUTE_ID = 2L;
+ private static final long POINT_OF_DELIVERY_ATTRIBUTE_ID = 3L;
+ private static final long POWER_THRESHOLD_ATTRIBUTE_ID = 4L;
+ private static final long POWER_THRESHOLD_SOURCE_ATTRIBUTE_ID = 5L;
+ private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L;
+ private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L;
+ private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L;
+ private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L;
+ private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L;
+ private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L;
+
+ public MeterIdentificationCluster(long devicePtr, int endpointId) {
+ super(devicePtr, endpointId, CLUSTER_ID);
+ }
+
+ @Override
+ @Deprecated
+ public long initWithDevice(long devicePtr, int endpointId) {
+ return 0L;
+ }
+
+ public interface MeterTypeAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable Integer value);
+ }
+
+ public interface CustomerNameAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable String value);
+ }
+
+ public interface UtilityNameAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable String value);
+ }
+
+ public interface PointOfDeliveryAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable String value);
+ }
+
+ public interface PowerThresholdAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable Long value);
+ }
+
+ public interface PowerThresholdSourceAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(@Nullable Integer value);
+ }
+
+ public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface EventListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public interface AttributeListAttributeCallback extends BaseAttributeCallback {
+ void onSuccess(List value);
+ }
+
+ public void readMeterTypeAttribute(
+ MeterTypeAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, METER_TYPE_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, METER_TYPE_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeMeterTypeAttribute(
+ MeterTypeAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, METER_TYPE_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, METER_TYPE_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readCustomerNameAttribute(
+ CustomerNameAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CUSTOMER_NAME_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, CUSTOMER_NAME_ATTRIBUTE_ID, true);
+ }
+
+ public void writeCustomerNameAttribute(DefaultClusterCallback callback, String value) {
+ writeCustomerNameAttribute(callback, value, 0);
+ }
+
+ public void writeCustomerNameAttribute(DefaultClusterCallback callback, String value, int timedWriteTimeoutMs) {
+ BaseTLVType tlvValue = value != null ? new StringType(value) : new NullType();
+ writeAttribute(new WriteAttributesCallbackImpl(callback), CUSTOMER_NAME_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs);
+ }
+
+ public void subscribeCustomerNameAttribute(
+ CustomerNameAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CUSTOMER_NAME_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, CUSTOMER_NAME_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readUtilityNameAttribute(
+ UtilityNameAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, UTILITY_NAME_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, UTILITY_NAME_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeUtilityNameAttribute(
+ UtilityNameAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, UTILITY_NAME_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, UTILITY_NAME_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readPointOfDeliveryAttribute(
+ PointOfDeliveryAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, POINT_OF_DELIVERY_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, POINT_OF_DELIVERY_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribePointOfDeliveryAttribute(
+ PointOfDeliveryAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, POINT_OF_DELIVERY_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable String value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, POINT_OF_DELIVERY_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readPowerThresholdAttribute(
+ PowerThresholdAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, POWER_THRESHOLD_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, POWER_THRESHOLD_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribePowerThresholdAttribute(
+ PowerThresholdAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, POWER_THRESHOLD_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, POWER_THRESHOLD_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readPowerThresholdSourceAttribute(
+ PowerThresholdSourceAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, POWER_THRESHOLD_SOURCE_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, POWER_THRESHOLD_SOURCE_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribePowerThresholdSourceAttribute(
+ PowerThresholdSourceAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, POWER_THRESHOLD_SOURCE_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, POWER_THRESHOLD_SOURCE_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readGeneratedCommandListAttribute(
+ GeneratedCommandListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeGeneratedCommandListAttribute(
+ GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readAcceptedCommandListAttribute(
+ AcceptedCommandListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeAcceptedCommandListAttribute(
+ AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readEventListAttribute(
+ EventListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, EVENT_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeEventListAttribute(
+ EventListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readAttributeListAttribute(
+ AttributeListAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeAttributeListAttribute(
+ AttributeListAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readFeatureMapAttribute(
+ LongAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, FEATURE_MAP_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeFeatureMapAttribute(
+ LongAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+
+ public void readClusterRevisionAttribute(
+ IntegerAttributeCallback callback) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID);
+
+ readAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, CLUSTER_REVISION_ATTRIBUTE_ID, true);
+ }
+
+ public void subscribeClusterRevisionAttribute(
+ IntegerAttributeCallback callback, int minInterval, int maxInterval) {
+ ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID);
+
+ subscribeAttribute(new ReportCallbackImpl(callback, path) {
+ @Override
+ public void onSuccess(byte[] tlv) {
+ Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv);
+ callback.onSuccess(value);
+ }
+ }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval);
+ }
+ }
+
public static class ElectricalMeasurementCluster extends BaseChipCluster {
public static final long CLUSTER_ID = 2820L;
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
index df03516f3e4063..57e97a125f5769 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java
@@ -379,6 +379,9 @@ public static BaseCluster getCluster(long clusterId) {
if (clusterId == ContentAppObserver.ID) {
return new ContentAppObserver();
}
+ if (clusterId == MeterIdentification.ID) {
+ return new MeterIdentification();
+ }
if (clusterId == ElectricalMeasurement.ID) {
return new ElectricalMeasurement();
}
@@ -16780,6 +16783,112 @@ public long getCommandID(String name) throws IllegalArgumentException {
return Command.valueOf(name).getID();
}
}
+ public static class MeterIdentification implements BaseCluster {
+ public static final long ID = 2817L;
+ public long getID() {
+ return ID;
+ }
+
+ public enum Attribute {
+ MeterType(0L),
+ CustomerName(1L),
+ UtilityName(2L),
+ PointOfDelivery(3L),
+ PowerThreshold(4L),
+ PowerThresholdSource(5L),
+ GeneratedCommandList(65528L),
+ AcceptedCommandList(65529L),
+ EventList(65530L),
+ AttributeList(65531L),
+ FeatureMap(65532L),
+ ClusterRevision(65533L),;
+ private final long id;
+ Attribute(long id) {
+ this.id = id;
+ }
+
+ public long getID() {
+ return id;
+ }
+
+ public static Attribute value(long id) throws NoSuchFieldError {
+ for (Attribute attribute : Attribute.values()) {
+ if (attribute.getID() == id) {
+ return attribute;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }
+
+ public enum Event {;
+ private final long id;
+ Event(long id) {
+ this.id = id;
+ }
+
+ public long getID() {
+ return id;
+ }
+
+ public static Event value(long id) throws NoSuchFieldError {
+ for (Event event : Event.values()) {
+ if (event.getID() == id) {
+ return event;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }
+
+ public enum Command {;
+ private final long id;
+ Command(long id) {
+ this.id = id;
+ }
+
+ public long getID() {
+ return id;
+ }
+
+ public static Command value(long id) throws NoSuchFieldError {
+ for (Command command : Command.values()) {
+ if (command.getID() == id) {
+ return command;
+ }
+ }
+ throw new NoSuchFieldError();
+ }
+ }@Override
+ public String getAttributeName(long id) throws NoSuchFieldError {
+ return Attribute.value(id).toString();
+ }
+
+ @Override
+ public String getEventName(long id) throws NoSuchFieldError {
+ return Event.value(id).toString();
+ }
+
+ @Override
+ public String getCommandName(long id) throws NoSuchFieldError {
+ return Command.value(id).toString();
+ }
+
+ @Override
+ public long getAttributeID(String name) throws IllegalArgumentException {
+ return Attribute.valueOf(name).getID();
+ }
+
+ @Override
+ public long getEventID(String name) throws IllegalArgumentException {
+ return Event.valueOf(name).getID();
+ }
+
+ @Override
+ public long getCommandID(String name) throws IllegalArgumentException {
+ return Command.valueOf(name).getID();
+ }
+ }
public static class ElectricalMeasurement implements BaseCluster {
public static final long ID = 2820L;
public long getID() {
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
index 219baca838f58b..2308689f757207 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java
@@ -19576,6 +19576,216 @@ public void onError(Exception ex) {
}
}
+ public static class DelegatedMeterIdentificationClusterMeterTypeAttributeCallback implements ChipClusters.MeterIdentificationCluster.MeterTypeAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable Integer value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterCustomerNameAttributeCallback implements ChipClusters.MeterIdentificationCluster.CustomerNameAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable String value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "String");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterUtilityNameAttributeCallback implements ChipClusters.MeterIdentificationCluster.UtilityNameAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable String value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "String");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterPointOfDeliveryAttributeCallback implements ChipClusters.MeterIdentificationCluster.PointOfDeliveryAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable String value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "String");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterPowerThresholdAttributeCallback implements ChipClusters.MeterIdentificationCluster.PowerThresholdAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable Long value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterPowerThresholdSourceAttributeCallback implements ChipClusters.MeterIdentificationCluster.PowerThresholdSourceAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(@Nullable Integer value) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer");
+ responseValues.put(commandResponseInfo, value);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterGeneratedCommandListAttributeCallback implements ChipClusters.MeterIdentificationCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterAcceptedCommandListAttributeCallback implements ChipClusters.MeterIdentificationCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterEventListAttributeCallback implements ChipClusters.MeterIdentificationCluster.EventListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
+ public static class DelegatedMeterIdentificationClusterAttributeListAttributeCallback implements ChipClusters.MeterIdentificationCluster.AttributeListAttributeCallback, DelegatedClusterCallback {
+ private ClusterCommandCallback callback;
+ @Override
+ public void setCallbackDelegate(ClusterCommandCallback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void onSuccess(List valueList) {
+ Map responseValues = new LinkedHashMap<>();
+ CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List");
+ responseValues.put(commandResponseInfo, valueList);
+ callback.onSuccess(responseValues);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ callback.onFailure(ex);
+ }
+ }
+
public static class DelegatedElectricalMeasurementClusterGeneratedCommandListAttributeCallback implements ChipClusters.ElectricalMeasurementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback {
private ClusterCommandCallback callback;
@Override
@@ -21647,6 +21857,10 @@ public Map initializeClusterMap() {
(ptr, endpointId) -> new ChipClusters.ContentAppObserverCluster(ptr, endpointId), new HashMap<>());
clusterMap.put("contentAppObserver", contentAppObserverClusterInfo);
+ ClusterInfo meterIdentificationClusterInfo = new ClusterInfo(
+ (ptr, endpointId) -> new ChipClusters.MeterIdentificationCluster(ptr, endpointId), new HashMap<>());
+ clusterMap.put("meterIdentification", meterIdentificationClusterInfo);
+
ClusterInfo electricalMeasurementClusterInfo = new ClusterInfo(
(ptr, endpointId) -> new ChipClusters.ElectricalMeasurementCluster(ptr, endpointId), new HashMap<>());
clusterMap.put("electricalMeasurement", electricalMeasurementClusterInfo);
@@ -21784,6 +21998,7 @@ public void combineCommand(Map destination, Map> getCommandMap() {
commandMap.put("contentAppObserver", contentAppObserverClusterInteractionInfoMap);
+ Map meterIdentificationClusterInteractionInfoMap = new LinkedHashMap<>();
+
+ commandMap.put("meterIdentification", meterIdentificationClusterInteractionInfoMap);
+
Map electricalMeasurementClusterInteractionInfoMap = new LinkedHashMap<>();
Map electricalMeasurementgetProfileInfoCommandCommandParams = new LinkedHashMap();
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java
index 23261b74f09dbf..0cb26203fac7c6 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java
@@ -18192,6 +18192,142 @@ private static Map readContentAppObserverInteractionInf
return result;
}
+ private static Map readMeterIdentificationInteractionInfo() {
+ Map result = new LinkedHashMap<>();Map readMeterIdentificationMeterTypeCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationMeterTypeAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readMeterTypeAttribute(
+ (ChipClusters.MeterIdentificationCluster.MeterTypeAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterMeterTypeAttributeCallback(),
+ readMeterIdentificationMeterTypeCommandParams
+ );
+ result.put("readMeterTypeAttribute", readMeterIdentificationMeterTypeAttributeInteractionInfo);
+ Map readMeterIdentificationCustomerNameCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationCustomerNameAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readCustomerNameAttribute(
+ (ChipClusters.MeterIdentificationCluster.CustomerNameAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterCustomerNameAttributeCallback(),
+ readMeterIdentificationCustomerNameCommandParams
+ );
+ result.put("readCustomerNameAttribute", readMeterIdentificationCustomerNameAttributeInteractionInfo);
+ Map readMeterIdentificationUtilityNameCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationUtilityNameAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readUtilityNameAttribute(
+ (ChipClusters.MeterIdentificationCluster.UtilityNameAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterUtilityNameAttributeCallback(),
+ readMeterIdentificationUtilityNameCommandParams
+ );
+ result.put("readUtilityNameAttribute", readMeterIdentificationUtilityNameAttributeInteractionInfo);
+ Map readMeterIdentificationPointOfDeliveryCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationPointOfDeliveryAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readPointOfDeliveryAttribute(
+ (ChipClusters.MeterIdentificationCluster.PointOfDeliveryAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterPointOfDeliveryAttributeCallback(),
+ readMeterIdentificationPointOfDeliveryCommandParams
+ );
+ result.put("readPointOfDeliveryAttribute", readMeterIdentificationPointOfDeliveryAttributeInteractionInfo);
+ Map readMeterIdentificationPowerThresholdCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationPowerThresholdAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readPowerThresholdAttribute(
+ (ChipClusters.MeterIdentificationCluster.PowerThresholdAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterPowerThresholdAttributeCallback(),
+ readMeterIdentificationPowerThresholdCommandParams
+ );
+ result.put("readPowerThresholdAttribute", readMeterIdentificationPowerThresholdAttributeInteractionInfo);
+ Map readMeterIdentificationPowerThresholdSourceCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationPowerThresholdSourceAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readPowerThresholdSourceAttribute(
+ (ChipClusters.MeterIdentificationCluster.PowerThresholdSourceAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterPowerThresholdSourceAttributeCallback(),
+ readMeterIdentificationPowerThresholdSourceCommandParams
+ );
+ result.put("readPowerThresholdSourceAttribute", readMeterIdentificationPowerThresholdSourceAttributeInteractionInfo);
+ Map readMeterIdentificationGeneratedCommandListCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationGeneratedCommandListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readGeneratedCommandListAttribute(
+ (ChipClusters.MeterIdentificationCluster.GeneratedCommandListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterGeneratedCommandListAttributeCallback(),
+ readMeterIdentificationGeneratedCommandListCommandParams
+ );
+ result.put("readGeneratedCommandListAttribute", readMeterIdentificationGeneratedCommandListAttributeInteractionInfo);
+ Map readMeterIdentificationAcceptedCommandListCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationAcceptedCommandListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readAcceptedCommandListAttribute(
+ (ChipClusters.MeterIdentificationCluster.AcceptedCommandListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterAcceptedCommandListAttributeCallback(),
+ readMeterIdentificationAcceptedCommandListCommandParams
+ );
+ result.put("readAcceptedCommandListAttribute", readMeterIdentificationAcceptedCommandListAttributeInteractionInfo);
+ Map readMeterIdentificationEventListCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationEventListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readEventListAttribute(
+ (ChipClusters.MeterIdentificationCluster.EventListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterEventListAttributeCallback(),
+ readMeterIdentificationEventListCommandParams
+ );
+ result.put("readEventListAttribute", readMeterIdentificationEventListAttributeInteractionInfo);
+ Map readMeterIdentificationAttributeListCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationAttributeListAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readAttributeListAttribute(
+ (ChipClusters.MeterIdentificationCluster.AttributeListAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedMeterIdentificationClusterAttributeListAttributeCallback(),
+ readMeterIdentificationAttributeListCommandParams
+ );
+ result.put("readAttributeListAttribute", readMeterIdentificationAttributeListAttributeInteractionInfo);
+ Map readMeterIdentificationFeatureMapCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationFeatureMapAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readFeatureMapAttribute(
+ (ChipClusters.LongAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(),
+ readMeterIdentificationFeatureMapCommandParams
+ );
+ result.put("readFeatureMapAttribute", readMeterIdentificationFeatureMapAttributeInteractionInfo);
+ Map readMeterIdentificationClusterRevisionCommandParams = new LinkedHashMap();
+ InteractionInfo readMeterIdentificationClusterRevisionAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).readClusterRevisionAttribute(
+ (ChipClusters.IntegerAttributeCallback) callback
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(),
+ readMeterIdentificationClusterRevisionCommandParams
+ );
+ result.put("readClusterRevisionAttribute", readMeterIdentificationClusterRevisionAttributeInteractionInfo);
+
+ return result;
+ }
private static Map readElectricalMeasurementInteractionInfo() {
Map result = new LinkedHashMap<>();Map readElectricalMeasurementMeasurementTypeCommandParams = new LinkedHashMap();
InteractionInfo readElectricalMeasurementMeasurementTypeAttributeInteractionInfo = new InteractionInfo(
@@ -20903,6 +21039,7 @@ public Map> getReadAttributeMap() {
put("accountLogin", readAccountLoginInteractionInfo());
put("contentControl", readContentControlInteractionInfo());
put("contentAppObserver", readContentAppObserverInteractionInfo());
+ put("meterIdentification", readMeterIdentificationInteractionInfo());
put("electricalMeasurement", readElectricalMeasurementInteractionInfo());
put("unitTesting", readUnitTestingInteractionInfo());
put("faultInjection", readFaultInjectionInteractionInfo());
diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java
index 948e665b63da72..1111582e6682b4 100644
--- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java
+++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java
@@ -3692,6 +3692,30 @@ public Map> getWriteAttributeMap() {
writeAttributeMap.put("contentControl", writeContentControlInteractionInfo);
Map writeContentAppObserverInteractionInfo = new LinkedHashMap<>();
writeAttributeMap.put("contentAppObserver", writeContentAppObserverInteractionInfo);
+ Map writeMeterIdentificationInteractionInfo = new LinkedHashMap<>();
+ Map writeMeterIdentificationCustomerNameCommandParams = new LinkedHashMap();
+ CommandParameterInfo meterIdentificationcustomerNameCommandParameterInfo =
+ new CommandParameterInfo(
+ "value",
+ String.class,
+ String.class
+ );
+ writeMeterIdentificationCustomerNameCommandParams.put(
+ "value",
+ meterIdentificationcustomerNameCommandParameterInfo
+ );
+ InteractionInfo writeMeterIdentificationCustomerNameAttributeInteractionInfo = new InteractionInfo(
+ (cluster, callback, commandArguments) -> {
+ ((ChipClusters.MeterIdentificationCluster) cluster).writeCustomerNameAttribute(
+ (DefaultClusterCallback) callback,
+ (String) commandArguments.get("value")
+ );
+ },
+ () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(),
+ writeMeterIdentificationCustomerNameCommandParams
+ );
+ writeMeterIdentificationInteractionInfo.put("writeCustomerNameAttribute", writeMeterIdentificationCustomerNameAttributeInteractionInfo);
+ writeAttributeMap.put("meterIdentification", writeMeterIdentificationInteractionInfo);
Map writeElectricalMeasurementInteractionInfo = new LinkedHashMap<>();
Map writeElectricalMeasurementAverageRmsVoltageMeasurementPeriodCommandParams = new LinkedHashMap();
CommandParameterInfo electricalMeasurementaverageRmsVoltageMeasurementPeriodCommandParameterInfo =
diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/MeterIdentificationCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/MeterIdentificationCluster.kt
new file mode 100644
index 00000000000000..b8973ff8a815f4
--- /dev/null
+++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/MeterIdentificationCluster.kt
@@ -0,0 +1,1301 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package matter.controller.cluster.clusters
+
+import java.time.Duration
+import java.util.logging.Level
+import java.util.logging.Logger
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.transform
+import matter.controller.MatterController
+import matter.controller.ReadData
+import matter.controller.ReadRequest
+import matter.controller.SubscribeRequest
+import matter.controller.SubscriptionState
+import matter.controller.UIntSubscriptionState
+import matter.controller.UShortSubscriptionState
+import matter.controller.WriteRequest
+import matter.controller.WriteRequests
+import matter.controller.WriteResponse
+import matter.controller.cluster.structs.*
+import matter.controller.model.AttributePath
+import matter.tlv.AnonymousTag
+import matter.tlv.TlvReader
+import matter.tlv.TlvWriter
+
+class MeterIdentificationCluster(
+ private val controller: MatterController,
+ private val endpointId: UShort
+) {
+ class MeterTypeAttribute(val value: UByte?)
+
+ sealed class MeterTypeAttributeSubscriptionState {
+ data class Success(val value: UByte?) : MeterTypeAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : MeterTypeAttributeSubscriptionState()
+
+ object SubscriptionEstablished : MeterTypeAttributeSubscriptionState()
+ }
+
+ class CustomerNameAttribute(val value: String?)
+
+ sealed class CustomerNameAttributeSubscriptionState {
+ data class Success(val value: String?) : CustomerNameAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : CustomerNameAttributeSubscriptionState()
+
+ object SubscriptionEstablished : CustomerNameAttributeSubscriptionState()
+ }
+
+ class UtilityNameAttribute(val value: String?)
+
+ sealed class UtilityNameAttributeSubscriptionState {
+ data class Success(val value: String?) : UtilityNameAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : UtilityNameAttributeSubscriptionState()
+
+ object SubscriptionEstablished : UtilityNameAttributeSubscriptionState()
+ }
+
+ class PointOfDeliveryAttribute(val value: String?)
+
+ sealed class PointOfDeliveryAttributeSubscriptionState {
+ data class Success(val value: String?) : PointOfDeliveryAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : PointOfDeliveryAttributeSubscriptionState()
+
+ object SubscriptionEstablished : PointOfDeliveryAttributeSubscriptionState()
+ }
+
+ class PowerThresholdAttribute(val value: Long?)
+
+ sealed class PowerThresholdAttributeSubscriptionState {
+ data class Success(val value: Long?) : PowerThresholdAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : PowerThresholdAttributeSubscriptionState()
+
+ object SubscriptionEstablished : PowerThresholdAttributeSubscriptionState()
+ }
+
+ class PowerThresholdSourceAttribute(val value: UByte?)
+
+ sealed class PowerThresholdSourceAttributeSubscriptionState {
+ data class Success(val value: UByte?) : PowerThresholdSourceAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : PowerThresholdSourceAttributeSubscriptionState()
+
+ object SubscriptionEstablished : PowerThresholdSourceAttributeSubscriptionState()
+ }
+
+ class GeneratedCommandListAttribute(val value: List)
+
+ sealed class GeneratedCommandListAttributeSubscriptionState {
+ data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState()
+ }
+
+ class AcceptedCommandListAttribute(val value: List)
+
+ sealed class AcceptedCommandListAttributeSubscriptionState {
+ data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState()
+ }
+
+ class EventListAttribute(val value: List)
+
+ sealed class EventListAttributeSubscriptionState {
+ data class Success(val value: List) : EventListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : EventListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : EventListAttributeSubscriptionState()
+ }
+
+ class AttributeListAttribute(val value: List)
+
+ sealed class AttributeListAttributeSubscriptionState {
+ data class Success(val value: List) : AttributeListAttributeSubscriptionState()
+
+ data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState()
+
+ object SubscriptionEstablished : AttributeListAttributeSubscriptionState()
+ }
+
+ suspend fun readMeterTypeAttribute(): MeterTypeAttribute {
+ 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) { "Metertype 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 MeterTypeAttribute(decodedValue)
+ }
+
+ suspend fun subscribeMeterTypeAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 0u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ MeterTypeAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Metertype attribute not found in Node State update" }
+
+ // 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
+ }
+
+ decodedValue?.let { emit(MeterTypeAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(MeterTypeAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readCustomerNameAttribute(): CustomerNameAttribute {
+ 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) { "Customername 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 CustomerNameAttribute(decodedValue)
+ }
+
+ suspend fun writeCustomerNameAttribute(value: String, timedWriteTimeout: Duration? = null) {
+ val ATTRIBUTE_ID: UInt = 1u
+
+ 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 = timedWriteTimeout
+ )
+
+ 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 subscribeCustomerNameAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 1u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ CustomerNameAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Customername attribute not found in Node State update" }
+
+ // 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
+ }
+
+ decodedValue?.let { emit(CustomerNameAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(CustomerNameAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readUtilityNameAttribute(): UtilityNameAttribute {
+ 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) { "Utilityname 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 UtilityNameAttribute(decodedValue)
+ }
+
+ suspend fun subscribeUtilityNameAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 2u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ UtilityNameAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Utilityname attribute not found in Node State update" }
+
+ // 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
+ }
+
+ decodedValue?.let { emit(UtilityNameAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(UtilityNameAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readPointOfDeliveryAttribute(): PointOfDeliveryAttribute {
+ 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) { "Pointofdelivery 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 PointOfDeliveryAttribute(decodedValue)
+ }
+
+ suspend fun subscribePointOfDeliveryAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 3u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ PointOfDeliveryAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Pointofdelivery attribute not found in Node State update"
+ }
+
+ // 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
+ }
+
+ decodedValue?.let { emit(PointOfDeliveryAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(PointOfDeliveryAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readPowerThresholdAttribute(): PowerThresholdAttribute {
+ 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) { "Powerthreshold 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
+ }
+
+ return PowerThresholdAttribute(decodedValue)
+ }
+
+ suspend fun subscribePowerThresholdAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 4u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ PowerThresholdAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Powerthreshold attribute not found in Node State update"
+ }
+
+ // 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
+ }
+
+ decodedValue?.let { emit(PowerThresholdAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(PowerThresholdAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ suspend fun readPowerThresholdSourceAttribute(): PowerThresholdSourceAttribute {
+ 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) { "Powerthresholdsource 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 PowerThresholdSourceAttribute(decodedValue)
+ }
+
+ suspend fun subscribePowerThresholdSourceAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 5u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ PowerThresholdSourceAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Powerthresholdsource attribute not found in Node State update"
+ }
+
+ // 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
+ }
+
+ decodedValue?.let { emit(PowerThresholdSourceAttributeSubscriptionState.Success(it)) }
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(PowerThresholdSourceAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ 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 subscribeGeneratedCommandListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65528u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ GeneratedCommandListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Generatedcommandlist attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ 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 subscribeAcceptedCommandListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65529u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ AcceptedCommandListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Acceptedcommandlist attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ 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 subscribeEventListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65530u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ EventListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(EventListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(EventListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ 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 subscribeAttributeListAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65531u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ AttributeListAttributeSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: List =
+ buildList {
+ tlvReader.enterArray(AnonymousTag)
+ while (!tlvReader.isEndOfContainer()) {
+ add(tlvReader.getUInt(AnonymousTag))
+ }
+ tlvReader.exitContainer()
+ }
+
+ emit(AttributeListAttributeSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ 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 subscribeFeatureMapAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65532u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ UIntSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UInt = tlvReader.getUInt(AnonymousTag)
+
+ emit(UIntSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(UIntSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ 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
+ }
+
+ suspend fun subscribeClusterRevisionAttribute(
+ minInterval: Int,
+ maxInterval: Int
+ ): Flow {
+ val ATTRIBUTE_ID: UInt = 65533u
+ val attributePaths =
+ listOf(
+ AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID)
+ )
+
+ val subscribeRequest: SubscribeRequest =
+ SubscribeRequest(
+ eventPaths = emptyList(),
+ attributePaths = attributePaths,
+ minInterval = Duration.ofSeconds(minInterval.toLong()),
+ maxInterval = Duration.ofSeconds(maxInterval.toLong())
+ )
+
+ return controller.subscribe(subscribeRequest).transform { subscriptionState ->
+ when (subscriptionState) {
+ is SubscriptionState.SubscriptionErrorNotification -> {
+ emit(
+ UShortSubscriptionState.Error(
+ Exception(
+ "Subscription terminated with error code: ${subscriptionState.terminationCause}"
+ )
+ )
+ )
+ }
+ is SubscriptionState.NodeStateUpdate -> {
+ val attributeData =
+ subscriptionState.updateState.successes
+ .filterIsInstance()
+ .firstOrNull { it.path.attributeId == ATTRIBUTE_ID }
+
+ requireNotNull(attributeData) {
+ "Clusterrevision attribute not found in Node State update"
+ }
+
+ // Decode the TLV data into the appropriate type
+ val tlvReader = TlvReader(attributeData.data)
+ val decodedValue: UShort = tlvReader.getUShort(AnonymousTag)
+
+ emit(UShortSubscriptionState.Success(decodedValue))
+ }
+ SubscriptionState.SubscriptionEstablished -> {
+ emit(UShortSubscriptionState.SubscriptionEstablished)
+ }
+ }
+ }
+ }
+
+ companion object {
+ private val logger = Logger.getLogger(MeterIdentificationCluster::class.java.name)
+ const val CLUSTER_ID: UInt = 2817u
+ }
+}
diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni
index ff3afa7d53e5fd..b4eb5e87bcdf47 100644
--- a/src/controller/java/generated/java/matter/controller/cluster/files.gni
+++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni
@@ -289,6 +289,7 @@ matter_clusters_sources = [
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/MediaInputCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/MediaPlaybackCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/MessagesCluster.kt",
+ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/MeterIdentificationCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/MicrowaveOvenControlCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/MicrowaveOvenModeCluster.kt",
"${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ModeSelectCluster.kt",
diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
index 6f9ee58cafcadb..1dca7d14159f83 100644
--- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
+++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp
@@ -41481,6 +41481,274 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR
}
break;
}
+ case app::Clusters::MeterIdentification::Id: {
+ using namespace app::Clusters::MeterIdentification;
+ switch (aPath.mAttributeId)
+ {
+ case Attributes::MeterType::Id: {
+ using TypeInfo = Attributes::MeterType::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ std::string valueClassName = "java/lang/Integer";
+ std::string valueCtorSignature = "(I)V";
+ jint jnivalue = static_cast(cppValue.Value());
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(),
+ jnivalue, value);
+ }
+ return value;
+ }
+ case Attributes::CustomerName::Id: {
+ using TypeInfo = Attributes::CustomerName::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.Value(), value));
+ }
+ return value;
+ }
+ case Attributes::UtilityName::Id: {
+ using TypeInfo = Attributes::UtilityName::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.Value(), value));
+ }
+ return value;
+ }
+ case Attributes::PointOfDelivery::Id: {
+ using TypeInfo = Attributes::PointOfDelivery::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.Value(), value));
+ }
+ return value;
+ }
+ case Attributes::PowerThreshold::Id: {
+ using TypeInfo = Attributes::PowerThreshold::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ std::string valueClassName = "java/lang/Long";
+ std::string valueCtorSignature = "(J)V";
+ jlong jnivalue = static_cast(cppValue.Value());
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(),
+ jnivalue, value);
+ }
+ return value;
+ }
+ case Attributes::PowerThresholdSource::Id: {
+ using TypeInfo = Attributes::PowerThresholdSource::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ if (cppValue.IsNull())
+ {
+ value = nullptr;
+ }
+ else
+ {
+ std::string valueClassName = "java/lang/Integer";
+ std::string valueCtorSignature = "(I)V";
+ jint jnivalue = static_cast(cppValue.Value());
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(),
+ jnivalue, value);
+ }
+ return value;
+ }
+ case Attributes::GeneratedCommandList::Id: {
+ using TypeInfo = Attributes::GeneratedCommandList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::AcceptedCommandList::Id: {
+ using TypeInfo = Attributes::AcceptedCommandList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::EventList::Id: {
+ using TypeInfo = Attributes::EventList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::AttributeList::Id: {
+ using TypeInfo = Attributes::AttributeList::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ chip::JniReferences::GetInstance().CreateArrayList(value);
+
+ auto iter_value_0 = cppValue.begin();
+ while (iter_value_0.Next())
+ {
+ auto & entry_0 = iter_value_0.GetValue();
+ jobject newElement_0;
+ std::string newElement_0ClassName = "java/lang/Long";
+ std::string newElement_0CtorSignature = "(J)V";
+ jlong jninewElement_0 = static_cast(entry_0);
+ chip::JniReferences::GetInstance().CreateBoxedObject(
+ newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0);
+ chip::JniReferences::GetInstance().AddToList(value, newElement_0);
+ }
+ return value;
+ }
+ case Attributes::FeatureMap::Id: {
+ using TypeInfo = Attributes::FeatureMap::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ std::string valueClassName = "java/lang/Long";
+ std::string valueCtorSignature = "(J)V";
+ jlong jnivalue = static_cast(cppValue);
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(),
+ jnivalue, value);
+ return value;
+ }
+ case Attributes::ClusterRevision::Id: {
+ using TypeInfo = Attributes::ClusterRevision::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = app::DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR)
+ {
+ return nullptr;
+ }
+ jobject value;
+ std::string valueClassName = "java/lang/Integer";
+ std::string valueCtorSignature = "(I)V";
+ jint jnivalue = static_cast(cppValue);
+ chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue,
+ value);
+ return value;
+ }
+ default:
+ *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB;
+ break;
+ }
+ break;
+ }
case app::Clusters::ElectricalMeasurement::Id: {
using namespace app::Clusters::ElectricalMeasurement;
switch (aPath.mAttributeId)
diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp
index 0df7c762b20da8..422ebfa3f82305 100644
--- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp
+++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp
@@ -7910,6 +7910,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader &
}
break;
}
+ case app::Clusters::MeterIdentification::Id: {
+ using namespace app::Clusters::MeterIdentification;
+ switch (aPath.mEventId)
+ {
+ default:
+ *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB;
+ break;
+ }
+ break;
+ }
case app::Clusters::ElectricalMeasurement::Id: {
using namespace app::Clusters::ElectricalMeasurement;
switch (aPath.mEventId)
diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py
index c89a767203ce71..eb01aeeb749dda 100644
--- a/src/controller/python/chip/clusters/CHIPClusters.py
+++ b/src/controller/python/chip/clusters/CHIPClusters.py
@@ -12994,6 +12994,87 @@ class ChipClusters:
},
},
}
+ _METER_IDENTIFICATION_CLUSTER_INFO = {
+ "clusterName": "MeterIdentification",
+ "clusterId": 0x00000B01,
+ "commands": {
+ },
+ "attributes": {
+ 0x00000000: {
+ "attributeName": "MeterType",
+ "attributeId": 0x00000000,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x00000001: {
+ "attributeName": "CustomerName",
+ "attributeId": 0x00000001,
+ "type": "str",
+ "reportable": True,
+ "writable": True,
+ },
+ 0x00000002: {
+ "attributeName": "UtilityName",
+ "attributeId": 0x00000002,
+ "type": "str",
+ "reportable": True,
+ },
+ 0x00000003: {
+ "attributeName": "PointOfDelivery",
+ "attributeId": 0x00000003,
+ "type": "str",
+ "reportable": True,
+ },
+ 0x00000004: {
+ "attributeName": "PowerThreshold",
+ "attributeId": 0x00000004,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x00000005: {
+ "attributeName": "PowerThresholdSource",
+ "attributeId": 0x00000005,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFF8: {
+ "attributeName": "GeneratedCommandList",
+ "attributeId": 0x0000FFF8,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFF9: {
+ "attributeName": "AcceptedCommandList",
+ "attributeId": 0x0000FFF9,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFA: {
+ "attributeName": "EventList",
+ "attributeId": 0x0000FFFA,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFB: {
+ "attributeName": "AttributeList",
+ "attributeId": 0x0000FFFB,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFC: {
+ "attributeName": "FeatureMap",
+ "attributeId": 0x0000FFFC,
+ "type": "int",
+ "reportable": True,
+ },
+ 0x0000FFFD: {
+ "attributeName": "ClusterRevision",
+ "attributeId": 0x0000FFFD,
+ "type": "int",
+ "reportable": True,
+ },
+ },
+ }
_ELECTRICAL_MEASUREMENT_CLUSTER_INFO = {
"clusterName": "ElectricalMeasurement",
"clusterId": 0x00000B04,
@@ -14896,6 +14977,7 @@ class ChipClusters:
0x0000050E: _ACCOUNT_LOGIN_CLUSTER_INFO,
0x0000050F: _CONTENT_CONTROL_CLUSTER_INFO,
0x00000510: _CONTENT_APP_OBSERVER_CLUSTER_INFO,
+ 0x00000B01: _METER_IDENTIFICATION_CLUSTER_INFO,
0x00000B04: _ELECTRICAL_MEASUREMENT_CLUSTER_INFO,
0xFFF1FC05: _UNIT_TESTING_CLUSTER_INFO,
0xFFF1FC06: _FAULT_INJECTION_CLUSTER_INFO,
@@ -15020,6 +15102,7 @@ class ChipClusters:
"AccountLogin": _ACCOUNT_LOGIN_CLUSTER_INFO,
"ContentControl": _CONTENT_CONTROL_CLUSTER_INFO,
"ContentAppObserver": _CONTENT_APP_OBSERVER_CLUSTER_INFO,
+ "MeterIdentification": _METER_IDENTIFICATION_CLUSTER_INFO,
"ElectricalMeasurement": _ELECTRICAL_MEASUREMENT_CLUSTER_INFO,
"UnitTesting": _UNIT_TESTING_CLUSTER_INFO,
"FaultInjection": _FAULT_INJECTION_CLUSTER_INFO,
diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py
index 1a3bb036add4b7..98e6aec02fe554 100644
--- a/src/controller/python/chip/clusters/Objects.py
+++ b/src/controller/python/chip/clusters/Objects.py
@@ -45353,6 +45353,260 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
value: 'uint' = 0
+@dataclass
+class MeterIdentification(Cluster):
+ id: typing.ClassVar[int] = 0x00000B01
+
+ @ChipUtility.classproperty
+ def descriptor(cls) -> ClusterObjectDescriptor:
+ return ClusterObjectDescriptor(
+ Fields=[
+ ClusterObjectFieldDescriptor(Label="meterType", Tag=0x00000000, Type=typing.Union[Nullable, MeterIdentification.Enums.MeterTypeEnum]),
+ ClusterObjectFieldDescriptor(Label="customerName", Tag=0x00000001, Type=typing.Union[Nullable, str]),
+ ClusterObjectFieldDescriptor(Label="utilityName", Tag=0x00000002, Type=typing.Union[Nullable, str]),
+ ClusterObjectFieldDescriptor(Label="pointOfDelivery", Tag=0x00000003, Type=typing.Union[Nullable, str]),
+ ClusterObjectFieldDescriptor(Label="powerThreshold", Tag=0x00000004, Type=typing.Union[Nullable, int]),
+ ClusterObjectFieldDescriptor(Label="powerThresholdSource", Tag=0x00000005, Type=typing.Union[Nullable, MeterIdentification.Enums.PowerThresholdSourceEnum]),
+ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]),
+ ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint),
+ ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint),
+ ])
+
+ meterType: 'typing.Union[Nullable, MeterIdentification.Enums.MeterTypeEnum]' = None
+ customerName: 'typing.Union[Nullable, str]' = None
+ utilityName: 'typing.Union[Nullable, str]' = None
+ pointOfDelivery: 'typing.Union[Nullable, str]' = None
+ powerThreshold: 'typing.Union[Nullable, int]' = None
+ powerThresholdSource: 'typing.Union[Nullable, MeterIdentification.Enums.PowerThresholdSourceEnum]' = None
+ generatedCommandList: 'typing.List[uint]' = None
+ acceptedCommandList: 'typing.List[uint]' = None
+ eventList: 'typing.List[uint]' = None
+ attributeList: 'typing.List[uint]' = None
+ featureMap: 'uint' = None
+ clusterRevision: 'uint' = None
+
+ class Enums:
+ class MeterTypeEnum(MatterIntEnum):
+ kUtility = 0x00
+ kPrivate = 0x01
+ kGeneric = 0x02
+ # All received enum values that are not listed above will be mapped
+ # to kUnknownEnumValue. This is a helper enum value that should only
+ # be used by code to process how it handles receiving and unknown
+ # enum value. This specific should never be transmitted.
+ kUnknownEnumValue = 3,
+
+ class PowerThresholdSourceEnum(MatterIntEnum):
+ kContract = 0x00
+ kRegulator = 0x01
+ kEquipment = 0x02
+ # All received enum values that are not listed above will be mapped
+ # to kUnknownEnumValue. This is a helper enum value that should only
+ # be used by code to process how it handles receiving and unknown
+ # enum value. This specific should never be transmitted.
+ kUnknownEnumValue = 3,
+
+ class Bitmaps:
+ class Feature(IntFlag):
+ kPowerThreshold = 0x1
+
+ class Attributes:
+ @dataclass
+ class MeterType(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000000
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, MeterIdentification.Enums.MeterTypeEnum])
+
+ value: 'typing.Union[Nullable, MeterIdentification.Enums.MeterTypeEnum]' = NullValue
+
+ @dataclass
+ class CustomerName(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000001
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, str])
+
+ value: 'typing.Union[Nullable, str]' = NullValue
+
+ @dataclass
+ class UtilityName(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000002
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, str])
+
+ value: 'typing.Union[Nullable, str]' = NullValue
+
+ @dataclass
+ class PointOfDelivery(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000003
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, str])
+
+ value: 'typing.Union[Nullable, str]' = NullValue
+
+ @dataclass
+ class PowerThreshold(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000004
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int])
+
+ value: 'typing.Union[Nullable, int]' = NullValue
+
+ @dataclass
+ class PowerThresholdSource(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x00000005
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, MeterIdentification.Enums.PowerThresholdSourceEnum])
+
+ value: 'typing.Union[Nullable, MeterIdentification.Enums.PowerThresholdSourceEnum]' = NullValue
+
+ @dataclass
+ class GeneratedCommandList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFF8
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class AcceptedCommandList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFF9
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class EventList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFA
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class AttributeList(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFB
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=typing.List[uint])
+
+ value: 'typing.List[uint]' = field(default_factory=lambda: [])
+
+ @dataclass
+ class FeatureMap(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFC
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=uint)
+
+ value: 'uint' = 0
+
+ @dataclass
+ class ClusterRevision(ClusterAttributeDescriptor):
+ @ChipUtility.classproperty
+ def cluster_id(cls) -> int:
+ return 0x00000B01
+
+ @ChipUtility.classproperty
+ def attribute_id(cls) -> int:
+ return 0x0000FFFD
+
+ @ChipUtility.classproperty
+ def attribute_type(cls) -> ClusterObjectFieldDescriptor:
+ return ClusterObjectFieldDescriptor(Type=uint)
+
+ value: 'uint' = 0
+
+
@dataclass
class ElectricalMeasurement(Cluster):
id: typing.ClassVar[int] = 0x00000B04
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm
index 603647682805f6..2ac9ead6750a1d 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm
@@ -5900,6 +5900,51 @@ static BOOL AttributeIsSpecifiedInContentAppObserverCluster(AttributeId aAttribu
}
}
}
+static BOOL AttributeIsSpecifiedInMeterIdentificationCluster(AttributeId aAttributeId)
+{
+ using namespace Clusters::MeterIdentification;
+ switch (aAttributeId) {
+ case Attributes::MeterType::Id: {
+ return YES;
+ }
+ case Attributes::CustomerName::Id: {
+ return YES;
+ }
+ case Attributes::UtilityName::Id: {
+ return YES;
+ }
+ case Attributes::PointOfDelivery::Id: {
+ return YES;
+ }
+ case Attributes::PowerThreshold::Id: {
+ return YES;
+ }
+ case Attributes::PowerThresholdSource::Id: {
+ return YES;
+ }
+ case Attributes::GeneratedCommandList::Id: {
+ return YES;
+ }
+ case Attributes::AcceptedCommandList::Id: {
+ return YES;
+ }
+ case Attributes::EventList::Id: {
+ return YES;
+ }
+ case Attributes::AttributeList::Id: {
+ return YES;
+ }
+ case Attributes::FeatureMap::Id: {
+ return YES;
+ }
+ case Attributes::ClusterRevision::Id: {
+ return YES;
+ }
+ default: {
+ return NO;
+ }
+ }
+}
static BOOL AttributeIsSpecifiedInElectricalMeasurementCluster(AttributeId aAttributeId)
{
using namespace Clusters::ElectricalMeasurement;
@@ -6963,6 +7008,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId)
case Clusters::ContentAppObserver::Id: {
return AttributeIsSpecifiedInContentAppObserverCluster(aAttributeId);
}
+ case Clusters::MeterIdentification::Id: {
+ return AttributeIsSpecifiedInMeterIdentificationCluster(aAttributeId);
+ }
case Clusters::ElectricalMeasurement::Id: {
return AttributeIsSpecifiedInElectricalMeasurementCluster(aAttributeId);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
index fdc2820cc0d584..18fa03db36838f 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm
@@ -16610,6 +16610,123 @@ static id _Nullable DecodeAttributeValueForContentAppObserverCluster(AttributeId
*aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB;
return nil;
}
+static id _Nullable DecodeAttributeValueForMeterIdentificationCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
+{
+ using namespace Clusters::MeterIdentification;
+ switch (aAttributeId) {
+ case Attributes::MeterType::Id: {
+ using TypeInfo = Attributes::MeterType::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSNumber * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value())];
+ }
+ return value;
+ }
+ case Attributes::CustomerName::Id: {
+ using TypeInfo = Attributes::CustomerName::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSString * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = AsString(cppValue.Value());
+ if (value == nil) {
+ CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT;
+ *aError = err;
+ return nil;
+ }
+ }
+ return value;
+ }
+ case Attributes::UtilityName::Id: {
+ using TypeInfo = Attributes::UtilityName::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSString * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = AsString(cppValue.Value());
+ if (value == nil) {
+ CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT;
+ *aError = err;
+ return nil;
+ }
+ }
+ return value;
+ }
+ case Attributes::PointOfDelivery::Id: {
+ using TypeInfo = Attributes::PointOfDelivery::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSString * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = AsString(cppValue.Value());
+ if (value == nil) {
+ CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT;
+ *aError = err;
+ return nil;
+ }
+ }
+ return value;
+ }
+ case Attributes::PowerThreshold::Id: {
+ using TypeInfo = Attributes::PowerThreshold::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSNumber * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = [NSNumber numberWithLongLong:cppValue.Value()];
+ }
+ return value;
+ }
+ case Attributes::PowerThresholdSource::Id: {
+ using TypeInfo = Attributes::PowerThresholdSource::TypeInfo;
+ TypeInfo::DecodableType cppValue;
+ *aError = DataModel::Decode(aReader, cppValue);
+ if (*aError != CHIP_NO_ERROR) {
+ return nil;
+ }
+ NSNumber * _Nullable value;
+ if (cppValue.IsNull()) {
+ value = nil;
+ } else {
+ value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value())];
+ }
+ return value;
+ }
+ default: {
+ break;
+ }
+ }
+
+ *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB;
+ return nil;
+}
static id _Nullable DecodeAttributeValueForElectricalMeasurementCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
{
using namespace Clusters::ElectricalMeasurement;
@@ -19825,6 +19942,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T
case Clusters::ContentAppObserver::Id: {
return DecodeAttributeValueForContentAppObserverCluster(aPath.mAttributeId, aReader, aError);
}
+ case Clusters::MeterIdentification::Id: {
+ return DecodeAttributeValueForMeterIdentificationCluster(aPath.mAttributeId, aReader, aError);
+ }
case Clusters::ElectricalMeasurement::Id: {
return DecodeAttributeValueForElectricalMeasurementCluster(aPath.mAttributeId, aReader, aError);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
index 35f0a1d1b0e18f..7fd469c1e99f28 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h
@@ -14741,6 +14741,105 @@ MTR_PROVISIONALLY_AVAILABLE
@end
+/**
+ * Cluster Meter Identification
+ *
+ * This cluster provides attributes for determining advanced information about utility metering device.
+ */
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRBaseClusterMeterIdentification : MTRGenericBaseCluster
+
+- (void)readAttributeMeterTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeMeterTypeWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeMeterTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeCustomerNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributeCustomerNameWithValue:(NSString * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributeCustomerNameWithValue:(NSString * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeCustomerNameWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeCustomerNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeUtilityNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeUtilityNameWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeUtilityNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributePointOfDeliveryWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributePointOfDeliveryWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributePointOfDeliveryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributePowerThresholdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributePowerThresholdWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributePowerThresholdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributePowerThresholdSourceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributePowerThresholdSourceWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributePowerThresholdSourceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE;
++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+@end
+
+@interface MTRBaseClusterMeterIdentification (Availability)
+
+/**
+ * For all instance methods (reads, writes, commands) that take a completion,
+ * the completion will be called on the provided queue.
+ */
+- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device
+ endpointID:(NSNumber *)endpointID
+ queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE;
+
+@end
+
/**
* Cluster Electrical Measurement
*
@@ -20208,6 +20307,22 @@ typedef NS_ENUM(uint8_t, MTRContentAppObserverStatus) {
MTRContentAppObserverStatusUnexpectedData MTR_PROVISIONALLY_AVAILABLE = 0x01,
} MTR_PROVISIONALLY_AVAILABLE;
+typedef NS_ENUM(uint8_t, MTRMeterIdentificationMeterType) {
+ MTRMeterIdentificationMeterTypeUtility MTR_PROVISIONALLY_AVAILABLE = 0x00,
+ MTRMeterIdentificationMeterTypePrivate MTR_PROVISIONALLY_AVAILABLE = 0x01,
+ MTRMeterIdentificationMeterTypeGeneric MTR_PROVISIONALLY_AVAILABLE = 0x02,
+} MTR_PROVISIONALLY_AVAILABLE;
+
+typedef NS_ENUM(uint8_t, MTRMeterIdentificationPowerThresholdSource) {
+ MTRMeterIdentificationPowerThresholdSourceContract MTR_PROVISIONALLY_AVAILABLE = 0x00,
+ MTRMeterIdentificationPowerThresholdSourceRegulator MTR_PROVISIONALLY_AVAILABLE = 0x01,
+ MTRMeterIdentificationPowerThresholdSourceEquipment MTR_PROVISIONALLY_AVAILABLE = 0x02,
+} MTR_PROVISIONALLY_AVAILABLE;
+
+typedef NS_OPTIONS(uint32_t, MTRMeterIdentificationFeature) {
+ MTRMeterIdentificationFeaturePowerThreshold MTR_PROVISIONALLY_AVAILABLE = 0x1,
+} MTR_PROVISIONALLY_AVAILABLE;
+
typedef NS_ENUM(uint8_t, MTRUnitTestingSimple) {
MTRUnitTestingSimpleUnspecified MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00,
MTRUnitTestingSimpleValueA MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x01,
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm
index f5ad47a7917dd0..8844f75db471d5 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm
@@ -103589,6 +103589,475 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC
@end
+@implementation MTRBaseClusterMeterIdentification
+
+- (void)readAttributeMeterTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::MeterType::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeMeterTypeWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::MeterType::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeMeterTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::MeterType::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeCustomerNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::CustomerName::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)writeAttributeCustomerNameWithValue:(NSString * _Nullable)value completion:(MTRStatusCompletion)completion
+{
+ [self writeAttributeCustomerNameWithValue:(NSString * _Nullable) value params:nil completion:completion];
+}
+- (void)writeAttributeCustomerNameWithValue:(NSString * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion
+{
+ // Make a copy of params before we go async.
+ params = [params copy];
+ value = [value copy];
+
+ auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
+ chip::Optional timedWriteTimeout;
+ if (params != nil) {
+ if (params.timedWriteTimeout != nil){
+ timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
+ }
+ }
+
+ ListFreer listFreer;
+ using TypeInfo = MeterIdentification::Attributes::CustomerName::TypeInfo;
+ TypeInfo::Type cppValue;
+ if (value == nil) {
+ cppValue.SetNull();
+ } else {
+ auto & nonNullValue_0 = cppValue.SetNonNull();
+ nonNullValue_0 = AsCharSpan(value);
+ }
+
+ chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue);
+ return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); });
+ std::move(*bridge).DispatchAction(self.device);
+}
+
+- (void)subscribeAttributeCustomerNameWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::CustomerName::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeCustomerNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::CustomerName::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeUtilityNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::UtilityName::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeUtilityNameWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::UtilityName::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeUtilityNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::UtilityName::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributePointOfDeliveryWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::PointOfDelivery::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributePointOfDeliveryWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::PointOfDelivery::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributePointOfDeliveryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::PointOfDelivery::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributePowerThresholdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::PowerThreshold::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributePowerThresholdWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::PowerThreshold::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributePowerThresholdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::PowerThreshold::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributePowerThresholdSourceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::PowerThresholdSource::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributePowerThresholdSourceWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::PowerThresholdSource::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributePowerThresholdSourceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::PowerThresholdSource::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::GeneratedCommandList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::GeneratedCommandList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::GeneratedCommandList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::AcceptedCommandList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::AcceptedCommandList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::AcceptedCommandList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::EventList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::EventList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::EventList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::AttributeList::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::AttributeList::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::AttributeList::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::FeatureMap::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::FeatureMap::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::FeatureMap::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::ClusterRevision::TypeInfo;
+ [self.device _readKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:nil
+ queue:self.callbackQueue
+ completion:completion];
+}
+
+- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
+ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
+ reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
+{
+ using TypeInfo = MeterIdentification::Attributes::ClusterRevision::TypeInfo;
+ [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID
+ clusterID:@(TypeInfo::GetClusterId())
+ attributeID:@(TypeInfo::GetAttributeId())
+ params:params
+ queue:self.callbackQueue
+ reportHandler:reportHandler
+ subscriptionEstablished:subscriptionEstablished];
+}
+
++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
+{
+ using TypeInfo = MeterIdentification::Attributes::ClusterRevision::TypeInfo;
+ [clusterStateCacheContainer
+ _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue])
+ clusterID:TypeInfo::GetClusterId()
+ attributeID:TypeInfo::GetAttributeId()
+ queue:queue
+ completion:completion];
+}
+
+@end
+
@implementation MTRBaseClusterElectricalMeasurement
- (void)getProfileInfoCommandWithCompletion:(MTRStatusCompletion)completion
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h
index da9c24e4c35beb..5ee1044853b6fb 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h
@@ -201,6 +201,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) {
MTRClusterIDTypeAccountLoginID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000050E,
MTRClusterIDTypeContentControlID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F,
MTRClusterIDTypeContentAppObserverID MTR_PROVISIONALLY_AVAILABLE = 0x00000510,
+ MTRClusterIDTypeMeterIdentificationID MTR_PROVISIONALLY_AVAILABLE = 0x00000B01,
MTRClusterIDTypeElectricalMeasurementID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000B04,
MTRClusterIDTypeUnitTestingID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0xFFF1FC05,
MTRClusterIDTypeSampleMEIID MTR_PROVISIONALLY_AVAILABLE = 0xFFF1FC20,
@@ -4842,6 +4843,20 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) {
MTRAttributeIDTypeClusterContentAppObserverAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID,
MTRAttributeIDTypeClusterContentAppObserverAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID,
+ // Cluster MeterIdentification attributes
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeMeterTypeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeCustomerNameID MTR_PROVISIONALLY_AVAILABLE = 0x00000001,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeUtilityNameID MTR_PROVISIONALLY_AVAILABLE = 0x00000002,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributePointOfDeliveryID MTR_PROVISIONALLY_AVAILABLE = 0x00000003,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributePowerThresholdID MTR_PROVISIONALLY_AVAILABLE = 0x00000004,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributePowerThresholdSourceID MTR_PROVISIONALLY_AVAILABLE = 0x00000005,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID,
+ MTRAttributeIDTypeClusterMeterIdentificationAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID,
+
// Cluster ElectricalMeasurement deprecated attribute names
MTRClusterElectricalMeasurementAttributeMeasurementTypeID
MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterElectricalMeasurementAttributeMeasurementTypeID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4))
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm
index 5ca3b9058c217a..910e3d4e3483b4 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm
@@ -369,6 +369,9 @@
case MTRClusterIDTypeContentAppObserverID:
result = @"ContentAppObserver";
break;
+ case MTRClusterIDTypeMeterIdentificationID:
+ result = @"MeterIdentification";
+ break;
case MTRClusterIDTypeElectricalMeasurementID:
result = @"ElectricalMeasurement";
break;
@@ -8003,6 +8006,64 @@
break;
}
+ case MTRClusterIDTypeMeterIdentificationID:
+
+ switch (attributeID) {
+
+ // Cluster MeterIdentification attributes
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeMeterTypeID:
+ result = @"MeterType";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeCustomerNameID:
+ result = @"CustomerName";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeUtilityNameID:
+ result = @"UtilityName";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributePointOfDeliveryID:
+ result = @"PointOfDelivery";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributePowerThresholdID:
+ result = @"PowerThreshold";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributePowerThresholdSourceID:
+ result = @"PowerThresholdSource";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeGeneratedCommandListID:
+ result = @"GeneratedCommandList";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeAcceptedCommandListID:
+ result = @"AcceptedCommandList";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeEventListID:
+ result = @"EventList";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeAttributeListID:
+ result = @"AttributeList";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeFeatureMapID:
+ result = @"FeatureMap";
+ break;
+
+ case MTRAttributeIDTypeClusterMeterIdentificationAttributeClusterRevisionID:
+ result = @"ClusterRevision";
+ break;
+
+ default:
+ result = [NSString stringWithFormat:@"", attributeID];
+ break;
+ }
+
case MTRClusterIDTypeElectricalMeasurementID:
switch (attributeID) {
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h
index e2a0873cee6392..a95523113b4263 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h
@@ -6836,6 +6836,56 @@ MTR_PROVISIONALLY_AVAILABLE
@end
+/**
+ * Cluster Meter Identification
+ * This cluster provides attributes for determining advanced information about utility metering device.
+ */
+MTR_PROVISIONALLY_AVAILABLE
+@interface MTRClusterMeterIdentification : MTRGenericCluster
+
+- (NSDictionary * _Nullable)readAttributeMeterTypeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeCustomerNameWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributeCustomerNameWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE;
+- (void)writeAttributeCustomerNameWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeUtilityNameWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributePointOfDeliveryWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributePowerThresholdWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributePowerThresholdSourceWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE;
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+@end
+
+@interface MTRClusterMeterIdentification (Availability)
+
+/**
+ * The queue is currently unused, but may be used in the future for calling completions
+ * for command invocations if commands are added to this cluster.
+ */
+- (instancetype _Nullable)initWithDevice:(MTRDevice *)device
+ endpointID:(NSNumber *)endpointID
+ queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE;
+
+@end
+
/**
* Cluster Electrical Measurement
* Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster..
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm
index 953df0cde7fa90..c79aaec0eac0b1 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm
@@ -19641,6 +19641,81 @@ - (void)contentAppMessageWithParams:(MTRContentAppObserverClusterContentAppMessa
@end
+@implementation MTRClusterMeterIdentification
+
+- (NSDictionary * _Nullable)readAttributeMeterTypeWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeMeterTypeID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeCustomerNameWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeCustomerNameID) params:params];
+}
+
+- (void)writeAttributeCustomerNameWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs
+{
+ [self writeAttributeCustomerNameWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil];
+}
+- (void)writeAttributeCustomerNameWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params
+{
+ NSNumber * timedWriteTimeout = params.timedWriteTimeout;
+
+ [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeCustomerNameID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout];
+}
+
+- (NSDictionary * _Nullable)readAttributeUtilityNameWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeUtilityNameID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributePointOfDeliveryWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributePointOfDeliveryID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributePowerThresholdWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributePowerThresholdID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributePowerThresholdSourceWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributePowerThresholdSourceID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeGeneratedCommandListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeAcceptedCommandListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeEventListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeAttributeListID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeFeatureMapID) params:params];
+}
+
+- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params
+{
+ return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMeterIdentificationID) attributeID:@(MTRAttributeIDTypeClusterMeterIdentificationAttributeClusterRevisionID) params:params];
+}
+
+@end
+
@implementation MTRClusterElectricalMeasurement
- (void)getProfileInfoCommandWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm
index f49e574232b544..8c897363902ed6 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm
@@ -1127,6 +1127,15 @@ static BOOL CommandNeedsTimedInvokeInContentAppObserverCluster(AttributeId aAttr
}
}
}
+static BOOL CommandNeedsTimedInvokeInMeterIdentificationCluster(AttributeId aAttributeId)
+{
+ using namespace Clusters::MeterIdentification;
+ switch (aAttributeId) {
+ default: {
+ return NO;
+ }
+ }
+}
static BOOL CommandNeedsTimedInvokeInElectricalMeasurementCluster(AttributeId aAttributeId)
{
using namespace Clusters::ElectricalMeasurement;
@@ -1506,6 +1515,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn
case Clusters::ContentAppObserver::Id: {
return CommandNeedsTimedInvokeInContentAppObserverCluster(commandID);
}
+ case Clusters::MeterIdentification::Id: {
+ return CommandNeedsTimedInvokeInMeterIdentificationCluster(commandID);
+ }
case Clusters::ElectricalMeasurement::Id: {
return CommandNeedsTimedInvokeInElectricalMeasurementCluster(commandID);
}
diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm
index db48844fca89ee..fe7fdb048ffc2c 100644
--- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm
+++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm
@@ -4404,6 +4404,18 @@ static id _Nullable DecodeEventPayloadForContentAppObserverCluster(EventId aEven
*aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB;
return nil;
}
+static id _Nullable DecodeEventPayloadForMeterIdentificationCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
+{
+ using namespace Clusters::MeterIdentification;
+ switch (aEventId) {
+ default: {
+ break;
+ }
+ }
+
+ *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB;
+ return nil;
+}
static id _Nullable DecodeEventPayloadForElectricalMeasurementCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError)
{
using namespace Clusters::ElectricalMeasurement;
@@ -4940,6 +4952,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead
case Clusters::ContentAppObserver::Id: {
return DecodeEventPayloadForContentAppObserverCluster(aPath.mEventId, aReader, aError);
}
+ case Clusters::MeterIdentification::Id: {
+ return DecodeEventPayloadForMeterIdentificationCluster(aPath.mEventId, aReader, aError);
+ }
case Clusters::ElectricalMeasurement::Id: {
return DecodeEventPayloadForElectricalMeasurementCluster(aPath.mEventId, aReader, aError);
}
diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp
index 9a952b67e21b17..51a493d1e63866 100644
--- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp
+++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp
@@ -37936,6 +37936,649 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu
} // namespace Attributes
} // namespace ContentAppObserver
+namespace MeterIdentification {
+namespace Attributes {
+
+namespace MeterType {
+
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint,
+ DataModel::Nullable & value)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType temp;
+ uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
+ Protocols::InteractionModel::Status status =
+ emberAfReadAttribute(endpoint, Clusters::MeterIdentification::Id, Id, readable, sizeof(temp));
+ VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status);
+ if (Traits::IsNullValue(temp))
+ {
+ value.SetNull();
+ }
+ else
+ {
+ value.SetNonNull() = Traits::StorageToWorking(temp);
+ }
+ return status;
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::MeterIdentification::MeterTypeEnum value,
+ MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::MeterIdentification::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty);
+}
+
+Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::MeterIdentification::MeterTypeEnum value)
+{
+ using Traits = NumericAttributeTraits;
+ if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
+ {
+ return Protocols::InteractionModel::Status::ConstraintError;
+ }
+ Traits::StorageType storageValue;
+ Traits::WorkingToStorage(value, storageValue);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
+ return emberAfWriteAttribute(endpoint, Clusters::MeterIdentification::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
+}
+
+Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType value;
+ Traits::SetNull(value);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
+ return emberAfWriteAttribute(endpoint, Clusters::MeterIdentification::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty);
+}
+
+Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint)
+{
+ using Traits = NumericAttributeTraits;
+ Traits::StorageType value;
+ Traits::SetNull(value);
+ uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
+ return emberAfWriteAttribute(endpoint, Clusters::MeterIdentification::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
+}
+
+Protocols::InteractionModel::Status
+Set(chip::EndpointId endpoint,
+ const chip::app::DataModel::Nullable & value,
+ MarkAttributeDirty markDirty)
+{
+ if (value.IsNull())
+ {
+ return SetNull(endpoint, markDirty);
+ }
+
+ return Set(endpoint, value.Value(), markDirty);
+}
+
+Protocols::InteractionModel::Status
+Set(chip::EndpointId endpoint,
+ const chip::app::DataModel::Nullable & value)
+{
+ if (value.IsNull())
+ {
+ return SetNull(endpoint);
+ }
+
+ return Set(endpoint, value.Value());
+}
+
+} // namespace MeterType
+
+namespace CustomerName {
+
+Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value)
+{
+ if (value.IsNull())
+ {
+ ChipLogError(Zcl, "Null Nullable passed to MeterIdentification::CustomerName::Get");
+ return Protocols::InteractionModel::Status::Failure;
+ }
+
+ uint8_t zclString[64 + 1];
+ Protocols::InteractionModel::Status status =
+ emberAfReadAttribute(endpoint, Clusters::MeterIdentification::Id, Id, zclString, sizeof(zclString));
+ VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status);
+ size_t length = emberAfStringLength(zclString);
+ if (length == NumericAttributeTraits