Merge branch 'master' into asuppercamelcase
diff --git a/.github/workflows/matter.yml b/.github/workflows/matter.yml
index be52be3..50420f3 100644
--- a/.github/workflows/matter.yml
+++ b/.github/workflows/matter.yml
@@ -192,7 +192,7 @@
 
     # CHIP container required because clang-format version needs to match
     container:
-      image: connectedhomeip/chip-build:0.6.11
+      image: ghcr.io/project-chip/chip-build:125
 
     steps:
       - uses: actions/download-artifact@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 78c3c0d..72a9247 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -333,6 +333,76 @@
       - name: ZAP binary check (Linux) - unzip cleanup
         if: startsWith(matrix.os, 'ubuntu')
         run: rm -rf dist/zap-linux
+      - name: Verify zap.png exists in package's base directory
+        if: startsWith(matrix.os, 'ubuntu')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: ./node_modules/7zip-bin/linux/x64/7za l ./dist/zap-linux-x64.zip | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in package's app.asar archive
+        if: startsWith(matrix.os, 'ubuntu')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: npx asar l ./dist/linux-unpacked/resources/app.asar | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in Windows x64 .zip package
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: 7za l ./dist/zap-win-x64.zip | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in Windows x64 .zip package's app.asar archive
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: npx asar l ./dist/win-unpacked/resources/app.asar | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in Windows arm64 .zip package
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: 7za l ./dist/zap-win-arm64.zip | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in Windows arm64 .zip package's app.asar archive
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: npx asar l ./dist/win-arm64-unpacked/resources/app.asar | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in macOS x64 .zip package
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: 7za l ./dist/zap-mac-x64.zip | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in macOS x64 .zip package's app-x64.asar archive
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: npx asar l ./dist/mac/zap.app/Contents/Resources/app-x64.asar | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in macOS arm64 .zip package
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: 7za l ./dist/zap-mac-arm64.zip | grep zap.png
+          contains: 'zap.png'
+
+      - name: Verify zap.png exists in macOS arm64 .zip package's app-arm64.asar archive
+        if: startsWith(matrix.os, 'macos')
+        uses: GuillaumeFalourd/assert-command-line-output@v2.1
+        with:
+          command_line: npx asar l ./dist/mac-arm64/zap.app/Contents/Resources/app-arm64.asar | grep zap.png
+          contains: 'zap.png'
+
       - name: Verify apack.json exists in package's base directory
         if: startsWith(matrix.os, 'ubuntu')
         uses: GuillaumeFalourd/assert-command-line-output@v2.1
diff --git a/apack.json b/apack.json
index 6d5bae0..6c5bb2c 100644
--- a/apack.json
+++ b/apack.json
@@ -55,6 +55,7 @@
       "id": "ZAP",
       "category": "tools",
       "label": "ZCL Advanced Platform",
+      "icon": "zap.png",
       "launchUiFunction": "launchZAP",
       "toolTip": "ZCL Advanced Platform"
     }
diff --git a/cypress/e2e/clusters/cluster-filter.cy.js b/cypress/e2e/clusters/cluster-filter.cy.js
index cf2619b..a694e1c 100644
--- a/cypress/e2e/clusters/cluster-filter.cy.js
+++ b/cypress/e2e/clusters/cluster-filter.cy.js
@@ -13,7 +13,9 @@
     })
     cy.setZclProperties()
     cy.fixture('data').then((data) => {
-      cy.addEndpoint(data.endpoint1, data.cluster1)
+      // Selecting SE Range Extender for Zigbee
+      // Selecting Matter Dimmable Light (0x0101) for Matter
+      cy.addEndpoint(data.endpoint9)
     })
   })
   it(
@@ -21,11 +23,84 @@
     { retries: { runMode: 2, openMode: 2 } },
     () => {
       cy.get('[data-test="filter-input"]').click()
+      // Selecting Enabled clusters
       cy.get('.q-virtual-scroll__content > :nth-child(3)').click({
         force: true
       })
       cy.fixture('data').then((data) => {
-        cy.get('tbody').children().contains(data.cluster2).should('not.exist')
+        // Power Configurator for Zigbee is disabled and should not show up
+        // Occupancy Sensing for Matter is disabled and should not exist
+        cy.get('tbody').children().contains(data.cluster10).should('not.exist')
+        // Basic for Zigbee is enabled and should show up
+        // Identify for Matter is enabled and should show up
+        cy.get('tbody').children().contains(data.cluster11).should('exist')
+      })
+    }
+  )
+  it(
+    'filter legal clusters and check clusters',
+    { retries: { runMode: 2, openMode: 2 } },
+    () => {
+      cy.get('[data-test="filter-input"]').click()
+      // Selecting Legal Clusters
+      cy.get('.q-virtual-scroll__content > :nth-child(4)').click({
+        force: true
+      })
+      cy.fixture('data').then((data) => {
+        // Power Configurator for Zigbee is legal and should show up
+        // Occupancy Sensing for Matter is legal and should show up
+        if (data.cluster10 == 'Power Configuration') {
+          cy.get('tbody')
+            .children()
+            .contains(data.cluster10)
+            .should('exist')
+            .parents('tr')
+            .within(() => {
+              cy.get('div[role="checkbox"][aria-label="Client"]')
+                .should('have.attr', 'aria-checked', 'false')
+                .click({ force: true })
+                .should('have.attr', 'aria-checked', 'false') // Even when clicking on the client checkbox it should not be enabled because of legal cluster filter setting does not allow non Device type clusters to be enabled.
+            })
+          cy.get('tbody')
+            .children()
+            .contains(data.cluster10)
+            .should('exist')
+            .parents('tr')
+            .within(() => {
+              cy.get('div[role="checkbox"][aria-label="Server"]')
+                .should('have.attr', 'aria-checked', 'false')
+                .click({ force: true })
+                .should('have.attr', 'aria-checked', 'true') // when clicking on the server checkbox it should be enabled because of legal cluster filter setting allows it to be selected
+            })
+        } else {
+          // Occupancy Sensing
+          cy.get('tbody')
+            .children()
+            .contains(data.cluster10)
+            .should('exist')
+            .parents('tr')
+            .within(() => {
+              cy.get('div[role="checkbox"][aria-label="Client"]')
+                .should('have.attr', 'aria-checked', 'false')
+                .click({ force: true })
+                .should('have.attr', 'aria-checked', 'true') // when clicking on the server checkbox it should be enabled because of legal cluster filter setting allows it to be selected
+            })
+          cy.get('tbody')
+            .children()
+            .contains(data.cluster10)
+            .should('exist')
+            .parents('tr')
+            .within(() => {
+              cy.get('div[role="checkbox"][aria-label="Server"]')
+                .should('have.attr', 'aria-checked', 'false')
+                .click({ force: true })
+                .should('have.attr', 'aria-checked', 'false') // Even when clicking on the client checkbox it should not be enabled because of legal cluster filter setting does not allow non Device type clusters to be enabled.
+            })
+        }
+
+        // Basic for Zigbee is legal and should show up
+        // Identify for Matter is legal and should show up
+        cy.get('tbody').children().contains(data.cluster11).should('exist')
       })
     }
   )
diff --git a/cypress/fixtures/data.json b/cypress/fixtures/data.json
index c09ce42..e1b52cb 100644
--- a/cypress/fixtures/data.json
+++ b/cypress/fixtures/data.json
@@ -7,6 +7,7 @@
   "endpoint6": "LO Dimmable Light (0x0101)",
   "endpoint7": "Billing Unit (0x0203)",
   "endpoint8": "Billing Unit (0x0203)",
+  "endpoint9": "SE Range Extender (0x0008)",
   "cluster1": "General",
   "cluster2": "Power Configuration",
   "cluster3": "Basic",
@@ -16,6 +17,8 @@
   "cluster7": "Identify",
   "cluster8": "Data Sharing",
   "cluster9": "General",
+  "cluster10": "Power Configuration",
+  "cluster11": "Basic",
   "attribute1": "ZCL version",
   "attribute2": "application version",
   "attribute3": "OTA Upgrade Server ID",
diff --git a/cypress/matterFixtures/data.json b/cypress/matterFixtures/data.json
index 4326dd2..a899f86 100644
--- a/cypress/matterFixtures/data.json
+++ b/cypress/matterFixtures/data.json
@@ -7,6 +7,7 @@
   "endpoint6": "Matter Dimmable Light (0x0101)",
   "endpoint7": "Matter Control Bridge",
   "endpoint8": "Matter Color Temperature Light (0x010C)",
+  "endpoint9": "Matter Dimmable Light (0x0101)",
   "cluster1": "General",
   "cluster2": "On/off Switch Configuration",
   "cluster3": "Basic",
@@ -16,6 +17,8 @@
   "cluster7": "Identify",
   "cluster8": "Pulse Width Modulation",
   "cluster9": "General",
+  "cluster10": "Occupancy Sensing",
+  "cluster11": "Identify",
   "attribute1": "GeneratedCommandList",
   "attribute2": "IdentifyTime",
   "attribute3": "ClusterRevision",
diff --git a/docs/api.md b/docs/api.md
index 2d8291a..83fa303 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -35,7 +35,7 @@
 <dd><p>This module provides queries related to attributes.</p>
 </dd>
 <dt><a href="#module_DB API_ zcl database access">DB API: zcl database access</a></dt>
-<dd><p>This module provides queries for enums.</p>
+<dd><p>This module provides queries for bitmaps.</p>
 </dd>
 <dt><a href="#module_DB API_ cluster queries.">DB API: cluster queries.</a></dt>
 <dd><p>This module provides queries related to cluster.</p>
@@ -877,6 +877,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -886,8 +887,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -1093,6 +1096,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -1222,6 +1241,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -1252,6 +1287,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -1681,6 +1732,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -1690,8 +1742,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -1897,6 +1951,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -2026,6 +2096,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -2056,6 +2142,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -2461,7 +2563,7 @@
 <a name="module_DB API_ zcl database access"></a>
 
 ## DB API: zcl database access
-This module provides queries for enums.
+This module provides queries for bitmaps.
 
 
 * [DB API: zcl database access](#module_DB API_ zcl database access)
@@ -2480,6 +2582,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -2489,8 +2592,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -2696,6 +2801,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -2825,6 +2946,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -2855,6 +2992,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -3287,16 +3440,19 @@
     * [~selectAllDeviceTypes(db, packageId)](#module_DB API_ device type database access..selectAllDeviceTypes) ⇒
     * [~selectDeviceTypeById(db, id)](#module_DB API_ device type database access..selectDeviceTypeById) ⇒
     * [~selectDeviceTypeByCodeAndName(db, packageId, code, name)](#module_DB API_ device type database access..selectDeviceTypeByCodeAndName) ⇒
-    * [~selectDeviceTypeByCode(db, packageId, code, name)](#module_DB API_ device type database access..selectDeviceTypeByCode) ⇒
+    * [~selectDeviceTypeByCode(db, packageId, code)](#module_DB API_ device type database access..selectDeviceTypeByCode) ⇒
     * [~selectDeviceTypeClustersByDeviceTypeRef(db, deviceTypeRef)](#module_DB API_ device type database access..selectDeviceTypeClustersByDeviceTypeRef) ⇒
     * [~selectDeviceTypeClusterByDeviceTypeClusterId(db, deviceTypeClusterId)](#module_DB API_ device type database access..selectDeviceTypeClusterByDeviceTypeClusterId) ⇒
     * [~selectDeviceTypeAttributesByDeviceTypeRef(db, deviceTypeRef)](#module_DB API_ device type database access..selectDeviceTypeAttributesByDeviceTypeRef) ⇒
     * [~selectDeviceTypeCommandsByDeviceTypeRef(db, deviceTypeRef)](#module_DB API_ device type database access..selectDeviceTypeCommandsByDeviceTypeRef) ⇒
-    * [~updateClusterReferencesForDeviceTypeClusters(db)](#module_DB API_ device type database access..updateClusterReferencesForDeviceTypeClusters) ⇒
-    * [~updateAttributeReferencesForDeviceTypeReferences(db)](#module_DB API_ device type database access..updateAttributeReferencesForDeviceTypeReferences) ⇒
-    * [~updateCommandReferencesForDeviceTypeReferences(db)](#module_DB API_ device type database access..updateCommandReferencesForDeviceTypeReferences) ⇒
-    * [~updateFeatureReferencesForDeviceTypeReferences(db)](#module_DB API_ device type database access..updateFeatureReferencesForDeviceTypeReferences) ⇒
+    * [~updateClusterReferencesForDeviceTypeClusters(db, packageId, sessionPackages)](#module_DB API_ device type database access..updateClusterReferencesForDeviceTypeClusters) ⇒
+    * [~updateAttributeReferencesForDeviceTypeReferences(db, packageId, sessionPackages)](#module_DB API_ device type database access..updateAttributeReferencesForDeviceTypeReferences) ⇒
+    * [~updateCommandReferencesForDeviceTypeReferences(db, packageId, sessionPackages)](#module_DB API_ device type database access..updateCommandReferencesForDeviceTypeReferences) ⇒
+    * [~updateFeatureReferencesForDeviceTypeReferences(db, packageId)](#module_DB API_ device type database access..updateFeatureReferencesForDeviceTypeReferences) ⇒
     * [~updateDeviceTypeEntityReferences(db)](#module_DB API_ device type database access..updateDeviceTypeEntityReferences) ⇒
+    * [~updateDeviceTypeReferencesForCustomXml(db, packageId, sessionPackages, sessionId)](#module_DB API_ device type database access..updateDeviceTypeReferencesForCustomXml) ⇒
+    * [~deleteUnlinkedDeviceTypeClusters(db, packageId)](#module_DB API_ device type database access..deleteUnlinkedDeviceTypeClusters)
+    * [~warnUnlinkedDeviceTypeClusters(db, packageId, sessionId)](#module_DB API_ device type database access..warnUnlinkedDeviceTypeClusters)
     * [~selectDeviceTypesWithCompositionByEndpointTypeId(db, endpointTypeId)](#module_DB API_ device type database access..selectDeviceTypesWithCompositionByEndpointTypeId) ⇒ <code>Promise.&lt;Array&gt;</code>
     * [~selectDeviceTypesByEndpointTypeId(db, endpointTypeId)](#module_DB API_ device type database access..selectDeviceTypesByEndpointTypeId) ⇒
     * [~selectDeviceTypeFeaturesByEndpointTypeIdAndClusterId(db, endpointTypeId, clusterId)](#module_DB API_ device type database access..selectDeviceTypeFeaturesByEndpointTypeIdAndClusterId) ⇒
@@ -3344,7 +3500,7 @@
 
 <a name="module_DB API_ device type database access..selectDeviceTypeByCode"></a>
 
-### DB API: device type database access~selectDeviceTypeByCode(db, packageId, code, name) ⇒
+### DB API: device type database access~selectDeviceTypeByCode(db, packageId, code) ⇒
 Retrieves the device type by the package, code and name.
 
 **Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
@@ -3355,7 +3511,6 @@
 | db | <code>\*</code> | 
 | packageId | <code>\*</code> | 
 | code | <code>\*</code> | 
-| name | <code>\*</code> | 
 
 <a name="module_DB API_ device type database access..selectDeviceTypeClustersByDeviceTypeRef"></a>
 
@@ -3411,48 +3566,54 @@
 
 <a name="module_DB API_ device type database access..updateClusterReferencesForDeviceTypeClusters"></a>
 
-### DB API: device type database access~updateClusterReferencesForDeviceTypeClusters(db) ⇒
+### DB API: device type database access~updateClusterReferencesForDeviceTypeClusters(db, packageId, sessionPackages) ⇒
 After loading up device type cluster table with the names,
-this method links the refererence to actual cluster reference.
+this method links the reference to actual cluster reference.
 
 **Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
 **Returns**: promise of completion  
 
-| Param | Type |
-| --- | --- |
-| db | <code>\*</code> | 
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| db | <code>\*</code> |  |  |
+| packageId | <code>\*</code> |  |  |
+| sessionPackages | <code>\*</code> | <code></code> | (if processing custom xml file it might need to reference clusters from primary zcl or other custom xml) |
 
 <a name="module_DB API_ device type database access..updateAttributeReferencesForDeviceTypeReferences"></a>
 
-### DB API: device type database access~updateAttributeReferencesForDeviceTypeReferences(db) ⇒
+### DB API: device type database access~updateAttributeReferencesForDeviceTypeReferences(db, packageId, sessionPackages) ⇒
 After loading up device type attribute table with the names,
-this method links the refererence to actual attribute reference.
+this method links the references to actual attribute reference.
 
 **Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
 **Returns**: promise of completion  
 
-| Param | Type |
-| --- | --- |
-| db | <code>\*</code> | 
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| db | <code>\*</code> |  |  |
+| packageId | <code>\*</code> |  |  |
+| sessionPackages | <code>\*</code> | <code></code> | (if processing custom xml file it might need to reference attributes from primary zcl or other custom xml) |
 
 <a name="module_DB API_ device type database access..updateCommandReferencesForDeviceTypeReferences"></a>
 
-### DB API: device type database access~updateCommandReferencesForDeviceTypeReferences(db) ⇒
+### DB API: device type database access~updateCommandReferencesForDeviceTypeReferences(db, packageId, sessionPackages) ⇒
 After loading up device type command table with the names,
-this method links the refererence to actual command reference.
+this method links the reference to actual command reference.
 
 **Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
 **Returns**: promise of completion  
 
-| Param | Type |
-| --- | --- |
-| db | <code>\*</code> | 
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| db | <code>\*</code> |  |  |
+| packageId | <code>\*</code> |  |  |
+| sessionPackages | <code>\*</code> | <code></code> | (if processing custom xml file it might need to reference commands from primary zcl or other custom xml) |
 
 <a name="module_DB API_ device type database access..updateFeatureReferencesForDeviceTypeReferences"></a>
 
-### DB API: device type database access~updateFeatureReferencesForDeviceTypeReferences(db) ⇒
+### DB API: device type database access~updateFeatureReferencesForDeviceTypeReferences(db, packageId) ⇒
 After loading up device type feature table with the names,
-this method links the refererence to actual feature reference.
+this method links the reference to actual feature reference.
 
 **Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
 **Returns**: promise of completion  
@@ -3460,6 +3621,7 @@
 | Param | Type |
 | --- | --- |
 | db | <code>\*</code> | 
+| packageId | <code>\*</code> | 
 
 <a name="module_DB API_ device type database access..updateDeviceTypeEntityReferences"></a>
 
@@ -3478,6 +3640,50 @@
 | --- | --- |
 | db | <code>\*</code> | 
 
+<a name="module_DB API_ device type database access..updateDeviceTypeReferencesForCustomXml"></a>
+
+### DB API: device type database access~updateDeviceTypeReferencesForCustomXml(db, packageId, sessionPackages, sessionId) ⇒
+Device types defined in custom xml files might refer to cluster, commands and attributes
+from the primary zcl file and other custom xml in the session.
+
+This method returns the promise of linking the device type entities to the correct
+foreign keys in such cases.
+
+**Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
+**Returns**: promise of completed linking  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| packageId | <code>\*</code> | 
+| sessionPackages | <code>\*</code> | 
+| sessionId | <code>\*</code> | 
+
+<a name="module_DB API_ device type database access..deleteUnlinkedDeviceTypeClusters"></a>
+
+### DB API: device type database access~deleteUnlinkedDeviceTypeClusters(db, packageId)
+This method deletes all device type clusters that are not linked to any cluster.
+
+**Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| packageId | <code>\*</code> | 
+
+<a name="module_DB API_ device type database access..warnUnlinkedDeviceTypeClusters"></a>
+
+### DB API: device type database access~warnUnlinkedDeviceTypeClusters(db, packageId, sessionId)
+This method adds warnings for all device type clusters that are not linked to any cluster.
+
+**Kind**: inner method of [<code>DB API: device type database access</code>](#module_DB API_ device type database access)  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| packageId | <code>\*</code> | 
+| sessionId | <code>\*</code> | 
+
 <a name="module_DB API_ device type database access..selectDeviceTypesWithCompositionByEndpointTypeId"></a>
 
 ### DB API: device type database access~selectDeviceTypesWithCompositionByEndpointTypeId(db, endpointTypeId) ⇒ <code>Promise.&lt;Array&gt;</code>
@@ -3546,6 +3752,7 @@
     * [~selectEnumById(db, id)](#module_DB API_ zcl database enum access..selectEnumById) ⇒
     * [~selectEnumByName(db, name, packageIds)](#module_DB API_ zcl database enum access..selectEnumByName) ⇒
     * [~selectEnumByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database enum access..selectEnumByNameAndClusterId) ⇒
+    * [~selectEnumByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database enum access..selectEnumByNameAndClusterName) ⇒
 
 <a name="module_DB API_ zcl database enum access..selectAllEnums"></a>
 
@@ -3642,6 +3849,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database enum access..selectEnumByNameAndClusterName"></a>
+
+### DB API: zcl database enum access~selectEnumByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a enum matched by name and cluster name
+Note: Use selectEnumByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database enum access</code>](#module_DB API_ zcl database enum access)  
+**Returns**: enum information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ event queries."></a>
 
 ## DB API: event queries.
@@ -3754,6 +3977,8 @@
     * [~getEndpointCompositionIdByCode(db, deviceType)](#module_DB API_ zcl loading queries..getEndpointCompositionIdByCode) ⇒ <code>Promise.&lt;(number\|null)&gt;</code>
     * [~insertDeviceComposition(db, deviceType, endpointCompositionId)](#module_DB API_ zcl loading queries..insertDeviceComposition) ⇒ <code>Promise</code>
     * [~insertDeviceTypes(db, packageId, data)](#module_DB API_ zcl loading queries..insertDeviceTypes) ⇒
+    * [~reloadDeviceTypes(db, packageId, data, sessionPackages)](#module_DB API_ zcl loading queries..reloadDeviceTypes)
+    * [~isDeviceTypeClusterInsertRequired(db, deviceTypeId, clusterName, packageId, sessionPackages)](#module_DB API_ zcl loading queries..isDeviceTypeClusterInsertRequired) ⇒ <code>Promise.&lt;boolean&gt;</code>
     * [~insertDeviceTypeFeatures(db, dtClusterRefDataPairs)](#module_DB API_ zcl loading queries..insertDeviceTypeFeatures)
     * [~insertDeviceTypeAttributes(db, dtClusterRefDataPairs)](#module_DB API_ zcl loading queries..insertDeviceTypeAttributes)
     * [~insertDeviceTypeCommands(db, dtClusterRefDataPairs)](#module_DB API_ zcl loading queries..insertDeviceTypeCommands)
@@ -4158,6 +4383,38 @@
 | packageId | <code>\*</code> |  |
 | data | <code>\*</code> | an array of objects that must contain: domain, code, profileId, name, description |
 
+<a name="module_DB API_ zcl loading queries..reloadDeviceTypes"></a>
+
+### DB API: zcl loading queries~reloadDeviceTypes(db, packageId, data, sessionPackages)
+Reloads device types into the database.
+This function is responsible for inserting new device type entities as required
+when a previously loaded custom xml file (containing a device type) is added to a session.
+
+**Kind**: inner method of [<code>DB API: zcl loading queries</code>](#module_DB API_ zcl loading queries)  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| packageId | <code>\*</code> | 
+| data | <code>\*</code> | 
+| sessionPackages | <code>\*</code> | 
+
+<a name="module_DB API_ zcl loading queries..isDeviceTypeClusterInsertRequired"></a>
+
+### DB API: zcl loading queries~isDeviceTypeClusterInsertRequired(db, deviceTypeId, clusterName, packageId, sessionPackages) ⇒ <code>Promise.&lt;boolean&gt;</code>
+Checks if a device type cluster insert is required on device type reload.
+
+**Kind**: inner method of [<code>DB API: zcl loading queries</code>](#module_DB API_ zcl loading queries)  
+**Returns**: <code>Promise.&lt;boolean&gt;</code> - - Returns true if the insert is required, false otherwise.  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| deviceTypeId | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageId | <code>\*</code> | 
+| sessionPackages | <code>\*</code> | 
+
 <a name="module_DB API_ zcl loading queries..insertDeviceTypeFeatures"></a>
 
 ### DB API: zcl loading queries~insertDeviceTypeFeatures(db, dtClusterRefDataPairs)
@@ -4563,6 +4820,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -4572,8 +4830,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -4779,6 +5039,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -4908,6 +5184,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -4938,6 +5230,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -5408,6 +5716,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -5417,8 +5726,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -5624,6 +5935,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -5753,6 +6080,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -5783,6 +6126,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -6203,6 +6562,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -6212,8 +6572,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -6419,6 +6781,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -6548,6 +6926,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -6578,6 +6972,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -6997,6 +7407,7 @@
     * [~selectAllBitmaps(db)](#module_DB API_ zcl database access..selectAllBitmaps) ⇒
     * [~selectBitmapByName(db, packageIds, name)](#module_DB API_ zcl database access..selectBitmapByName) ⇒
     * [~selectBitmapByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterId) ⇒
+    * [~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectBitmapByNameAndClusterName) ⇒
     * [~selectBitmapById(db, id)](#module_DB API_ zcl database access..selectBitmapById) ⇒
     * [~selectSessionClusterByCode(db, sessionId, code, mfgCode)](#module_DB API_ zcl database access..selectSessionClusterByCode) ⇒
     * [~selectAllSessionClusters(db, sessionId)](#module_DB API_ zcl database access..selectAllSessionClusters) ⇒
@@ -7006,8 +7417,10 @@
     * [~selectStructById(db, id)](#module_DB API_ zcl database access..selectStructById) ⇒
     * [~selectStructByName(db, name, packageIds)](#module_DB API_ zcl database access..selectStructByName) ⇒
     * [~selectStructByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterId) ⇒
+    * [~selectStructByNameAndClusterName(db, name, clusterName, packageIds)](#module_DB API_ zcl database access..selectStructByNameAndClusterName) ⇒
     * [~selectStructsWithClusterAssociation(db, packageIds, groupByStructName)](#module_DB API_ zcl database access..selectStructsWithClusterAssociation) ⇒
     * [~sqlQueryForDataTypeByNameAndClusterId(typeDiscriminator, clusterId, packageIds)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterId) ⇒
+    * [~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options)](#module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName) ⇒
     * [~selectClusterBitmaps(db, packageId, clusterId)](#module_DB API_ zcl database access..selectClusterBitmaps) ⇒
     * [~selectAllBitmapFieldsById(db, id)](#module_DB API_ zcl database access..selectAllBitmapFieldsById) ⇒
     * [~selectAllBitmapFields(db, packageId)](#module_DB API_ zcl database access..selectAllBitmapFields) ⇒
@@ -7213,6 +7626,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectBitmapByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectBitmapByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a bitmap matched by name and cluster name
+Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: bitmap information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectBitmapById"></a>
 
 ### DB API: zcl database access~selectBitmapById(db, id) ⇒
@@ -7342,6 +7771,22 @@
 | clusterId | <code>\*</code> | 
 | packageIds | <code>\*</code> | 
 
+<a name="module_DB API_ zcl database access..selectStructByNameAndClusterName"></a>
+
+### DB API: zcl database access~selectStructByNameAndClusterName(db, name, clusterName, packageIds) ⇒
+Select a struct matched by name and cluster name
+Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: struct information or undefined  
+
+| Param | Type |
+| --- | --- |
+| db | <code>\*</code> | 
+| name | <code>\*</code> | 
+| clusterName | <code>\*</code> | 
+| packageIds | <code>\*</code> | 
+
 <a name="module_DB API_ zcl database access..selectStructsWithClusterAssociation"></a>
 
 ### DB API: zcl database access~selectStructsWithClusterAssociation(db, packageIds, groupByStructName) ⇒
@@ -7372,6 +7817,22 @@
 | clusterId | <code>\*</code> | <code></code> | 
 | packageIds | <code>\*</code> |  | 
 
+<a name="module_DB API_ zcl database access..sqlQueryForDataTypeByNameAndClusterName"></a>
+
+### DB API: zcl database access~sqlQueryForDataTypeByNameAndClusterName(typeDiscriminator, name, clusterName, packageIds, options) ⇒
+Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+
+**Kind**: inner method of [<code>DB API: zcl database access</code>](#module_DB API_ zcl database access)  
+**Returns**: SQLite query string  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| typeDiscriminator | <code>\*</code> |  |
+| name | <code>\*</code> | data type name |
+| clusterName | <code>\*</code> |  |
+| packageIds | <code>\*</code> |  |
+| options | <code>\*</code> |  |
+
 <a name="module_DB API_ zcl database access..selectClusterBitmaps"></a>
 
 ### DB API: zcl database access~selectClusterBitmaps(db, packageId, clusterId) ⇒
@@ -7774,6 +8235,7 @@
 ## JS API: generator logic
 
 * [JS API: generator logic](#module_JS API_ generator logic)
+    * [~findAndReadJsonFiles(obj, basePath)](#module_JS API_ generator logic..findAndReadJsonFiles) ⇒ <code>Promise.&lt;string&gt;</code>
     * [~loadGenTemplateFromFile(templatePath)](#module_JS API_ generator logic..loadGenTemplateFromFile) ⇒
     * [~recordPackageIfNonexistent(db, packagePath, parentId, packageType, version, category, description)](#module_JS API_ generator logic..recordPackageIfNonexistent) ⇒
     * [~loadTemplateOptionsFromJsonFile(db, packageId, category, externalPath)](#module_JS API_ generator logic..loadTemplateOptionsFromJsonFile) ⇒
@@ -7821,6 +8283,19 @@
     * [~templatePromise(global, promise)](#module_JS API_ generator logic..templatePromise)
     * [~deprecatedHelper(fn, explanation)](#module_JS API_ generator logic..deprecatedHelper) ⇒
 
+<a name="module_JS API_ generator logic..findAndReadJsonFiles"></a>
+
+### JS API: generator logic~findAndReadJsonFiles(obj, basePath) ⇒ <code>Promise.&lt;string&gt;</code>
+Finds and reads JSON files referenced in a nested object.
+
+**Kind**: inner method of [<code>JS API: generator logic</code>](#module_JS API_ generator logic)  
+**Returns**: <code>Promise.&lt;string&gt;</code> - - A promise that resolves to the concatenated content of all JSON files.  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| obj | <code>Object</code> | The object to search for JSON file references. |
+| basePath | <code>string</code> | The base directory to resolve relative paths. |
+
 <a name="module_JS API_ generator logic..loadGenTemplateFromFile"></a>
 
 ### JS API: generator logic~loadGenTemplateFromFile(templatePath) ⇒
@@ -13112,6 +13587,7 @@
 ## JS API: generator logic
 
 * [JS API: generator logic](#module_JS API_ generator logic)
+    * [~findAndReadJsonFiles(obj, basePath)](#module_JS API_ generator logic..findAndReadJsonFiles) ⇒ <code>Promise.&lt;string&gt;</code>
     * [~loadGenTemplateFromFile(templatePath)](#module_JS API_ generator logic..loadGenTemplateFromFile) ⇒
     * [~recordPackageIfNonexistent(db, packagePath, parentId, packageType, version, category, description)](#module_JS API_ generator logic..recordPackageIfNonexistent) ⇒
     * [~loadTemplateOptionsFromJsonFile(db, packageId, category, externalPath)](#module_JS API_ generator logic..loadTemplateOptionsFromJsonFile) ⇒
@@ -13159,6 +13635,19 @@
     * [~templatePromise(global, promise)](#module_JS API_ generator logic..templatePromise)
     * [~deprecatedHelper(fn, explanation)](#module_JS API_ generator logic..deprecatedHelper) ⇒
 
+<a name="module_JS API_ generator logic..findAndReadJsonFiles"></a>
+
+### JS API: generator logic~findAndReadJsonFiles(obj, basePath) ⇒ <code>Promise.&lt;string&gt;</code>
+Finds and reads JSON files referenced in a nested object.
+
+**Kind**: inner method of [<code>JS API: generator logic</code>](#module_JS API_ generator logic)  
+**Returns**: <code>Promise.&lt;string&gt;</code> - - A promise that resolves to the concatenated content of all JSON files.  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| obj | <code>Object</code> | The object to search for JSON file references. |
+| basePath | <code>string</code> | The base directory to resolve relative paths. |
+
 <a name="module_JS API_ generator logic..loadGenTemplateFromFile"></a>
 
 ### JS API: generator logic~loadGenTemplateFromFile(templatePath) ⇒
@@ -13774,6 +14263,7 @@
 ## JS API: generator logic
 
 * [JS API: generator logic](#module_JS API_ generator logic)
+    * [~findAndReadJsonFiles(obj, basePath)](#module_JS API_ generator logic..findAndReadJsonFiles) ⇒ <code>Promise.&lt;string&gt;</code>
     * [~loadGenTemplateFromFile(templatePath)](#module_JS API_ generator logic..loadGenTemplateFromFile) ⇒
     * [~recordPackageIfNonexistent(db, packagePath, parentId, packageType, version, category, description)](#module_JS API_ generator logic..recordPackageIfNonexistent) ⇒
     * [~loadTemplateOptionsFromJsonFile(db, packageId, category, externalPath)](#module_JS API_ generator logic..loadTemplateOptionsFromJsonFile) ⇒
@@ -13821,6 +14311,19 @@
     * [~templatePromise(global, promise)](#module_JS API_ generator logic..templatePromise)
     * [~deprecatedHelper(fn, explanation)](#module_JS API_ generator logic..deprecatedHelper) ⇒
 
+<a name="module_JS API_ generator logic..findAndReadJsonFiles"></a>
+
+### JS API: generator logic~findAndReadJsonFiles(obj, basePath) ⇒ <code>Promise.&lt;string&gt;</code>
+Finds and reads JSON files referenced in a nested object.
+
+**Kind**: inner method of [<code>JS API: generator logic</code>](#module_JS API_ generator logic)  
+**Returns**: <code>Promise.&lt;string&gt;</code> - - A promise that resolves to the concatenated content of all JSON files.  
+
+| Param | Type | Description |
+| --- | --- | --- |
+| obj | <code>Object</code> | The object to search for JSON file references. |
+| basePath | <code>string</code> | The base directory to resolve relative paths. |
+
 <a name="module_JS API_ generator logic..loadGenTemplateFromFile"></a>
 
 ### JS API: generator logic~loadGenTemplateFromFile(templatePath) ⇒
@@ -18166,7 +18669,7 @@
 the string into tokens.
 
 Differs from `toCamelCase` by different handling of "." inside names,
-so that results are always usable as a code-compatibe name (e.g.
+so that results are always usable as a code-compatible name (e.g.
 "Foo 2.5" becomes "Foo25" rather than "Foo2.5").
 
 **Kind**: inner method of [<code>JS API: string utilities</code>](#module_JS API_ string utilities)  
@@ -18814,6 +19317,7 @@
     * [~commandComparator(a, b)](#module_REST API_ various zcl utilities..commandComparator) ⇒
     * [~eventComparator(a, b)](#module_REST API_ various zcl utilities..eventComparator) ⇒
     * [~findStructByName(structs, name)](#module_REST API_ various zcl utilities..findStructByName) ⇒
+    * [~sortStructsByDependencyHelper()](#module_REST API_ various zcl utilities..sortStructsByDependencyHelper)
     * [~sortStructsByDependency(structs)](#module_REST API_ various zcl utilities..sortStructsByDependency) ⇒
     * [~calculateBytes(res, options, db, packageIds, isStructType)](#module_REST API_ various zcl utilities..calculateBytes)
     * [~optionsHashOrDefault(options, optionsKey, defaultValue)](#module_REST API_ various zcl utilities..optionsHashOrDefault)
@@ -18897,6 +19401,12 @@
 | structs | <code>\*</code> | 
 | name | <code>\*</code> | 
 
+<a name="module_REST API_ various zcl utilities..sortStructsByDependencyHelper"></a>
+
+### REST API: various zcl utilities~sortStructsByDependencyHelper()
+Non-exported helper for sortStructsByDependency.
+
+**Kind**: inner method of [<code>REST API: various zcl utilities</code>](#module_REST API_ various zcl utilities)  
 <a name="module_REST API_ various zcl utilities..sortStructsByDependency"></a>
 
 ### REST API: various zcl utilities~sortStructsByDependency(structs) ⇒
@@ -20289,6 +20799,7 @@
     * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒
     * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ <code>Object</code>
     * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ <code>Promise</code>
+    * [~processReloadDeviceTypes()](#module_Loader API_ Loader APIs..processReloadDeviceTypes) ⇒ <code>Promise</code>
     * [~processDataTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processDataTypes) ⇒
     * [~processAtomicTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processAtomicTypes) ⇒
     * [~processNonAtomicTypes(db, filePath, packageId, knownPackages, toplevel, featureClusters)](#module_Loader API_ Loader APIs..processNonAtomicTypes) ⇒
@@ -21669,6 +22180,14 @@
 | data | <code>Array</code> | The array of device types to be processed. |
 | context | <code>\*</code> | Additional context that might be required for processing. |
 
+<a name="module_Loader API_ Loader APIs..processReloadDeviceTypes"></a>
+
+### Loader API: Loader APIs~processReloadDeviceTypes() ⇒ <code>Promise</code>
+Processes and reloads device type entities in the database.
+This function is called when a custom xml with device types is reloaded.
+
+**Kind**: inner method of [<code>Loader API: Loader APIs</code>](#module_Loader API_ Loader APIs)  
+**Returns**: <code>Promise</code> - A promise that resolves after all device types have been reloaded.  
 <a name="module_Loader API_ Loader APIs..processDataTypes"></a>
 
 ### Loader API: Loader APIs~processDataTypes(db, filePath, packageId, knownPackages, toplevel) ⇒
@@ -22141,6 +22660,7 @@
     * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒
     * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ <code>Object</code>
     * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ <code>Promise</code>
+    * [~processReloadDeviceTypes()](#module_Loader API_ Loader APIs..processReloadDeviceTypes) ⇒ <code>Promise</code>
     * [~processDataTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processDataTypes) ⇒
     * [~processAtomicTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processAtomicTypes) ⇒
     * [~processNonAtomicTypes(db, filePath, packageId, knownPackages, toplevel, featureClusters)](#module_Loader API_ Loader APIs..processNonAtomicTypes) ⇒
@@ -23521,6 +24041,14 @@
 | data | <code>Array</code> | The array of device types to be processed. |
 | context | <code>\*</code> | Additional context that might be required for processing. |
 
+<a name="module_Loader API_ Loader APIs..processReloadDeviceTypes"></a>
+
+### Loader API: Loader APIs~processReloadDeviceTypes() ⇒ <code>Promise</code>
+Processes and reloads device type entities in the database.
+This function is called when a custom xml with device types is reloaded.
+
+**Kind**: inner method of [<code>Loader API: Loader APIs</code>](#module_Loader API_ Loader APIs)  
+**Returns**: <code>Promise</code> - A promise that resolves after all device types have been reloaded.  
 <a name="module_Loader API_ Loader APIs..processDataTypes"></a>
 
 ### Loader API: Loader APIs~processDataTypes(db, filePath, packageId, knownPackages, toplevel) ⇒
@@ -23993,6 +24521,7 @@
     * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒
     * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ <code>Object</code>
     * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ <code>Promise</code>
+    * [~processReloadDeviceTypes()](#module_Loader API_ Loader APIs..processReloadDeviceTypes) ⇒ <code>Promise</code>
     * [~processDataTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processDataTypes) ⇒
     * [~processAtomicTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processAtomicTypes) ⇒
     * [~processNonAtomicTypes(db, filePath, packageId, knownPackages, toplevel, featureClusters)](#module_Loader API_ Loader APIs..processNonAtomicTypes) ⇒
@@ -25373,6 +25902,14 @@
 | data | <code>Array</code> | The array of device types to be processed. |
 | context | <code>\*</code> | Additional context that might be required for processing. |
 
+<a name="module_Loader API_ Loader APIs..processReloadDeviceTypes"></a>
+
+### Loader API: Loader APIs~processReloadDeviceTypes() ⇒ <code>Promise</code>
+Processes and reloads device type entities in the database.
+This function is called when a custom xml with device types is reloaded.
+
+**Kind**: inner method of [<code>Loader API: Loader APIs</code>](#module_Loader API_ Loader APIs)  
+**Returns**: <code>Promise</code> - A promise that resolves after all device types have been reloaded.  
 <a name="module_Loader API_ Loader APIs..processDataTypes"></a>
 
 ### Loader API: Loader APIs~processDataTypes(db, filePath, packageId, knownPackages, toplevel) ⇒
@@ -25845,6 +26382,7 @@
     * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒
     * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ <code>Object</code>
     * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ <code>Promise</code>
+    * [~processReloadDeviceTypes()](#module_Loader API_ Loader APIs..processReloadDeviceTypes) ⇒ <code>Promise</code>
     * [~processDataTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processDataTypes) ⇒
     * [~processAtomicTypes(db, filePath, packageId, knownPackages, toplevel)](#module_Loader API_ Loader APIs..processAtomicTypes) ⇒
     * [~processNonAtomicTypes(db, filePath, packageId, knownPackages, toplevel, featureClusters)](#module_Loader API_ Loader APIs..processNonAtomicTypes) ⇒
@@ -27225,6 +27763,14 @@
 | data | <code>Array</code> | The array of device types to be processed. |
 | context | <code>\*</code> | Additional context that might be required for processing. |
 
+<a name="module_Loader API_ Loader APIs..processReloadDeviceTypes"></a>
+
+### Loader API: Loader APIs~processReloadDeviceTypes() ⇒ <code>Promise</code>
+Processes and reloads device type entities in the database.
+This function is called when a custom xml with device types is reloaded.
+
+**Kind**: inner method of [<code>Loader API: Loader APIs</code>](#module_Loader API_ Loader APIs)  
+**Returns**: <code>Promise</code> - A promise that resolves after all device types have been reloaded.  
 <a name="module_Loader API_ Loader APIs..processDataTypes"></a>
 
 ### Loader API: Loader APIs~processDataTypes(db, filePath, packageId, knownPackages, toplevel) ⇒
diff --git a/src-electron/db/db-mapping.js b/src-electron/db/db-mapping.js
index b32f72d..2bc1a0c 100644
--- a/src-electron/db/db-mapping.js
+++ b/src-electron/db/db-mapping.js
@@ -149,7 +149,10 @@
       clusterCode2: x.C2_CODE,
       clusterMfgCode2: x.C2_MANUFACTURER_CODE,
       clusterName1: x.C1_NAME,
-      clusterName2: x.C2_NAME
+      clusterName2: x.C2_NAME,
+      clusterMappingIndex: x.CLUSTER_MAPPING_INDEX,
+      totalClusterMappedAttributes: x.TOTAL_CLUSTER_MAPPED_ATTRIBUTES,
+      isLastPartition: dbApi.fromDbBool(x.IS_LAST_CLUSTER_PARTITION)
     }
   },
 
@@ -159,6 +162,7 @@
       fieldIdentifier: x.FIELD_IDENTIFIER,
       name: x.NAME,
       type: x.TYPE,
+      defaultValue: x.DEFAULT_VALUE,
       isArray: dbApi.fromDbBool(x.IS_ARRAY),
       isNullable: dbApi.fromDbBool(x.IS_NULLABLE),
       isOptional: dbApi.fromDbBool(x.IS_OPTIONAL)
@@ -206,6 +210,7 @@
       clusterDefineName: x.CLUSTER_DEFINE_NAME,
       argName: x.ARG_NAME,
       argType: x.ARG_TYPE,
+      argDefaultValue: x.ARG_DEFAULT_VALUE,
       argIsArray: dbApi.fromDbBool(x.ARG_IS_ARRAY),
       argPresentIf: x.ARG_PRESENT_IF,
       argCountArg: x.ARG_COUNT_ARG,
@@ -238,6 +243,7 @@
       max: x.MAX,
       minLength: x.MIN_LENGTH,
       maxLength: x.MAX_LENGTH,
+      defaultValue: x.DEFAULT_VALUE,
       code: x.CODE,
       isArray: dbApi.fromDbBool(x.IS_ARRAY),
       presentIf: x.PRESENT_IF,
@@ -387,6 +393,7 @@
       type: x.TYPE,
       minLength: x.MIN_LENGTH,
       maxLength: x.MAX_LENGTH,
+      defaultValue: x.DEFAULT_VALUE,
       isArray: dbApi.fromDbBool(x.IS_ARRAY),
       isEnum: dbApi.fromDbBool(x.IS_ENUM),
       isWritable: dbApi.fromDbBool(x.IS_WRITABLE),
diff --git a/src-electron/db/query-attribute.js b/src-electron/db/query-attribute.js
index 87035aa..9ac2916 100644
--- a/src-electron/db/query-attribute.js
+++ b/src-electron/db/query-attribute.js
@@ -1219,7 +1219,28 @@
       C1.NAME AS C1_NAME,
       C2.CODE AS C2_CODE,
       COALESCE(C2.MANUFACTURER_CODE, 0) AS C2_MANUFACTURER_CODE,
-      C2.NAME AS C2_NAME
+      C2.NAME AS C2_NAME,
+      ROW_NUMBER() OVER (
+        PARTITION BY C1.CODE, COALESCE(C1.MANUFACTURER_CODE, 0), C2.CODE, COALESCE(C2.MANUFACTURER_CODE, 0)
+        ORDER BY C1.CODE, COALESCE(C1.MANUFACTURER_CODE, 0), C2.CODE, COALESCE(C2.MANUFACTURER_CODE, 0)
+      ) AS CLUSTER_MAPPING_INDEX,
+      COUNT(*) OVER (
+        PARTITION BY C1.CODE, COALESCE(C1.MANUFACTURER_CODE, 0), C2.CODE, COALESCE(C2.MANUFACTURER_CODE, 0)
+      ) AS TOTAL_CLUSTER_MAPPED_ATTRIBUTES,
+      CASE
+        WHEN
+          (
+            RANK() OVER (
+              ORDER BY C1.CODE, COALESCE(C1.MANUFACTURER_CODE, 0), C2.CODE, COALESCE(C2.MANUFACTURER_CODE, 0)
+            )
+            +  
+            COUNT(*) OVER (
+              PARTITION BY C1.CODE, COALESCE(C1.MANUFACTURER_CODE, 0), C2.CODE, COALESCE(C2.MANUFACTURER_CODE, 0)
+            )
+          ) > COUNT(*) OVER ()
+        THEN 1
+        ELSE 0
+      END AS IS_LAST_CLUSTER_PARTITION
     FROM
       ATTRIBUTE_MAPPING
     INNER JOIN
@@ -1242,7 +1263,7 @@
       A1.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
     OR
       A2.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
-
+    ORDER BY C1_CODE, C1_MANUFACTURER_CODE, C2_CODE, C2_MANUFACTURER_CODE, A1_CODE, A1_MANUFACTURER_CODE, A2_CODE, A2_MANUFACTURER_CODE
     `
   )
   return rows.map(dbMapping.map.attributeMapping)
diff --git a/src-electron/db/query-bitmap.js b/src-electron/db/query-bitmap.js
index 44b70b8..ea4ed06 100644
--- a/src-electron/db/query-bitmap.js
+++ b/src-electron/db/query-bitmap.js
@@ -16,7 +16,7 @@
  */
 
 /**
- * This module provides queries for enums.
+ * This module provides queries for bitmaps.
  *
  * @module DB API: zcl database access
  */
@@ -25,6 +25,7 @@
 const dbCache = require('./db-cache')
 const dbMapping = require('./db-mapping')
 const queryUtil = require('./query-util')
+const dbEnum = require('../../src-shared/db-enum')
 
 /**
  * Retrieves all the bitmaps in the database.
@@ -89,12 +90,12 @@
  */
 async function selectBitmapByNameAndClusterId(db, name, clusterId, packageIds) {
   let queryWithoutClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
-    'bitmap',
+    dbEnum.zclType.bitmap,
     null,
     packageIds
   )
   let queryWithClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
-    'bitmap',
+    dbEnum.zclType.bitmap,
     clusterId,
     packageIds
   )
@@ -113,6 +114,48 @@
 }
 
 /**
+ * Select a bitmap matched by name and cluster name
+ * Note: Use selectBitmapByNameAndClusterId but this was needed for backwards compatibility.
+ * @param {*} db
+ * @param {*} name
+ * @param {*} clusterName
+ * @param {*} packageIds
+ * @returns bitmap information or undefined
+ */
+async function selectBitmapByNameAndClusterName(
+  db,
+  name,
+  clusterName,
+  packageIds
+) {
+  let queryWithClusterName = queryUtil.sqlQueryForDataTypeByNameAndClusterName(
+    dbEnum.zclType.bitmap,
+    name,
+    clusterName,
+    packageIds
+  )
+  let res = await dbApi
+    .dbAll(db, queryWithClusterName)
+    .then((rows) => rows.map(dbMapping.map.bitmap))
+  if (res && res.length == 1) {
+    return res[0]
+  } else if (res && res.length > 1) {
+    throw new Error(
+      `More than one bitmap ${name} exists with same name for ${clusterName} cluster.`
+    )
+  } else {
+    queryWithClusterName = queryUtil.sqlQueryForDataTypeByNameAndClusterName(
+      dbEnum.zclType.bitmap,
+      name,
+      null, // Retrieving global data types since cluster specific ones were not found.
+      packageIds
+    )
+    res = await dbApi.dbGet(db, queryWithClusterName).then(dbMapping.map.bitmap)
+    return res
+  }
+}
+
+/**
  * Get Bitmap information by Bitmap ID.
  * @param {*} db
  * @param {*} id
@@ -141,3 +184,4 @@
 exports.selectBitmapByNameAndClusterId = dbCache.cacheQuery(
   selectBitmapByNameAndClusterId
 )
+exports.selectBitmapByNameAndClusterName = selectBitmapByNameAndClusterName
diff --git a/src-electron/db/query-command.js b/src-electron/db/query-command.js
index 40dc6f3..05b031b 100644
--- a/src-electron/db/query-command.js
+++ b/src-electron/db/query-command.js
@@ -880,19 +880,19 @@
       0
   END AS OUTGOING,
   COUNT(COMMAND.MANUFACTURER_CODE) OVER () AS MANUFACTURING_SPECIFIC_COMMAND_COUNT
-FROM 
+FROM
   COMMAND
-INNER JOIN 
+INNER JOIN
   ENDPOINT_TYPE_COMMAND
-ON 
+ON
   ENDPOINT_TYPE_COMMAND.COMMAND_REF = COMMAND.COMMAND_ID
-INNER JOIN 
+INNER JOIN
   ENDPOINT_TYPE_CLUSTER
-ON 
+ON
   ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = ENDPOINT_TYPE_COMMAND.ENDPOINT_TYPE_CLUSTER_REF
-INNER JOIN 
+INNER JOIN
   CLUSTER
-ON 
+ON
   ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
 WHERE
   ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_REF IN (${endpointTypeIds})
@@ -1139,6 +1139,7 @@
       argMax: x.ARG_MAX,
       argMinLength: x.ARG_MIN_LENGTH,
       argMaxLength: x.ARG_MAX_LENGTH,
+      argDefaultValue: x.ARG_DEFAULT_VALUE,
       argFieldId: x.FIELD_IDENTIFIER,
       argIsArray: dbApi.fromDbBool(x.ARG_IS_ARRAY),
       argPresentIf: x.ARG_PRESENT_IF,
@@ -1175,6 +1176,7 @@
   CA.MAX as ARG_MAX,
   CA.MIN_LENGTH as ARG_MIN_LENGTH,
   CA.MAX_LENGTH as ARG_MAX_LENGTH,
+  CA.DEFAULT_VALUE AS ARG_DEFAULT_VALUE,
   CA.FIELD_IDENTIFIER,
   CA.IS_ARRAY AS ARG_IS_ARRAY,
   CA.PRESENT_IF AS ARG_PRESENT_IF,
@@ -1212,6 +1214,7 @@
         max: x.max,
         minLength: x.minLength,
         maxLength: x.maxLength,
+        defaultValue: x.argDefaultValue,
         fieldId: x.argFieldId,
         isArray: x.argIsArray,
         presentIf: x.argPresentIf,
@@ -1228,6 +1231,7 @@
       delete x.argMax
       delete x.argMinLength
       delete x.argMaxLength
+      delete x.argDefaultValue
       delete x.argFieldId
       delete x.argIsArray
       delete x.argPresentIf
@@ -1496,12 +1500,12 @@
   IS_FABRIC_SCOPED,
   RESPONSE_REF,
   RESPONSE_NAME
-FROM 
+FROM
   COMMAND
-WHERE 
-  CLUSTER_REF IS NOT NULL 
+WHERE
+  CLUSTER_REF IS NOT NULL
   AND PACKAGE_REF = ?
-ORDER BY 
+ORDER BY
   CODE`,
       [packageId]
     )
@@ -1528,6 +1532,7 @@
   COMMAND_ARG.MAX,
   COMMAND_ARG.MIN_LENGTH,
   COMMAND_ARG.MAX_LENGTH,
+  COMMAND_ARG.DEFAULT_VALUE,
   COMMAND_ARG.IS_ARRAY,
   COMMAND_ARG.PRESENT_IF,
   COMMAND_ARG.IS_NULLABLE,
@@ -1585,6 +1590,7 @@
   MAX,
   MIN_LENGTH,
   MAX_LENGTH,
+  DEFAULT_VALUE,
   IS_ARRAY,
   PRESENT_IF,
   IS_NULLABLE,
@@ -1639,6 +1645,7 @@
   CA.MAX AS ARG_MAX,
   CA.MIN_LENGTH AS ARG_MIN_LENGTH,
   CA.MAX_LENGTH AS ARG_MAX_LENGTH,
+  CA.DEFAULT_VALUE AS ARG_DEFAULT_VALUE,
   CA.IS_ARRAY AS ARG_IS_ARRAY,
   CA.PRESENT_IF AS ARG_PRESENT_IF,
   CA.IS_NULLABLE AS ARG_IS_NULLABLE,
@@ -1764,20 +1771,20 @@
     CLUSTER.CLUSTER_ID,
     ENDPOINT_TYPE_CLUSTER.ENABLED,
     ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
-  FROM 
+  FROM
     COMMAND
-  INNER JOIN 
+  INNER JOIN
     CLUSTER
-  ON 
+  ON
     COMMAND.CLUSTER_REF = CLUSTER.CLUSTER_ID
-  INNER JOIN 
+  INNER JOIN
     ENDPOINT_TYPE_CLUSTER
-  ON 
+  ON
     CLUSTER.CLUSTER_ID = ENDPOINT_TYPE_CLUSTER.CLUSTER_REF
   WHERE
     ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID IN (${endpointTypeClusterRef})
     AND COMMAND.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
-  GROUP BY 
+  GROUP BY
     COMMAND.NAME
         `
     )
diff --git a/src-electron/db/query-config.js b/src-electron/db/query-config.js
index 35a757b..233ecca 100644
--- a/src-electron/db/query-config.js
+++ b/src-electron/db/query-config.js
@@ -150,16 +150,16 @@
  * Promise that resolves after inserting the defaults associated with the clusterside to the database.
  * @param {*} db
  * @param {*} endpointTypeId
- * @param {*} clusterRef
- * @param {*} side
+ * @param {*} packageIds
+ * @param {*} cluster
  */
-async function insertClusterDefaults(db, endpointTypeId, packageId, cluster) {
+async function insertClusterDefaults(db, endpointTypeId, packageIds, cluster) {
   let promises = []
   promises.push(
-    resolveDefaultAttributes(db, endpointTypeId, packageId, [cluster])
+    resolveDefaultAttributes(db, endpointTypeId, packageIds, [cluster])
   )
   promises.push(
-    resolveNonOptionalCommands(db, endpointTypeId, [cluster], packageId)
+    resolveNonOptionalCommands(db, endpointTypeId, [cluster], packageIds)
   )
   return Promise.all(promises)
 }
@@ -937,14 +937,12 @@
   if (doTransaction) {
     await dbApi.dbBeginTransaction(db)
   }
-  let pkgs = await queryPackage.getSessionPackagesByType(
+  let zclPropertiesPkgs = await queryPackage.getSessionPackagesByType(
     db,
     sessionId,
     dbEnum.packageType.zclProperties
   )
-  if (pkgs == null || pkgs.length < 1)
-    throw new Error('Could not locate package id for a given session.')
-
+  // Filter on category if available
   let deviceTypeInfo =
     await querySession.selectDeviceTypePackageInfoFromDeviceTypeId(
       db,
@@ -952,13 +950,23 @@
     )
   let endpointTypeCategory =
     deviceTypeInfo.length > 0 ? deviceTypeInfo[0].category : null
-  let packageId = pkgs[0].id
-  for (let i = 0; i < pkgs.length; i++) {
-    if (pkgs[i].category == endpointTypeCategory) {
-      packageId = pkgs[i].id
-      break
-    }
+  if (endpointTypeCategory) {
+    zclPropertiesPkgs = zclPropertiesPkgs.filter((pkg) => {
+      return pkg.category == endpointTypeCategory
+    })
   }
+  if (zclPropertiesPkgs == null || zclPropertiesPkgs.length < 1)
+    throw new Error('Could not locate package id for a given session.')
+
+  let zclXmlStandalonePkgs = await queryPackage.getSessionPackagesByType(
+    db,
+    sessionId,
+    dbEnum.packageType.zclXmlStandalone
+  )
+  // Relevant packages are zcl file (filtered by category) and all custom xmls in the session
+  let pkgs = zclPropertiesPkgs.concat(zclXmlStandalonePkgs)
+  let packageIds = pkgs.map((pkg) => pkg.id)
+
   let clusters = await queryDeviceType.selectDeviceTypeClustersByDeviceTypeRef(
     db,
     deviceTypeRef
@@ -973,8 +981,8 @@
   promises.push(
     resolveDefaultDeviceTypeAttributes(db, endpointTypeId, deviceTypeRef),
     resolveDefaultDeviceTypeCommands(db, endpointTypeId, deviceTypeRef),
-    resolveDefaultAttributes(db, endpointTypeId, packageId, defaultClusters),
-    resolveNonOptionalCommands(db, endpointTypeId, defaultClusters, packageId)
+    resolveDefaultAttributes(db, endpointTypeId, packageIds, defaultClusters),
+    resolveNonOptionalCommands(db, endpointTypeId, defaultClusters, packageIds)
   )
 
   return Promise.all(promises).finally(() => {
@@ -1212,14 +1220,14 @@
  * Resolve attribute defaults for endpoint type clusters.
  * @param {*} db
  * @param {*} endpointTypeId
- * @param {*} packageId
+ * @param {*} packageIds
  * @param {*} endpointClusters
  * @returns Array of promises for endpointClusters with attributes
  */
 async function resolveDefaultAttributes(
   db,
   endpointTypeId,
-  packageId,
+  packageIds,
   endpointClusters
 ) {
   let endpointClustersPromises = endpointClusters.map((cluster) =>
@@ -1227,7 +1235,7 @@
       .selectAttributesByClusterIdAndSideIncludingGlobal(
         db,
         cluster.clusterRef,
-        [packageId],
+        packageIds,
         cluster.side
       )
       .then((attributes) => {
diff --git a/src-electron/db/query-device-type.js b/src-electron/db/query-device-type.js
index 3ba55e3..f47c98a 100644
--- a/src-electron/db/query-device-type.js
+++ b/src-electron/db/query-device-type.js
@@ -23,6 +23,7 @@
 
 const dbApi = require('./db-api')
 const dbMapping = require('./db-mapping')
+const querySessionNotification = require('./query-session-notification')
 
 /**
  * Retrieves all the device types in the database.
@@ -83,7 +84,6 @@
  * @param {*} db
  * @param {*} packageId
  * @param {*} code
- * @param {*} name
  * @returns Device type
  */
 async function selectDeviceTypeByCode(db, packageId, code) {
@@ -182,7 +182,7 @@
     DEVICE_TYPE_CLUSTER AS C
   ON
     C.DEVICE_TYPE_CLUSTER_ID = AT.DEVICE_TYPE_CLUSTER_REF
-  LEFT JOIN 
+  LEFT JOIN
     ATTRIBUTE
   ON
     AT.ATTRIBUTE_REF = ATTRIBUTE.ATTRIBUTE_ID
@@ -218,7 +218,7 @@
     DEVICE_TYPE_CLUSTER AS C
   ON
     C.DEVICE_TYPE_CLUSTER_ID = CMD.DEVICE_TYPE_CLUSTER_REF
-  LEFT JOIN 
+  LEFT JOIN
     COMMAND
   ON
     CMD.COMMAND_REF = COMMAND.COMMAND_ID
@@ -231,12 +231,19 @@
 
 /**
  * After loading up device type cluster table with the names,
- * this method links the refererence to actual cluster reference.
+ * this method links the reference to actual cluster reference.
  *
  * @param {*} db
+ * @param {*} packageId
+ * @param {*} sessionPackages (if processing custom xml file it might need to reference clusters from primary zcl or other custom xml)
  * @returns promise of completion
  */
-async function updateClusterReferencesForDeviceTypeClusters(db, packageId) {
+async function updateClusterReferencesForDeviceTypeClusters(
+  db,
+  packageId,
+  sessionPackages = null
+) {
+  let knownPackages = sessionPackages ? sessionPackages : [packageId]
   return dbApi.dbUpdate(
     db,
     `
@@ -251,25 +258,33 @@
     WHERE
       lower(CLUSTER.NAME) = lower(DEVICE_TYPE_CLUSTER.CLUSTER_NAME)
     AND
-      CLUSTER.PACKAGE_REF = ?
+      CLUSTER.PACKAGE_REF IN (${dbApi.toInClause(knownPackages)})
   )
 WHERE
-  ( SELECT PACKAGE_REF
+  CLUSTER_REF IS NULL
+  AND ( SELECT PACKAGE_REF
     FROM DEVICE_TYPE
     WHERE DEVICE_TYPE_ID = DEVICE_TYPE_CLUSTER.DEVICE_TYPE_REF
   ) = ?`,
-    [packageId, packageId]
+    [packageId]
   )
 }
 
 /**
  * After loading up device type attribute table with the names,
- * this method links the refererence to actual attribute reference.
+ * this method links the references to actual attribute reference.
  *
  * @param {*} db
+ * @param {*} packageId
+ * @param {*} sessionPackages (if processing custom xml file it might need to reference attributes from primary zcl or other custom xml)
  * @returns promise of completion
  */
-async function updateAttributeReferencesForDeviceTypeReferences(db, packageId) {
+async function updateAttributeReferencesForDeviceTypeReferences(
+  db,
+  packageId,
+  sessionPackages = null
+) {
+  let knownPackages = sessionPackages ? sessionPackages : [packageId]
   return dbApi.dbUpdate(
     db,
     `
@@ -293,23 +308,30 @@
           DEVICE_TYPE_CLUSTER_ID = DEVICE_TYPE_ATTRIBUTE.DEVICE_TYPE_CLUSTER_REF
       )
     AND
-      ATTRIBUTE.PACKAGE_REF = ?
+      ATTRIBUTE.PACKAGE_REF IN (${dbApi.toInClause(knownPackages)})
   )
 WHERE
   DEVICE_TYPE_ATTRIBUTE.ATTRIBUTE_REF IS NULL
   `,
-    [packageId]
+    []
   )
 }
 
 /**
  * After loading up device type command table with the names,
- * this method links the refererence to actual command reference.
+ * this method links the reference to actual command reference.
  *
  * @param {*} db
+ * @param {*} packageId
+ * @param {*} sessionPackages (if processing custom xml file it might need to reference commands from primary zcl or other custom xml)
  * @returns promise of completion
  */
-async function updateCommandReferencesForDeviceTypeReferences(db, packageId) {
+async function updateCommandReferencesForDeviceTypeReferences(
+  db,
+  packageId,
+  sessionPackages = null
+) {
+  let knownPackages = sessionPackages ? sessionPackages : [packageId]
   return dbApi.dbUpdate(
     db,
     `
@@ -333,19 +355,20 @@
           DEVICE_TYPE_CLUSTER_ID = DEVICE_TYPE_COMMAND.DEVICE_TYPE_CLUSTER_REF
       )
     AND
-      COMMAND.PACKAGE_REF = ?
+      COMMAND.PACKAGE_REF IN (${dbApi.toInClause(knownPackages)})
   )
 WHERE
   DEVICE_TYPE_COMMAND.COMMAND_REF IS NULL`,
-    [packageId]
+    []
   )
 }
 
 /**
  * After loading up device type feature table with the names,
- * this method links the refererence to actual feature reference.
+ * this method links the reference to actual feature reference.
  *
  * @param {*} db
+ * @param {*} packageId
  * @returns promise of completion
  */
 async function updateFeatureReferencesForDeviceTypeReferences(db, packageId) {
@@ -399,6 +422,125 @@
 }
 
 /**
+ * Device types defined in custom xml files might refer to cluster, commands and attributes
+ * from the primary zcl file and other custom xml in the session.
+ *
+ * This method returns the promise of linking the device type entities to the correct
+ * foreign keys in such cases.
+ *
+ * @param {*} db
+ * @param {*} packageId
+ * @param {*} sessionPackages
+ * @param {*} sessionId
+ * @returns promise of completed linking
+ */
+async function updateDeviceTypeReferencesForCustomXml(
+  db,
+  packageId,
+  sessionPackages,
+  sessionId
+) {
+  // update the references for device type clusters, attributes and commands
+  await updateClusterReferencesForDeviceTypeClusters(
+    db,
+    packageId,
+    sessionPackages
+  )
+  await updateAttributeReferencesForDeviceTypeReferences(
+    db,
+    packageId,
+    sessionPackages
+  )
+  await updateCommandReferencesForDeviceTypeReferences(
+    db,
+    packageId,
+    sessionPackages
+  )
+
+  // add warnings for unlinked device type clusters
+  await warnUnlinkedDeviceTypeClusters(db, packageId, sessionId)
+
+  // delete unlinked device type clusters
+  return deleteUnlinkedDeviceTypeClusters(db, packageId)
+}
+
+/**
+ * This method deletes all device type clusters that are not linked to any cluster.
+ *
+ * @param {*} db
+ * @param {*} packageId
+ */
+async function deleteUnlinkedDeviceTypeClusters(db, packageId) {
+  return dbApi.dbRemove(
+    db,
+    `
+    DELETE FROM
+      DEVICE_TYPE_CLUSTER
+    WHERE
+      CLUSTER_REF IS NULL
+    AND
+      DEVICE_TYPE_REF IN (
+        SELECT
+          DEVICE_TYPE_ID
+        FROM
+          DEVICE_TYPE
+        WHERE
+          PACKAGE_REF = ?
+      )
+    `,
+    [packageId]
+  )
+}
+
+/**
+ * This method adds warnings for all device type clusters that are not linked to any cluster.
+ *
+ * @param {*} db
+ * @param {*} packageId
+ * @param {*} sessionId
+ */
+async function warnUnlinkedDeviceTypeClusters(db, packageId, sessionId) {
+  let unlinkedDtClusters = await dbApi.dbAll(
+    db,
+    `
+    SELECT
+      DTC.CLUSTER_NAME,
+      DT.NAME
+    FROM
+      DEVICE_TYPE_CLUSTER AS DTC
+    JOIN
+      DEVICE_TYPE AS DT ON DTC.DEVICE_TYPE_REF = DT.DEVICE_TYPE_ID
+    WHERE
+      CLUSTER_REF IS NULL
+    AND
+      DT.PACKAGE_REF = ?
+    `,
+    [packageId]
+  )
+  let packagePath = await dbApi.dbGet(
+    db,
+    `
+    SELECT
+      PATH
+    FROM
+      PACKAGE
+    WHERE
+      PACKAGE_ID = ?`,
+    [packageId]
+  )
+  for (const dtCluster of unlinkedDtClusters) {
+    querySessionNotification.setNotification(
+      db,
+      'ERROR',
+      `Cluster "${dtCluster.CLUSTER_NAME}" in device type ${dtCluster.NAME} is not found in the current session - "${packagePath.PATH}"`,
+      sessionId,
+      1,
+      0
+    )
+  }
+}
+
+/**
  * Asynchronously selects device types with their compositions by a specific endpoint type ID.
  *
  * This function queries the database for device types associated with a given endpoint type ID,
@@ -532,6 +674,8 @@
 exports.selectDeviceTypeCommandsByDeviceTypeRef =
   selectDeviceTypeCommandsByDeviceTypeRef
 exports.updateDeviceTypeEntityReferences = updateDeviceTypeEntityReferences
+exports.updateDeviceTypeReferencesForCustomXml =
+  updateDeviceTypeReferencesForCustomXml
 exports.selectDeviceTypesByEndpointTypeId = selectDeviceTypesByEndpointTypeId
 exports.selectDeviceTypeFeaturesByEndpointTypeIdAndClusterId =
   selectDeviceTypeFeaturesByEndpointTypeIdAndClusterId
diff --git a/src-electron/db/query-endpoint.js b/src-electron/db/query-endpoint.js
index fc453e6..b446489 100644
--- a/src-electron/db/query-endpoint.js
+++ b/src-electron/db/query-endpoint.js
@@ -50,7 +50,7 @@
   ENDPOINT AS E1
 LEFT JOIN
   ENDPOINT AS E2
-ON 
+ON
   E2.ENDPOINT_ID = E1.PARENT_ENDPOINT_REF
 WHERE E1.SESSION_REF = ?
 ORDER BY E1.ENDPOINT_IDENTIFIER
@@ -70,18 +70,18 @@
  */
 async function getRootNode(db, packageIds) {
   const query = `
-    SELECT 
-      EC.DEVICE_TYPE_REF, 
-      EC.CODE, 
+    SELECT
+      EC.DEVICE_TYPE_REF,
+      EC.CODE,
       EC.TYPE,
-      DT.NAME, 
+      DT.NAME,
       DT.PACKAGE_REF
-    FROM 
+    FROM
       ENDPOINT_COMPOSITION EC
-    JOIN 
+    JOIN
       DEVICE_TYPE DT ON EC.DEVICE_TYPE_REF = DT.DEVICE_TYPE_ID
-    WHERE 
-      EC.TYPE = ? AND 
+    WHERE
+      EC.TYPE = ? AND
       DT.PACKAGE_REF IN (${packageIds.map(() => '?').join(', ')})
   `
 
@@ -124,7 +124,7 @@
   ENDPOINT AS E1
 LEFT JOIN
   ENDPOINT AS E2
-ON 
+ON
   E2.ENDPOINT_ID = E1.PARENT_ENDPOINT_REF
 INNER JOIN
   ENDPOINT_TYPE
@@ -145,12 +145,12 @@
 WHERE
   E1.SESSION_REF = ?
 AND
-  PACKAGE.CATEGORY = ?
+  ((PACKAGE.CATEGORY = ?) OR (PACKAGE.CATEGORY IS NULL AND PACKAGE.TYPE = ?))
 GROUP BY
   E1.ENDPOINT_IDENTIFIER
 ORDER BY E1.ENDPOINT_IDENTIFIER
     `,
-    [sessionId, templateCategory]
+    [sessionId, templateCategory, dbEnum.packageType.zclXmlStandalone]
   )
 
   // if now rows are found then return all endpoints in the session. This can
@@ -559,7 +559,7 @@
         NETWORK_IDENTIFIER,
         PROFILE
       )
-    SELECT 
+    SELECT
       SESSION_REF,
       ?,
       ?,
@@ -605,7 +605,7 @@
   ENDPOINT_TYPE_DEVICE.ENDPOINT_TYPE_REF = E1.ENDPOINT_TYPE_REF
 LEFT JOIN
   ENDPOINT AS E2
-ON 
+ON
   E2.ENDPOINT_ID = E1.PARENT_ENDPOINT_REF
 WHERE
   E1.ENDPOINT_ID = ?`,
diff --git a/src-electron/db/query-enum.js b/src-electron/db/query-enum.js
index 91949ef..58ecfe5 100644
--- a/src-electron/db/query-enum.js
+++ b/src-electron/db/query-enum.js
@@ -25,6 +25,7 @@
 const dbCache = require('./db-cache')
 const dbMapping = require('./db-mapping')
 const queryUtil = require('./query-util')
+const dbEnum = require('../../src-shared/db-enum')
 
 /**
  * Retrieves all the enums in the database.
@@ -226,12 +227,12 @@
  */
 async function selectEnumByNameAndClusterId(db, name, clusterId, packageIds) {
   let queryWithoutClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
-    'enum',
+    dbEnum.zclType.enum,
     null,
     packageIds
   )
   let queryWithClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
-    'enum',
+    dbEnum.zclType.enum,
     clusterId,
     packageIds
   )
@@ -248,6 +249,48 @@
   }
 }
 
+/**
+ * Select a enum matched by name and cluster name
+ * Note: Use selectEnumByNameAndClusterId but this was needed for backwards compatibility.
+ * @param {*} db
+ * @param {*} name
+ * @param {*} clusterName
+ * @param {*} packageIds
+ * @returns enum information or undefined
+ */
+async function selectEnumByNameAndClusterName(
+  db,
+  name,
+  clusterName,
+  packageIds
+) {
+  let queryWithClusterName = queryUtil.sqlQueryForDataTypeByNameAndClusterName(
+    dbEnum.zclType.enum,
+    name,
+    clusterName,
+    packageIds
+  )
+  let res = await dbApi
+    .dbAll(db, queryWithClusterName)
+    .then((rows) => rows.map(dbMapping.map.enum))
+  if (res && res.length == 1) {
+    return res[0]
+  } else if (res && res.length > 1) {
+    throw new Error(
+      `More than one enum ${name} exists with same name for ${clusterName} cluster.`
+    )
+  } else {
+    queryWithClusterName = queryUtil.sqlQueryForDataTypeByNameAndClusterName(
+      dbEnum.zclType.enum,
+      name,
+      null, // Retrieving global data types since cluster specific ones were not found.
+      packageIds
+    )
+    res = await dbApi.dbGet(db, queryWithClusterName).then(dbMapping.map.enum)
+    return res
+  }
+}
+
 // exports
 exports.selectAllEnums = selectAllEnums
 exports.selectEnumByName = dbCache.cacheQuery(selectEnumByName)
@@ -258,3 +301,4 @@
 exports.selectClusterEnums = selectClusterEnums
 exports.selectAllEnumItemsById = selectAllEnumItemsById
 exports.selectAllEnumItems = selectAllEnumItems
+exports.selectEnumByNameAndClusterName = selectEnumByNameAndClusterName
diff --git a/src-electron/db/query-event.js b/src-electron/db/query-event.js
index eb89d5d..6e52285 100644
--- a/src-electron/db/query-event.js
+++ b/src-electron/db/query-event.js
@@ -218,6 +218,7 @@
   FIELD_IDENTIFIER,
   NAME,
   TYPE,
+  DEFAULT_VALUE,
   IS_ARRAY,
   IS_NULLABLE,
   IS_OPTIONAL
diff --git a/src-electron/db/query-loader.js b/src-electron/db/query-loader.js
index c9bfd6a..26c11be 100644
--- a/src-electron/db/query-loader.js
+++ b/src-electron/db/query-loader.js
@@ -77,13 +77,14 @@
   FIELD_IDENTIFIER,
   NAME,
   TYPE,
+  DEFAULT_VALUE,
   IS_ARRAY,
   IS_NULLABLE,
   IS_OPTIONAL,
   INTRODUCED_IN_REF,
   REMOVED_IN_REF
 ) VALUES (
-  ?, ?, ?, ?, ?, ?, ?,
+  ?, ?, ?, ?, ?, ?, ?, ?,
   (SELECT SPEC_ID FROM SPEC WHERE CODE = ? AND PACKAGE_REF = ?),
   (SELECT SPEC_ID FROM SPEC WHERE CODE = ? AND PACKAGE_REF = ?)
 )
@@ -122,6 +123,7 @@
   MAX,
   MIN_LENGTH,
   MAX_LENGTH,
+  DEFAULT_VALUE,
   IS_ARRAY,
   PRESENT_IF,
   IS_NULLABLE,
@@ -131,7 +133,7 @@
   INTRODUCED_IN_REF,
   REMOVED_IN_REF
 ) VALUES (
-  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
+  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
   (SELECT SPEC_ID FROM SPEC WHERE CODE = ? AND PACKAGE_REF = ?),
   (SELECT SPEC_ID FROM SPEC WHERE CODE = ? AND PACKAGE_REF = ?)
 )`
@@ -333,6 +335,7 @@
     field.fieldIdentifier,
     field.name,
     field.type,
+    field.defaultValue,
     dbApi.toDbBool(field.isArray),
     dbApi.toDbBool(field.isNullable),
     dbApi.toDbBool(field.isOptional),
@@ -360,6 +363,7 @@
     arg.max,
     arg.minLength,
     arg.maxLength,
+    arg.defaultValue,
     dbApi.toDbBool(arg.isArray),
     arg.presentIf,
     dbApi.toDbBool(arg.isNullable),
@@ -1266,7 +1270,7 @@
         if ('clusters' in data[i]) {
           let lastId = lastIdsArray[i]
           let clusters = data[i].clusters
-          // This is an array that links the generated deviceTyepRef to the cluster via generating an array of arrays,
+          // This is an array that links the generated deviceTypeRef to the cluster via generating an array of arrays,
           zclIdsPromises = Promise.all(
             clusters.map((cluster) =>
               dbApi
@@ -1331,6 +1335,122 @@
 }
 
 /**
+ * Reloads device types into the database.
+ * This function is responsible for inserting new device type entities as required
+ * when a previously loaded custom xml file (containing a device type) is added to a session.
+ *
+ * @param {*} db
+ * @param {*} packageId
+ * @param {*} data
+ * @param {*} sessionPackages
+ */
+async function reloadDeviceTypes(db, packageId, data, sessionPackages) {
+  let zclIdsPromises = []
+  for (let dt of data) {
+    // Find the DEVICE_TYPE_ID for the current device type
+    const query = `
+      SELECT
+        DEVICE_TYPE_ID
+      FROM
+        DEVICE_TYPE
+      WHERE
+        PACKAGE_REF = ? AND CODE = ?`
+    const result = await dbApi.dbGet(db, query, [packageId, dt.code])
+
+    if (result) {
+      const existingId = result.DEVICE_TYPE_ID
+
+      if ('clusters' in dt) {
+        const clusters = dt.clusters
+
+        // Process clusters for the existing device type
+        const clusterPromises = []
+        for (const cluster of clusters) {
+          const isInsertRequired = await isDeviceTypeClusterInsertRequired(
+            db,
+            existingId,
+            cluster.clusterName,
+            packageId,
+            sessionPackages
+          )
+          // Only inserting new device type cluster if required
+          if (isInsertRequired) {
+            const promise = dbApi
+              .dbInsert(
+                db,
+                'INSERT INTO DEVICE_TYPE_CLUSTER (DEVICE_TYPE_REF, CLUSTER_NAME, INCLUDE_CLIENT, INCLUDE_SERVER, LOCK_CLIENT, LOCK_SERVER) VALUES (?,?,?,?,?,?)',
+                [
+                  existingId,
+                  cluster.clusterName,
+                  cluster.client,
+                  cluster.server,
+                  cluster.clientLocked,
+                  cluster.serverLocked
+                ],
+                true
+              )
+              .then((deviceTypeClusterRef) => ({
+                dtClusterRef: deviceTypeClusterRef,
+                clusterData: cluster
+              }))
+            clusterPromises.push(promise)
+          }
+        }
+
+        const dtClusterRefDataPairs = await Promise.all(clusterPromises)
+
+        // Insert attributes, commands, and features for the device type
+        await Promise.all([
+          insertDeviceTypeAttributes(db, dtClusterRefDataPairs),
+          insertDeviceTypeCommands(db, dtClusterRefDataPairs)
+        ])
+      }
+    }
+  }
+  return zclIdsPromises
+}
+
+/**
+ * Checks if a device type cluster insert is required on device type reload.
+ *
+ * @param {*} db
+ * @param {*} deviceTypeId
+ * @param {*} clusterName
+ * @param {*} packageId
+ * @param {*} sessionPackages
+ * @returns {Promise<boolean>} - Returns true if the insert is required, false otherwise.
+ */
+async function isDeviceTypeClusterInsertRequired(
+  db,
+  deviceTypeId,
+  clusterName,
+  packageId,
+  sessionPackages
+) {
+  let knownPackages = sessionPackages.concat(packageId)
+  const query = `
+    SELECT
+      DEVICE_TYPE_CLUSTER_ID
+    FROM
+      DEVICE_TYPE_CLUSTER
+    WHERE
+      DEVICE_TYPE_REF = ?
+    AND
+      CLUSTER_NAME = ?
+    AND
+      CLUSTER_REF IN
+      (SELECT
+        CLUSTER_ID
+        FROM
+          CLUSTER
+        WHERE
+          PACKAGE_REF IN (${dbApi.toInClause(knownPackages)}))
+  `
+  const result = await dbApi.dbGet(db, query, [deviceTypeId, clusterName])
+  return result === undefined
+}
+
+/**
  * This handles the loading of device type feature requirements into the database.
  * There is a need to post-process to attach the actual feature ref after the fact
  * @param {*} db
@@ -2282,7 +2402,7 @@
     db,
     `
   INSERT INTO
-    STRUCT_ITEM (STRUCT_REF, NAME, FIELD_IDENTIFIER, IS_ARRAY, IS_ENUM, MIN_LENGTH, MAX_LENGTH, IS_WRITABLE, IS_NULLABLE, IS_OPTIONAL, IS_FABRIC_SENSITIVE, SIZE, DATA_TYPE_REF)
+    STRUCT_ITEM (STRUCT_REF, NAME, FIELD_IDENTIFIER, IS_ARRAY, IS_ENUM, MIN_LENGTH, MAX_LENGTH, DEFAULT_VALUE, IS_WRITABLE, IS_NULLABLE, IS_OPTIONAL, IS_FABRIC_SENSITIVE, SIZE, DATA_TYPE_REF)
   VALUES (
     (SELECT
       CASE
@@ -2306,6 +2426,7 @@
     ?,
     ?,
     ?,
+    ?,
     (SELECT
       DATA_TYPE_ID
      FROM
@@ -2329,6 +2450,7 @@
       at.isEnum,
       at.minLength,
       at.maxLength,
+      at.defaultValue,
       at.isWritable,
       at.isNullable,
       at.isOptional,
@@ -2347,6 +2469,7 @@
 exports.insertGlobalAttributeDefault = insertGlobalAttributeDefault
 exports.insertAtomics = insertAtomics
 exports.insertDeviceTypes = insertDeviceTypes
+exports.reloadDeviceTypes = reloadDeviceTypes
 exports.insertTags = insertTags
 exports.insertAccessModifiers = insertAccessModifiers
 exports.insertAccessOperations = insertAccessOperations
diff --git a/src-electron/db/query-package.js b/src-electron/db/query-package.js
index be35153..954a9f6 100644
--- a/src-electron/db/query-package.js
+++ b/src-electron/db/query-package.js
@@ -533,7 +533,8 @@
   SESSION_PARTITION.SESSION_REF,
   SESSION_PARTITION.SESSION_PARTITION_ID,
   SP.REQUIRED,
-  P.CATEGORY
+  P.CATEGORY,
+  P.TYPE
 FROM
   SESSION_PARTITION
 INNER JOIN
@@ -686,7 +687,7 @@
         CATEGORY,
         DESCRIPTION,
         PARENT_PACKAGE_REF
-       FROM 
+       FROM
         PACKAGE
        WHERE
         IS_IN_SYNC = 1`
@@ -734,7 +735,7 @@
           po.OPTION_CODE = ?
           AND ${packageRefCondition}
 
-      UNION 
+      UNION
 
       SELECT
           c.NAME AS OPTION_CATEGORY,
diff --git a/src-electron/db/query-struct.js b/src-electron/db/query-struct.js
index 24b7b4b..5c9ada3 100644
--- a/src-electron/db/query-struct.js
+++ b/src-electron/db/query-struct.js
@@ -25,6 +25,7 @@
 const dbCache = require('./db-cache')
 const dbMapping = require('./db-mapping')
 const queryUtil = require('./query-util')
+const dbEnum = require('../../src-shared/db-enum')
 
 /**
  * Get all structs from a given package ID.
@@ -132,12 +133,12 @@
  */
 async function selectStructByNameAndClusterId(db, name, clusterId, packageIds) {
   let queryWithoutClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
-    'struct',
+    dbEnum.zclType.struct,
     null,
     packageIds
   )
   let queryWithClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
-    'struct',
+    dbEnum.zclType.struct,
     clusterId,
     packageIds
   )
@@ -155,6 +156,48 @@
 }
 
 /**
+ * Select a struct matched by name and cluster name
+ * Note: Use selectStructByNameAndClusterId but this was needed for backwards compatibility.
+ * @param {*} db
+ * @param {*} name
+ * @param {*} clusterName
+ * @param {*} packageIds
+ * @returns struct information or undefined
+ */
+async function selectStructByNameAndClusterName(
+  db,
+  name,
+  clusterName,
+  packageIds
+) {
+  let queryWithClusterName = queryUtil.sqlQueryForDataTypeByNameAndClusterName(
+    dbEnum.zclType.struct,
+    name,
+    clusterName,
+    packageIds
+  )
+  let res = await dbApi
+    .dbAll(db, queryWithClusterName)
+    .then((rows) => rows.map(dbMapping.map.struct))
+  if (res && res.length == 1) {
+    return res[0]
+  } else if (res && res.length > 1) {
+    throw new Error(
+      `More than one struct ${name} exists with same name for ${clusterName} cluster.`
+    )
+  } else {
+    queryWithClusterName = queryUtil.sqlQueryForDataTypeByNameAndClusterName(
+      dbEnum.zclType.struct,
+      name,
+      null, // Retrieving global data types since cluster specific ones were not found.
+      packageIds
+    )
+    res = await dbApi.dbGet(db, queryWithClusterName).then(dbMapping.map.struct)
+    return res
+  }
+}
+
+/**
  * Get all structs which have a cluster associated with them. If a struct is
  * present in more than one cluster then it can be grouped by struct name to
  * avoid additional rows.
@@ -208,5 +251,6 @@
 exports.selectStructByNameAndClusterId = dbCache.cacheQuery(
   selectStructByNameAndClusterId
 )
+exports.selectStructByNameAndClusterName = selectStructByNameAndClusterName
 exports.selectStructsWithClusterAssociation =
   selectStructsWithClusterAssociation
diff --git a/src-electron/db/query-util.js b/src-electron/db/query-util.js
index 5adedae..6e325cd 100644
--- a/src-electron/db/query-util.js
+++ b/src-electron/db/query-util.js
@@ -83,5 +83,71 @@
   return clusterId ? queryWithClusterId : queryWithoutClusterId
 }
 
+/**
+ * Formulate a sqlite query string for a data type from the given cluster name and package IDs.
+ * @param {*} typeDiscriminator
+ * @param {*} name data type name
+ * @param {*} clusterName
+ * @param {*} packageIds
+ * @param {*} options
+ * @returns SQLite query string
+ */
+function sqlQueryForDataTypeByNameAndClusterName(
+  typeDiscriminator,
+  name,
+  clusterName,
+  packageIds,
+  options = {}
+) {
+  let typeTableName = typeDiscriminator.toUpperCase()
+  let numberExtensionString =
+    typeDiscriminator == 'number' ? 'NUMBER.IS_SIGNED, ' : ''
+  let checkLowerCaseString =
+    typeDiscriminator != 'number' && typeDiscriminator != 'struct'
+      ? `OR DATA_TYPE.NAME = '${name}'`
+      : ''
+  let structExtensionString =
+    typeDiscriminator == 'struct'
+      ? 'STRUCT.IS_FABRIC_SCOPED, DATA_TYPE.DISCRIMINATOR_REF, '
+      : ''
+  let selectQueryString = `
+  SELECT
+    ${typeTableName}.${typeTableName}_ID,
+    ${structExtensionString}
+    DATA_TYPE.NAME AS NAME,
+    (SELECT COUNT(1) FROM DATA_TYPE_CLUSTER WHERE DATA_TYPE_CLUSTER.DATA_TYPE_REF = ${typeTableName}.${typeTableName}_ID) AS ${typeTableName}_CLUSTER_COUNT,
+    ${numberExtensionString}
+    ${typeTableName}.SIZE AS SIZE,
+    CLUSTER.NAME AS CLUSTER_NAME
+  FROM ${typeTableName}
+  INNER JOIN
+    DATA_TYPE
+  ON
+    ${typeTableName}.${typeTableName}_ID = DATA_TYPE.DATA_TYPE_ID
+  LEFT JOIN
+    DATA_TYPE_CLUSTER
+  ON
+    DATA_TYPE_CLUSTER.DATA_TYPE_REF = ${typeTableName}.${typeTableName}_ID 
+  LEFT JOIN
+    CLUSTER
+  ON
+    DATA_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
+  WHERE
+    (DATA_TYPE.NAME = '${name}' ${checkLowerCaseString})
+  AND
+    DATA_TYPE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)}) `
+
+  let whereClause = !options.ignoreClusterWhereClause
+    ? clusterName
+      ? `AND CLUSTER.NAME = '${clusterName}'`
+      : `AND CLUSTER.NAME IS NULL`
+    : ``
+
+  let resultingQuery = selectQueryString + whereClause
+  return resultingQuery
+}
+
 exports.sqlQueryForDataTypeByNameAndClusterId =
   sqlQueryForDataTypeByNameAndClusterId
+exports.sqlQueryForDataTypeByNameAndClusterName =
+  sqlQueryForDataTypeByNameAndClusterName
diff --git a/src-electron/db/query-zcl.js b/src-electron/db/query-zcl.js
index d7b8b33..377658b 100644
--- a/src-electron/db/query-zcl.js
+++ b/src-electron/db/query-zcl.js
@@ -356,7 +356,7 @@
       S.STRUCT_ID = SI.STRUCT_REF
     WHERE
       DT.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
-    ORDER BY DT.NAME, SI.FIELD_IDENTIFIER`
+    ORDER BY DT.NAME, DT.DATA_TYPE_ID, SI.FIELD_IDENTIFIER`
   } else {
     query = `
     SELECT
@@ -395,18 +395,19 @@
       DT.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
     AND
       DTC.CLUSTER_REF = ?
-    ORDER BY DT.NAME, SI.FIELD_IDENTIFIER`
+    ORDER BY DT.NAME, DT.DATA_TYPE_ID, SI.FIELD_IDENTIFIER`
     args = [clusterId]
   }
 
   let rows = await dbApi.dbAll(db, query, args)
   return rows.reduce((acc, value) => {
     let objectToActOn
-    if (acc.length == 0 || acc[acc.length - 1].name != value.STRUCT_NAME) {
+    if (acc.length == 0 || acc[acc.length - 1].struct_id != value.STRUCT_ID) {
       // Create a new object
       objectToActOn = {
         id: value.STRUCT_ID,
         name: value.STRUCT_NAME,
+        struct_id: value.STRUCT_ID,
         isFabricScoped: dbApi.fromDbBool(value.IS_FABRIC_SCOPED),
         apiMaturity: value.API_MATURITY,
         label: value.STRUCT_NAME,
@@ -459,6 +460,7 @@
   STRUCT_ITEM.IS_ENUM,
   STRUCT_ITEM.MIN_LENGTH,
   STRUCT_ITEM.MAX_LENGTH,
+  STRUCT_ITEM.DEFAULT_VALUE,
   STRUCT_ITEM.IS_WRITABLE,
   STRUCT_ITEM.IS_NULLABLE,
   STRUCT_ITEM.IS_OPTIONAL,
@@ -1332,6 +1334,12 @@
 exports.selectStructByName = queryStruct.selectStructByName
 exports.selectStructByNameAndClusterId =
   queryStruct.selectStructByNameAndClusterId
+exports.selectStructByNameAndClusterName =
+  queryStruct.selectStructByNameAndClusterName
+exports.selectEnumByNameAndClusterName =
+  queryEnum.selectEnumByNameAndClusterName
+exports.selectBitmapByNameAndClusterName =
+  queryBitmap.selectBitmapByNameAndClusterName
 
 exports.selectBitmapById = queryBitmap.selectBitmapById
 exports.selectAllBitmaps = queryBitmap.selectAllBitmaps
diff --git a/src-electron/db/zap-schema.sql b/src-electron/db/zap-schema.sql
index 77341f7..f5eec24 100644
--- a/src-electron/db/zap-schema.sql
+++ b/src-electron/db/zap-schema.sql
@@ -206,6 +206,7 @@
   "MAX" text,
   "MIN_LENGTH" integer,
   "MAX_LENGTH" integer,
+  "DEFAULT_VALUE" text,
   "IS_ARRAY" integer,
   "PRESENT_IF" text,
   "IS_NULLABLE" integer,
@@ -253,6 +254,7 @@
   "FIELD_IDENTIFIER" integer,
   "NAME" text,
   "TYPE" text,
+  "DEFAULT_VALUE" text,
   "IS_ARRAY" integer,
   "IS_NULLABLE" integer,
   "IS_OPTIONAL" integer,
@@ -624,7 +626,7 @@
 DROP TABLE IF EXISTS "BITMAP_FIELD";
 CREATE TABLE IF NOT EXISTS BITMAP_FIELD (
   BITMAP_FIELD_ID integer NOT NULL PRIMARY KEY autoincrement,
-  BITMAP_REF integer,
+  BITMAP_REF integer NOT NULL,
   FIELD_IDENTIFIER integer,
   NAME text(100),
   MASK integer,
@@ -647,7 +649,7 @@
 DROP TABLE IF EXISTS "ENUM_ITEM";
 CREATE TABLE IF NOT EXISTS "ENUM_ITEM" (
   "ENUM_ITEM_ID" integer NOT NULL PRIMARY KEY autoincrement,
-  "ENUM_REF" integer,
+  "ENUM_REF" integer NOT NULL,
   "NAME" text,
   "DESCRIPTION" text,
   "FIELD_IDENTIFIER" integer,
@@ -672,13 +674,14 @@
 DROP TABLE IF EXISTS "STRUCT_ITEM";
 CREATE TABLE IF NOT EXISTS STRUCT_ITEM (
   STRUCT_ITEM_ID integer NOT NULL PRIMARY KEY autoincrement,
-  STRUCT_REF integer,
+  STRUCT_REF integer NOT NULL,
   FIELD_IDENTIFIER integer,
   NAME text(100),
   IS_ARRAY integer,
   IS_ENUM integer,
   MIN_LENGTH integer,
   MAX_LENGTH integer,
+  DEFAULT_VALUE text,
   IS_WRITABLE integer,
   IS_NULLABLE integer,
   IS_OPTIONAL integer,
@@ -3433,7 +3436,7 @@
         ON
           ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
         WHERE
-          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF    
+          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF
       )
       ||
       (
@@ -3551,7 +3554,7 @@
         ON
           ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
         WHERE
-          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF    
+          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF
       )
       ||
       (
@@ -3578,7 +3581,7 @@
           C1.RESPONSE_REF = ETC.COMMAND_REF
         WHERE
           ETC.ENDPOINT_TYPE_COMMAND_ID = new.ENDPOINT_TYPE_COMMAND_ID
-      )   
+      )
     );
 END;
 
@@ -3663,7 +3666,7 @@
       ON
         ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
       WHERE
-        ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF    
+        ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF
     )
     ||
     (
@@ -3794,7 +3797,7 @@
         ON
           ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
         WHERE
-          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF    
+          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF
       )
       ||
       (
@@ -3821,7 +3824,7 @@
           C2.COMMAND_ID = C1.RESPONSE_REF
         WHERE
           ETC.ENDPOINT_TYPE_COMMAND_ID = new.ENDPOINT_TYPE_COMMAND_ID
-      )   
+      )
     );
 END;
 
@@ -3909,7 +3912,7 @@
         ON
           ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
         WHERE
-          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF    
+          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF
       )
       ||
       (
@@ -4027,7 +4030,7 @@
         ON
           ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
         WHERE
-          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF    
+          ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID = new.ENDPOINT_TYPE_CLUSTER_REF
       )
       ||
       (
@@ -4054,7 +4057,7 @@
           C1.RESPONSE_REF = ETC.COMMAND_REF
         WHERE
           ETC.ENDPOINT_TYPE_COMMAND_ID = new.ENDPOINT_TYPE_COMMAND_ID
-      )   
+      )
     );
 END;
 
diff --git a/src-electron/generator/generation-engine.js b/src-electron/generator/generation-engine.js
index f496fe5..73d23a9 100644
--- a/src-electron/generator/generation-engine.js
+++ b/src-electron/generator/generation-engine.js
@@ -34,6 +34,30 @@
 const queryNotification = require('../db/query-package-notification.js')
 
 /**
+ * Finds and reads JSON files referenced in a nested object.
+ *
+ * @param {Object} obj - The object to search for JSON file references.
+ * @param {string} basePath - The base directory to resolve relative paths.
+ * @returns {Promise<string>} - A promise that resolves to the concatenated content of all JSON files.
+ */
+async function findAndReadJsonFiles(obj, basePath) {
+  let additionalJsonContent = ''
+  for (const key in obj) {
+    if (typeof obj[key] === 'string' && obj[key].endsWith('.json')) {
+      // If the value is a JSON file reference, read its content
+      let jsonFilePath = path.resolve(path.join(basePath, obj[key]))
+      if (fs.existsSync(jsonFilePath)) {
+        additionalJsonContent += await fsPromise.readFile(jsonFilePath, 'utf8')
+      }
+    } else if (typeof obj[key] === 'object' && obj[key] !== null) {
+      // If the value is an object, recursively search for JSON file references
+      additionalJsonContent += await findAndReadJsonFiles(obj[key], basePath)
+    }
+  }
+  return additionalJsonContent
+}
+
+/**
  * Given a path, it will read generation template object into memory.
  *
  * @param {*} templatePath
@@ -42,34 +66,15 @@
 async function loadGenTemplateFromFile(templatePath) {
   let ret = {}
   ret.data = await fsPromise.readFile(templatePath, 'utf8')
-  ret.crc = util.checksum(ret.data)
   ret.templateData = JSON.parse(ret.data)
-  let zclExtension = ret.templateData.zcl
-  let zclExtensionFileContent = ''
-  // Adding zcl extension files to the template json crc
-  if (zclExtension && typeof zclExtension === 'object') {
-    for (const key of Object.keys(zclExtension)) {
-      let extension = zclExtension[key]
-      for (const key2 of Object.keys(extension)) {
-        let defaultExtensionValue = extension[key2].defaults
-        if (
-          typeof defaultExtensionValue === 'string' ||
-          defaultExtensionValue instanceof String
-        ) {
-          // Data is a string, so we will treat it as a relative path to the JSON file.
-          let externalPath = path.resolve(
-            path.join(path.dirname(templatePath), defaultExtensionValue)
-          )
-          zclExtensionFileContent += await fsPromise.readFile(
-            externalPath,
-            'utf8'
-          )
-        }
-      }
-    }
-    ret.crc = util.checksum(ret.data + zclExtensionFileContent)
-  }
-
+  // Find the json files within the gen template json files and add them to the
+  // crc as well.
+  let allJsonContentInTemplatePath = await findAndReadJsonFiles(
+    ret.templateData,
+    path.dirname(templatePath)
+  )
+  let checksumData = ret.data + allJsonContentInTemplatePath
+  ret.crc = util.checksum(checksumData)
   let requiredFeatureLevel = 0
   if ('requiredFeatureLevel' in ret.templateData) {
     requiredFeatureLevel = ret.templateData.requiredFeatureLevel
diff --git a/src-electron/generator/helper-c.js b/src-electron/generator/helper-c.js
index 2cb2c23..5664949 100644
--- a/src-electron/generator/helper-c.js
+++ b/src-electron/generator/helper-c.js
@@ -69,7 +69,14 @@
     return `0x${value.slice(2).toUpperCase()}`
   } else {
     let val = parseInt(value)
-    return `0x${val.toString(16).padStart(padding, '0').toUpperCase()}`
+    let paddingLength = padding
+    if (!paddingLength) {
+      paddingLength =
+        val.toString(16).length % 2 === 0
+          ? val.toString(16).length
+          : val.toString(16).length + 1
+    }
+    return `0x${val.toString(16).padStart(paddingLength, '0').toUpperCase()}`
   }
 }
 
diff --git a/src-electron/generator/matter/app/zap-templates/common/ClusterTestGeneration.js b/src-electron/generator/matter/app/zap-templates/common/ClusterTestGeneration.js
index e4aa9ac..f99ebb3 100644
--- a/src-electron/generator/matter/app/zap-templates/common/ClusterTestGeneration.js
+++ b/src-electron/generator/matter/app/zap-templates/common/ClusterTestGeneration.js
@@ -1454,6 +1454,9 @@
  * @returns data type as String
  */
 async function asTestType(type, isList) {
+  // NOTE: This is not used on current Matter tip, so the fact that it does not
+  // cluster-scope type names is not an issue.
+
   if (isList) {
     return 'list';
   }
diff --git a/src-electron/generator/matter/app/zap-templates/templates/app/helper.js b/src-electron/generator/matter/app/zap-templates/templates/app/helper.js
index 71cecfe..84c8c30 100644
--- a/src-electron/generator/matter/app/zap-templates/templates/app/helper.js
+++ b/src-electron/generator/matter/app/zap-templates/templates/app/helper.js
@@ -588,6 +588,52 @@
   return ns;
 }
 
+// Not to be exported.
+//
+// dataType can be "Enum", "Struct", or "Bitmap".
+async function getClusterCountForType(db, pkgId, type, dataType, options) {
+  if (options.hash.cluster === '') {
+    // This is a non-global data type that is associated with multiple
+    // clusters: in that case our caller can pass in cluster="", and
+    // we know that clusterCount > 1, so just set it to 2.
+    return 2;
+  }
+
+  const cluster = options.hash.cluster || options.hash.ns;
+  const typeObj = await zclQuery[`select${dataType}ByNameAndClusterName`](
+    db,
+    type,
+    cluster,
+    pkgId
+  );
+  if (typeObj) {
+    return typeObj[`${dataType.toLowerCase()}ClusterCount`];
+  }
+
+  if (options.hash.cluster === undefined) {
+    // Backwards-compat case: we were called without ns or cluster at all
+    // (not even cluster="").  Just get by name, since that's all we have to
+    // work with.  It won't work right when names are not unique, but that's
+    // the best we can do.
+    //
+    // selectBitmapByName has different argument ordering from selectEnumByName
+    // and selectStructByName, so account for that here.
+    const isBitmap = dataType == 'Bitmap';
+    const backwardsCompatTypeObj = await zclQuery[`select${dataType}ByName`](
+      db,
+      isBitmap ? pkgId : type,
+      isBitmap ? type : pkgId
+    );
+    return backwardsCompatTypeObj[`${dataType.toLowerCase()}ClusterCount`];
+  }
+
+  // Something is wrong here.  Possibly the caller is passing in a munged
+  // cluster name.  Just fail out instead of silently returning bad data.
+  throw new Error(
+    `Unable to find ${dataType.toLowerCase()} ${type} in cluster ${options.hash.cluster}`
+  );
+}
+
 /*
  * @brief
  *
@@ -641,12 +687,14 @@
         return 'uint' + s[1] + '_t';
       }
 
-      const enumObj = await zclQuery.selectEnumByName(
+      const clusterCount = await getClusterCountForType(
         this.global.db,
+        pkgId,
         type,
-        pkgId
+        'Enum',
+        options
       );
-      const ns = nsValueToNamespace(options.hash.ns, enumObj.enumClusterCount);
+      const ns = nsValueToNamespace(options.hash.ns, clusterCount);
       return ns + asUpperCamelCase.call(this, type, options);
     }
 
@@ -657,15 +705,14 @@
         return 'uint' + s[1] + '_t';
       }
 
-      const bitmapObj = await zclQuery.selectBitmapByName(
+      const clusterCount = await getClusterCountForType(
         this.global.db,
         pkgId,
-        type
+        type,
+        'Bitmap',
+        options
       );
-      const ns = nsValueToNamespace(
-        options.hash.ns,
-        bitmapObj.bitmapClusterCount
-      );
+      const ns = nsValueToNamespace(options.hash.ns, clusterCount);
       return (
         'chip::BitMask<' + ns + asUpperCamelCase.call(this, type, options) + '>'
       );
@@ -673,15 +720,14 @@
 
     if (types.isStruct) {
       passByReference = true;
-      const structObj = await zclQuery.selectStructByName(
+      const clusterCount = await getClusterCountForType(
         this.global.db,
+        pkgId,
         type,
-        pkgId
+        'Struct',
+        options
       );
-      const ns = nsValueToNamespace(
-        options.hash.ns,
-        structObj.structClusterCount
-      );
+      const ns = nsValueToNamespace(options.hash.ns, clusterCount);
       return (
         ns +
         'Structs::' +
@@ -768,16 +814,14 @@
         return 'uint';
       }
 
-      const enumObj = await zclQuery.selectEnumByName(
+      const clusterCount = await getClusterCountForType(
         this.global.db,
+        pkgId,
         type,
-        pkgId
+        'Enum',
+        options
       );
-
-      const ns = nsValueToPythonNamespace(
-        options.hash.ns,
-        enumObj.enumClusterCount
-      );
+      const ns = nsValueToPythonNamespace(options.hash.ns, clusterCount);
 
       return ns + '.Enums.' + type;
     }
@@ -787,16 +831,14 @@
     }
 
     if (await typeChecker('isStruct')) {
-      const structObj = await zclQuery.selectStructByName(
+      const clusterCount = await getClusterCountForType(
         this.global.db,
+        pkgId,
         type,
-        pkgId
+        'Struct',
+        options
       );
-
-      const ns = nsValueToPythonNamespace(
-        options.hash.ns,
-        structObj.structClusterCount
-      );
+      const ns = nsValueToPythonNamespace(options.hash.ns, clusterCount);
 
       return ns + '.Structs.' + type;
     }
@@ -887,16 +929,14 @@
     }
 
     if (await typeChecker('isStruct')) {
-      const structObj = await zclQuery.selectStructByName(
+      const clusterCount = await getClusterCountForType(
         this.global.db,
+        pkgId,
         type,
-        pkgId
+        'Struct',
+        options
       );
-
-      const ns = nsValueToPythonNamespace(
-        options.hash.ns,
-        structObj.structClusterCount
-      );
+      const ns = nsValueToPythonNamespace(options.hash.ns, clusterCount);
 
       return 'field(default_factory=lambda: ' + ns + '.Structs.' + type + '())';
     }
@@ -1073,7 +1113,19 @@
 // struct.
 async function if_is_fabric_scoped_struct(type, options) {
   let packageIds = await templateUtil.ensureZclPackageIds(this);
-  let st = await zclQuery.selectStructByName(this.global.db, type, packageIds);
+  let st;
+  if (options.hash.cluster) {
+    st = await zclQuery.selectStructByNameAndClusterName(
+      this.global.db,
+      type,
+      options.hash.cluster,
+      packageIds
+    );
+  } else {
+    // Backwards compat case; will not work right when multiple structs share
+    // the same name.
+    st = await zclQuery.selectStructByName(this.global.db, type, packageIds);
+  }
 
   if (st && st.isFabricScoped) {
     return options.fn(this);
diff --git a/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js b/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js
index b986e1e..de23bc6 100644
--- a/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js
+++ b/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js
@@ -240,12 +240,27 @@
   }
 
   if (isStruct) {
-    const structObj = await zclQuery.selectStructByName(
+    let structObj = await zclQuery.selectStructByNameAndClusterName(
       this.global.db,
       type,
+      cluster,
       pkgIds
     );
-    if (structObj.structClusterCount == 0) {
+
+    let isGlobalStruct;
+    if (!structObj) {
+      // Can end up here when our "cluster name" is a backwards compat name.
+      // Just fetch by struct name only in that case.
+      structObj = await zclQuery.selectStructByName(
+        this.global.db,
+        type,
+        pkgIds
+      );
+      isGlobalStruct = structObj.structClusterCount == 0;
+    } else {
+      isGlobalStruct = !structObj.clusterName;
+    }
+    if (isGlobalStruct) {
       // This is a global struct.
       return `${
         options.hash.structTypePrefix || 'MTR'
@@ -297,7 +312,20 @@
 }
 
 function asStructPropertyName(prop) {
-  prop = appHelper.asLowerCamelCase(prop);
+  prop = appHelper.asLowerCamelCase(prop, { hash: { preserveAcronyms: true } });
+
+  // If prop is now all-uppercase (which can happen, because we are preserving
+  // acronyms), lowercase it.
+  if (prop.match(/^[A-Z0-9]+$/)) {
+    prop = prop.toLowerCase();
+  }
+
+  // If prop is now all-uppercase, with at least two capital letters followed by
+  // a lowercase "s" (probably acronym being pluralized), just lowercase the
+  // whole thing.
+  if (prop.match(/^[A-Z][A-Z]+s$/)) {
+    prop = prop.toLowerCase();
+  }
 
   // If prop is now "description", we need to rename it, because that's
   // reserved.
@@ -307,8 +335,8 @@
 
   // If prop starts with a sequence of capital letters (which can happen for
   // output of asLowerCamelCase if the original string started that way),
-  // lowercase all but the last one.
-  return prop.replace(/^([A-Z]+)([A-Z])/, (match, p1, p2) => {
+  // followed by a lowercase letter, lowercase all but the last capital letter.
+  return prop.replace(/^([A-Z]+)([A-Z][a-z])/, (match, p1, p2) => {
     return p1.toLowerCase() + p2;
   });
 }
diff --git a/src-electron/importexport/import-json.js b/src-electron/importexport/import-json.js
index 35c4624..0c265ee 100644
--- a/src-electron/importexport/import-json.js
+++ b/src-electron/importexport/import-json.js
@@ -439,14 +439,10 @@
   specMessageIndent
 ) {
   let relevantZclPackageIds = allZclPackageIds
-  // Get all custom xml packages since they will be relevant packages as well.
   let packageInfo = await queryPackage.getPackagesByPackageIds(
     db,
     allZclPackageIds
   )
-  let customPackageInfo = packageInfo.filter(
-    (pkg) => pkg.type === dbEnum.packageType.zclXmlStandalone
-  )
   let endpointTypeDeviceTypesInfo =
     await queryDeviceType.selectDeviceTypesByEndpointTypeId(db, endpointTypeId)
   let deviceTypeRefs = endpointTypeDeviceTypesInfo.map(
@@ -457,12 +453,28 @@
       db,
       deviceTypeRefs[0]
     )
-    relevantZclPackageIds = [deviceTypeInfo.packageRef]
-
-    // If custom packages exist then account for them during import.
-    if (customPackageInfo && customPackageInfo.length > 0) {
-      let customPackageInfoIds = customPackageInfo.map((cp) => cp.id)
-      relevantZclPackageIds = relevantZclPackageIds.concat(customPackageInfoIds)
+    let deviceTypePackageInfo = packageInfo.find(
+      (pkg) => pkg.id == deviceTypeInfo.packageRef
+    )
+    if (
+      deviceTypePackageInfo &&
+      deviceTypePackageInfo.type === dbEnum.packageType.zclXmlStandalone
+    ) {
+      // If the device type comes from a custom xml, then we pass in all zcl and custom xml packages
+      relevantZclPackageIds = packageInfo
+        .filter(
+          (pkg) =>
+            pkg.type === dbEnum.packageType.zclXmlStandalone ||
+            pkg.type === dbEnum.packageType.zclProperties
+        )
+        .map((pkg) => pkg.id)
+    } else {
+      // If the device types comes from the zcl file, then we pass in that zcl file and all custom xml packages
+      relevantZclPackageIds = [deviceTypeInfo.packageRef]
+      let customPackageIds = packageInfo
+        .filter((pkg) => pkg.type == dbEnum.packageType.zclXmlStandalone)
+        .map((pkg) => pkg.id)
+      relevantZclPackageIds = relevantZclPackageIds.concat(customPackageIds)
     }
   }
   let conformanceWarnings = ''
diff --git a/src-electron/rest/user-data.js b/src-electron/rest/user-data.js
index 36672d9..4f58247 100644
--- a/src-electron/rest/user-data.js
+++ b/src-electron/rest/user-data.js
@@ -330,17 +330,13 @@
     let sessionId = request.zapSessionId
 
     try {
-      let packageId = await queryPackage
-        .getSessionPackagesByType(
-          db,
-          sessionId,
-          dbEnum.packageType.zclProperties
-        )
-        .then((pkgs) => pkgs?.shift()?.id) // default to always picking first package
-
-      if (packageId == null) {
-        throw new Error('Unable to find packageId')
-      }
+      let pkgs = await queryPackage.getSessionPackagesWithTypes(db, sessionId)
+      pkgs = pkgs.filter(
+        (pkg) =>
+          pkg.type == dbEnum.packageType.zclProperties ||
+          pkg.type == dbEnum.packageType.zclXmlStandalone
+      )
+      let packageIds = pkgs.map((pkg) => pkg.packageRef)
 
       let insertDefault = await queryConfig
         .selectClusterState(db, endpointTypeId, id, side)
@@ -355,10 +351,15 @@
       )
 
       if (insertDefault) {
-        await queryConfig.insertClusterDefaults(db, endpointTypeId, packageId, {
-          clusterRef: id,
-          side: side
-        })
+        await queryConfig.insertClusterDefaults(
+          db,
+          endpointTypeId,
+          packageIds,
+          {
+            clusterRef: id,
+            side: side
+          }
+        )
       }
 
       response
diff --git a/src-electron/util/zcl-util.js b/src-electron/util/zcl-util.js
index a540f55..8ff2918 100644
--- a/src-electron/util/zcl-util.js
+++ b/src-electron/util/zcl-util.js
@@ -110,16 +110,9 @@
 }
 
 /**
- * This method retrieves a bunch of structs sorted
- * alphabetically. It's expected to resort the structs into a list
- * where they are sorted in a way where dependency is observed.
- *
- * It uses the DFS-based topological sort algorithm.
- *
- * @param {*} structs
- * @returns sorted structs according to topological search.
+ * Non-exported helper for sortStructsByDependency.
  */
-async function sortStructsByDependency(structs) {
+function sortStructsByDependencyHelper(structs) {
   let allStructNames = structs.map((s) => s.name)
   let edges = []
 
@@ -147,6 +140,37 @@
 }
 
 /**
+ * This method retrieves a bunch of structs sorted
+ * alphabetically. It's expected to resort the structs into a list
+ * where they are sorted in a way where dependency is observed.
+ *
+ * It uses the DFS-based topological sort algorithm.
+ *
+ * @param {*} structs
+ * @returns sorted structs according to topological search.
+ */
+async function sortStructsByDependency(structs) {
+  // Given global and non-global structs, the way dependencies work is this:
+  //
+  // 1) Global structs can only depend on other global structs.
+  // 2) Non-global structs can depend on either non-global or global structs.
+  //
+  // So we can output all global structs first (sorted by dependency), and then
+  // the non-global structs, again sorted by dependency.
+  //
+  // NOTE: the topological sort we use is not a stable sort, so adding some
+  // structs to the list can entirely change the order of all the structs.
+  let sortedGlobalStructs = sortStructsByDependencyHelper(
+    structs.filter((s) => s.struct_cluster_count == 0)
+  )
+  let sortedNonGlobalStructs = sortStructsByDependencyHelper(
+    structs.filter((s) => s.struct_cluster_count != 0)
+  )
+
+  return sortedGlobalStructs.concat(sortedNonGlobalStructs)
+}
+
+/**
  * This function calculates the number of bytes in the data type and based on
  * that returns the option specified in the template.
  * for eg: Given that options are as follows:
diff --git a/src-electron/zcl/zcl-loader-silabs.js b/src-electron/zcl/zcl-loader-silabs.js
index 2ea3259..bf0549e 100644
--- a/src-electron/zcl/zcl-loader-silabs.js
+++ b/src-electron/zcl/zcl-loader-silabs.js
@@ -254,6 +254,20 @@
           returnObject.featureFlags = zclProps.featureFlags
         }
 
+        // ZCLDataTypes
+        if (zclProps.zclDataTypes) {
+          returnObject.ZCLDataTypes = zclProps.ZCLDataTypes
+        } else {
+          returnObject.ZCLDataTypes = [
+            'ARRAY',
+            'BITMAP',
+            'ENUM',
+            'NUMBER',
+            'STRING',
+            'STRUCT'
+          ]
+        }
+
         returnObject.supportCustomZclDevice = zclProps.supportCustomZclDevice
         returnObject.version = zclProps.version
         returnObject.description = zclProps.description
@@ -524,6 +538,7 @@
               max: arg.$.max,
               minLength: 0,
               maxLength: arg.$.length ? arg.$.length : null,
+              defaultValue: arg.$.default ? arg.$.default : null,
               isArray: arg.$.array == 'true' ? 1 : 0,
               presentIf: arg.$.presentIf,
               isNullable: arg.$.isNullable == 'true' ? true : false,
@@ -571,6 +586,7 @@
             ev.fields.push({
               name: field.$.name,
               type: field.$.type,
+              defaultValue: field.$.default ? field.$.default : null,
               isArray: field.$.array == 'true' ? 1 : 0,
               isNullable: field.$.isNullable == 'true' ? true : false,
               isOptional: field.$.optional == 'true' ? true : false,
@@ -1634,6 +1650,7 @@
           fieldIdentifier: lastFieldId,
           minLength: 0,
           maxLength: item.$.length ? item.$.length : null,
+          defaultValue: item.$.default ? item.$.default : null,
           isWritable: item.$.writable == 'true',
           isArray: item.$.array == 'true' ? true : false,
           isEnum: item.$.enum == 'true' ? true : false,
@@ -1779,6 +1796,22 @@
 }
 
 /**
+ * Processes and reloads device type entities in the database.
+ * This function is called when a custom xml with device types is reloaded.
+ *
+ * @returns {Promise} A promise that resolves after all device types have been reloaded.
+ */
+async function processReloadDeviceTypes(db, packageId, data, sessionPackages) {
+  let deviceTypes = data.map((x) => prepareDeviceType(x))
+  return queryLoader.reloadDeviceTypes(
+    db,
+    packageId,
+    deviceTypes,
+    sessionPackages
+  )
+}
+
+/**
  * Process promises for loading the data types
  * @param {*} db
  * @param {*} filePath
@@ -2708,17 +2741,45 @@
     if (result.data) {
       result.result = await util.parseXml(result.data)
       delete result.data
-      // Just adding the cluster attribute and command extensions for a cluster
-      // because they can be related to any top level package in the .zap config
       if (
         result.customXmlReload &&
         result.result.configurator &&
-        result.result.configurator.clusterExtension
+        (result.result.configurator.clusterExtension ||
+          result.result.configurator.deviceType)
       ) {
-        result.result = {
-          configurator: {
-            clusterExtension: result.result.configurator.clusterExtension
+        // If custom xml has device types, reload them so the device type entities are correctly linked
+        if (result.result.configurator.deviceType) {
+          let sessionPackages = await queryPackage.getSessionZclPackages(
+            db,
+            sessionId
+          )
+          let knownPackages = sessionPackages
+            .filter((pkg) =>
+              [
+                dbEnum.packageType.zclProperties,
+                dbEnum.packageType.zclXmlStandalone
+              ].includes(pkg.type)
+            )
+            .map((pkg) => pkg.packageRef)
+          await processReloadDeviceTypes(
+            db,
+            pkgId,
+            result.result.configurator.deviceType,
+            knownPackages
+          )
+        }
+        // Reload cluster extension to link it to the correct top level package (if it exists)
+        if (result.result.configurator.clusterExtension) {
+          result.result = {
+            configurator: {
+              clusterExtension: result.result.configurator.clusterExtension
+            }
           }
+        } else {
+          env.logDebug(
+            `CRC match for file ${result.filePath} (${result.crc}), skipping parsing.`
+          )
+          delete result.result
         }
       } else if (
         result.customXmlReload &&
@@ -2731,6 +2792,7 @@
         delete result.result
       }
     }
+
     let sessionPackages = await queryPackage.getSessionZclPackages(
       db,
       sessionId
@@ -2786,6 +2848,23 @@
     await queryPackage.insertSessionPackage(db, sessionPartitionId, pkgId, true)
 
     await zclLoader.processZclPostLoading(db, pkgId)
+
+    // additional post-processing for custom xml
+    let knownPackages = sessionPackages
+      .filter((pkg) =>
+        [
+          dbEnum.packageType.zclProperties,
+          dbEnum.packageType.zclXmlStandalone
+        ].includes(pkg.type)
+      )
+      .map((pkg) => pkg.packageRef)
+    await queryDeviceType.updateDeviceTypeReferencesForCustomXml(
+      db,
+      pkgId,
+      knownPackages,
+      sessionId
+    )
+
     return { succeeded: true, packageId: pkgId }
   } catch (err) {
     env.logError(`Error reading xml file: ${filePath}\n` + err.message)
diff --git a/src-electron/zcl/zcl-loader.js b/src-electron/zcl/zcl-loader.js
index d8e37e5..16527e9 100644
--- a/src-electron/zcl/zcl-loader.js
+++ b/src-electron/zcl/zcl-loader.js
@@ -353,8 +353,9 @@
     }
   } else {
     // This is executed if CRC is found in the database and matches the actual CRC.
+
     // Sending data back when it is a custom xml
-    if (parentPackageId == null) {
+    if (packageType === dbEnum.packageType.zclXmlStandalone) {
       return {
         filePath: filePath,
         data: data,
@@ -363,6 +364,7 @@
         crc: actualCrc
       }
     }
+
     env.logDebug(
       `CRC match for file ${pkg.path} (${pkg.crc}), skipping parsing.`
     )
diff --git a/src-script/pack-apack-mac.js b/src-script/pack-apack-mac.js
index 459eeef..a873278 100644
--- a/src-script/pack-apack-mac.js
+++ b/src-script/pack-apack-mac.js
@@ -5,31 +5,48 @@
 const pathTo7zip = sevenBin.path7za
 
 exports.default = async function (buildResult) {
-  buildResult?.artifactPaths?.forEach((element) => {
+  for (const element of buildResult?.artifactPaths || []) {
     if (
       (element.includes('mac') ||
         element.includes('win') ||
         element.includes('linux')) &&
       element.endsWith('.zip')
     ) {
-      const myStream = Seven.add(
-        element,
-        path.join(buildResult.outDir, '../apack.json'),
-        {
-          $progress: true,
-          $bin: pathTo7zip
-        }
-      )
-      // myStream.on('end', function () {
-      //   console.log(myStream.info)
-      // })
+      // Add apack.json first
+      await new Promise((resolve, reject) => {
+        const myStream1 = Seven.add(
+          element, // The .zip file (output)
+          path.join(buildResult.outDir, '../apack.json'), // Add apack.json
+          {
+            $progress: true,
+            $bin: pathTo7zip
+          }
+        )
 
-      myStream.on('error', function (err) {
-        if (err) {
-          console.log(err.stderr)
-          throw err
-        }
+        myStream1.on('end', resolve)
+        myStream1.on('error', (err) => {
+          console.log('Error adding apack.json:', err.stderr)
+          reject(err)
+        })
+      })
+
+      // Then add zap.png after apack.json is added
+      await new Promise((resolve, reject) => {
+        const myStream2 = Seven.add(
+          element, // The .zip file (output)
+          path.join(buildResult.outDir, '../src/assets/zap.png'), // Add zap.png
+          {
+            $progress: true,
+            $bin: pathTo7zip
+          }
+        )
+
+        myStream2.on('end', resolve)
+        myStream2.on('error', (err) => {
+          console.log('Error adding zap.png:', err.stderr)
+          reject(err)
+        })
       })
     }
-  })
+  }
 }
diff --git a/src-script/pack-apack-win-linux.js b/src-script/pack-apack-win-linux.js
index 0120f9f..7eaaedc 100644
--- a/src-script/pack-apack-win-linux.js
+++ b/src-script/pack-apack-win-linux.js
@@ -6,12 +6,14 @@
     context.electronPlatformName === 'win32' ||
     context.electronPlatformName === 'linux'
   ) {
-    return scriptUtil.executeCmd({}, 'npx', [
+    await scriptUtil.executeCmd({}, 'npx', [
       'copyfiles',
       '-V',
       '-f',
       path.resolve(context.outDir, '../apack.json'),
+      path.resolve(context.outDir, '../src/assets/zap.png'),
       context.appOutDir
     ])
+    console.log('Files copied successfully.')
   }
 }
diff --git a/src/App.vue b/src/App.vue
index 0a623e8..7798897 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -248,6 +248,10 @@
         }
         this.$store.dispatch('zap/updateSelectedEndpoint', endpoint.id)
         this.$store.commit('zap/toggleEndpointModal', false)
+        this.$store.dispatch(
+          'zap/updateDeviceTypeClustersForSelectedEndpoint',
+          this.endpointDeviceTypeRef[this.endpointType[endpoint.id]]
+        )
       }
     },
     getAppData() {
diff --git a/src/components/ZclClusterManager.vue b/src/components/ZclClusterManager.vue
index 7ea46d3..c55573b 100644
--- a/src/components/ZclClusterManager.vue
+++ b/src/components/ZclClusterManager.vue
@@ -199,8 +199,9 @@
     },
     relevantClusters: {
       get() {
+        let relevantClusters = []
         if (this.clusters.clusterData) {
-          return this.clusters.clusterData.filter((cluster) =>
+          relevantClusters = this.clusters.clusterData.filter((cluster) =>
             this.filterString == ''
               ? true
               : cluster.label
@@ -208,7 +209,7 @@
                   .includes(this.filterString.toLowerCase())
           )
         } else {
-          return this.clusters.filter((cluster) =>
+          relevantClusters = this.clusters.filter((cluster) =>
             this.filterString == ''
               ? true
               : cluster.label
@@ -216,6 +217,8 @@
                   .includes(this.filterString.toLowerCase())
           )
         }
+        this.$store.commit('zap/setRelevantClusters', relevantClusters)
+        return relevantClusters
       }
     },
     enabledClusters: {
@@ -227,6 +230,12 @@
         return clusters
       }
     },
+    deviceTypeClustersForSelectedEndpoint: {
+      get() {
+        return this.$store.state.zap.endpointTypeView
+          .deviceTypeClustersForSelectedEndpoint
+      }
+    },
     filterOptions: {
       get() {
         return this.$store.state.zap.clusterManager.filterOptions
@@ -302,7 +311,12 @@
         .filter((a) => {
           return typeof this.filter.clusterFilterFn === 'function'
             ? this.filter.clusterFilterFn(a, {
-                enabledClusters: this.enabledClusters
+                enabledClusters: this.enabledClusters,
+                relevantClusters: this.relevantClusters,
+                deviceTypeRefsForSelectedEndpoint:
+                  this.endpointDeviceTypeRef[this.selectedEndpointId],
+                deviceTypeClustersForSelectedEndpoint:
+                  this.deviceTypeClustersForSelectedEndpoint
               })
             : true
         })
@@ -339,7 +353,12 @@
     changeDomainFilter(filter) {
       this.$store.dispatch('zap/setDomainFilter', {
         filter: filter,
-        enabledClusters: this.enabledClusters
+        enabledClusters: this.enabledClusters,
+        relevantClusters: this.relevantClusters,
+        deviceTypeRefsForSelectedEndpoint:
+          this.endpointDeviceTypeRef[this.selectedEndpointId],
+        deviceTypeClustersForSelectedEndpoint:
+          this.deviceTypeClustersForSelectedEndpoint
       })
     },
     doActionFilter(filter) {
diff --git a/src/components/ZclCreateModifyEndpoint.vue b/src/components/ZclCreateModifyEndpoint.vue
index 04dbff0..b5f88e8 100644
--- a/src/components/ZclCreateModifyEndpoint.vue
+++ b/src/components/ZclCreateModifyEndpoint.vue
@@ -780,6 +780,10 @@
                 deviceTypeRefs: deviceTypeRef,
                 endpointTypeRef: res.id
               })
+              this.$store.dispatch(
+                'zap/updateDeviceTypeClustersForSelectedEndpoint',
+                this.endpointDeviceTypeRef[this.endpointType[res.id]]
+              )
             })
         })
         .catch((err) => console.log('Error in newEpt: ' + err.message))
@@ -861,6 +865,10 @@
         deviceTypeRefs: deviceTypeRef,
         endpointTypeRef: this.endpointReference
       })
+      this.$store.dispatch(
+        'zap/updateDeviceTypeClustersForSelectedEndpoint',
+        deviceTypeRef
+      )
     },
     getDeviceOptionLabel(item) {
       if (item == null || item.deviceTypeRef == null) return ''
diff --git a/src/components/ZclDomainClusterView.vue b/src/components/ZclDomainClusterView.vue
index f74b16a..658e903 100644
--- a/src/components/ZclDomainClusterView.vue
+++ b/src/components/ZclDomainClusterView.vue
@@ -166,6 +166,14 @@
               :options="optionsForCheckboxes"
               color="primary"
               type="checkbox"
+              :disable="{
+                client:
+                  getClusterDisableStatus(props.row.id).client ||
+                  !getClusterEnableStatus(props.row.id).client,
+                server:
+                  getClusterDisableStatus(props.row.id).server ||
+                  !getClusterEnableStatus(props.row.id).server
+              }"
               @update:model-value="handleClusterSelection(props.row.id, $event)"
               inline
             />
@@ -239,6 +247,11 @@
   props: ['domainName', 'clusters'],
   mixins: [CommonMixin, uiOptions, EditableAttributesMixin],
   computed: {
+    isLegalClusterFilterActive() {
+      return (
+        this.$store.state.zap.clusterManager.filter.label === 'Legal Clusters'
+      )
+    },
     isInStandalone: {
       get() {
         return this.$store.state.zap.standalone
@@ -254,6 +267,18 @@
         return this.$store.state.zap.clustersView.recommendedServers
       }
     },
+    // Includes client clusters which are optional for a device type
+    optionalClients: {
+      get() {
+        return this.$store.state.zap.clustersView.optionalClients
+      }
+    },
+    // Includes server clusters which are optional for a device type
+    optionalServers: {
+      get() {
+        return this.$store.state.zap.clustersView.optionalServers
+      }
+    },
     visibleColumns: function () {
       let names = this.columns.map((x) => x.name)
       let statusColumn = 'status'
@@ -281,6 +306,38 @@
     }
   },
   methods: {
+    getClusterEnableStatus(id) {
+      // Only enforce constraints if the active filter is "Legal Clusters"
+      if (!this.isLegalClusterFilterActive) {
+        return { client: true, server: true } // Allow all actions
+      }
+      let isClientRecommended = this.recommendedClients.includes(id)
+      let isServerRecommended = this.recommendedServers.includes(id)
+      let isClientOptional = this.optionalClients.includes(id)
+      let isServerOptional = this.optionalServers.includes(id)
+      let isClientEnabled = this.selectionClients.includes(id)
+      let isServerEnabled = this.selectionServers.includes(id)
+
+      return {
+        client: isClientRecommended || isClientOptional || isClientEnabled, // Allow enabling only if recommended, optional, or already enabled
+        server: isServerRecommended || isServerOptional || isServerEnabled // Allow enabling only if recommended, optional, or already enabled
+      }
+    },
+    getClusterDisableStatus(id) {
+      // Only enforce constraints if the active filter is "Legal Clusters"
+      if (!this.isLegalClusterFilterActive) {
+        return { client: false, server: false } // No constraints
+      }
+
+      let isClientRecommended = this.recommendedClients.includes(id)
+      let isServerRecommended = this.recommendedServers.includes(id)
+      let isClientOptional = this.optionalClients.includes(id)
+      let isServerOptional = this.optionalServers.includes(id)
+      return {
+        client: isClientRecommended && !isClientOptional, // Disable if recommended and not optional
+        server: isServerRecommended && !isServerOptional // Disable if recommended and not optional
+      }
+    },
     enableAllClusters() {
       this.clusters.forEach(async (singleCluster) => {
         await this.updateZclRolesByClusterSelection(singleCluster.id, [
@@ -499,6 +556,57 @@
       return tmpEvent
     },
     async handleClusterSelection(id, event) {
+      const activeFilter = this.$store.state.zap.clusterManager.filter.label
+
+      // Only enforce constraints if the active filter is "Legal Clusters"
+      if (activeFilter === 'Legal Clusters') {
+        const disableStatus = this.getClusterDisableStatus(id)
+        const enableStatus = this.getClusterEnableStatus(id)
+
+        // Prevent disabling recommended client
+        if (disableStatus.client && event.includes('client') === false) {
+          this.$q.notify({
+            type: 'warning',
+            position: 'top',
+            message:
+              'You cannot disable a required client cluster for the device types on this endpoint when using a Legal Clusters Filter.'
+          })
+          return
+        }
+
+        // Prevent disabling recommended server
+        if (disableStatus.server && event.includes('server') === false) {
+          this.$q.notify({
+            type: 'warning',
+            position: 'top',
+            message:
+              'You cannot disable a required server cluster for the device types on this endpoint when using a Legal Clusters Filter.'
+          })
+          return
+        }
+
+        // Prevent enabling non-recommended client
+        if (!enableStatus.client && event.includes('client') === true) {
+          this.$q.notify({
+            type: 'warning',
+            position: 'top',
+            message:
+              'You cannot enabled a client cluster not required by the device types on this endpoint when using a Legal Clusters Filter.'
+          })
+          return
+        }
+
+        // Prevent enabling non-recommended server
+        if (!enableStatus.server && event.includes('server') === true) {
+          this.$q.notify({
+            type: 'warning',
+            position: 'top',
+            message:
+              'You cannot enabled a server cluster not required by the device types on this endpoint when using a Legal Clusters Filter.'
+          })
+          return
+        }
+      }
       let modifiedEvent = this.parseCheckboxEventToSelectionEvent(event)
       let selectionEvents = this.processZclSelectionEvent(id, modifiedEvent)
 
diff --git a/src/store/zap/actions.js b/src/store/zap/actions.js
index f8e3606..4eba9f4 100644
--- a/src/store/zap/actions.js
+++ b/src/store/zap/actions.js
@@ -405,27 +405,30 @@
   context,
   endpointTypeIdDeviceTypeRefPair
 ) {
-  axiosRequests
-    .$serverGet(
-      `${restApi.uri.deviceTypeClusters}${endpointTypeIdDeviceTypeRefPair.deviceTypeRef}`
+  Promise.all(
+    endpointTypeIdDeviceTypeRefPair.deviceTypeRef.map((ref) =>
+      axiosRequests.$serverGet(`${restApi.uri.deviceTypeClusters}${ref}`)
     )
-    .then((res) => {
-      setRecommendedClusterList(context, res.data)
-    })
-  axiosRequests
-    .$serverGet(
-      `${restApi.uri.deviceTypeAttributes}${endpointTypeIdDeviceTypeRefPair.deviceTypeRef}`
+  ).then((responses) => {
+    const allClusters = responses.flatMap((res) => res.data)
+    setRecommendedClusterList(context, allClusters)
+  })
+  Promise.all(
+    endpointTypeIdDeviceTypeRefPair.deviceTypeRef.map((ref) =>
+      axiosRequests.$serverGet(`${restApi.uri.deviceTypeAttributes}${ref}`)
     )
-    .then((res) => {
-      setRequiredAttributes(context, res.data)
-    })
-  axiosRequests
-    .$serverGet(
-      `${restApi.uri.deviceTypeCommands}${endpointTypeIdDeviceTypeRefPair.deviceTypeRef}`
+  ).then((responses) => {
+    const allAttributes = responses.flatMap((res) => res.data)
+    setRequiredAttributes(context, allAttributes)
+  })
+  Promise.all(
+    endpointTypeIdDeviceTypeRefPair.deviceTypeRef.map((ref) =>
+      axiosRequests.$serverGet(`${restApi.uri.deviceTypeCommands}${ref}`)
     )
-    .then((res) => {
-      setRequiredCommands(context, res.data)
-    })
+  ).then((responses) => {
+    const allCommands = responses.flatMap((res) => res.data)
+    setRequiredCommands(context, allCommands)
+  })
 
   axiosRequests
     .$serverGet(
@@ -709,33 +712,35 @@
           setEventStateLists(context, res.data || [])
         })
     )
-
     p.push(
-      axiosRequests
-        .$serverGet(
-          `${restApi.uri.deviceTypeClusters}${endpointTypeDeviceTypeRefPair.deviceTypeRef}`
+      Promise.all(
+        endpointTypeDeviceTypeRefPair.deviceTypeRef.map((ref) =>
+          axiosRequests.$serverGet(`${restApi.uri.deviceTypeClusters}${ref}`)
         )
-        .then((res) => {
-          setRecommendedClusterList(context, res.data)
-        })
+      ).then((responses) => {
+        const allClusters = responses.flatMap((res) => res.data)
+        setRecommendedClusterList(context, allClusters)
+      })
     )
     p.push(
-      axiosRequests
-        .$serverGet(
-          `${restApi.uri.deviceTypeAttributes}${endpointTypeDeviceTypeRefPair.deviceTypeRef}`
+      Promise.all(
+        endpointTypeDeviceTypeRefPair.deviceTypeRef.map((ref) =>
+          axiosRequests.$serverGet(`${restApi.uri.deviceTypeAttributes}${ref}`)
         )
-        .then((res) => {
-          setRequiredAttributes(context, res.data)
-        })
+      ).then((responses) => {
+        const allAttributes = responses.flatMap((res) => res.data)
+        setRequiredAttributes(context, allAttributes)
+      })
     )
     p.push(
-      axiosRequests
-        .$serverGet(
-          `${restApi.uri.deviceTypeCommands}${endpointTypeDeviceTypeRefPair.deviceTypeRef}`
+      Promise.all(
+        endpointTypeDeviceTypeRefPair.deviceTypeRef.map((ref) =>
+          axiosRequests.$serverGet(`${restApi.uri.deviceTypeCommands}${ref}`)
         )
-        .then((res) => {
-          setRequiredCommands(context, res.data)
-        })
+      ).then((responses) => {
+        const allCommands = responses.flatMap((res) => res.data)
+        setRequiredCommands(context, allCommands)
+      })
     )
 
     context.commit(
@@ -747,6 +752,25 @@
 }
 
 /**
+ *
+ * @param {*} context
+ * @param {*} deviceTypeRefs
+ */
+export async function updateDeviceTypeClustersForSelectedEndpoint(
+  context,
+  deviceTypeRefs
+) {
+  let res = await Promise.all(
+    deviceTypeRefs.map((ref) =>
+      axiosRequests.$serverGet(`${restApi.uri.deviceTypeClusters}${ref}`)
+    )
+  ).then((responses) => {
+    return responses.flatMap((response) => response.data)
+  })
+  context.commit('updateDeviceTypeClustersForSelectedEndpoint', res)
+}
+
+/**
  * set client and server cluster lists.
  * @param {*} context
  * @param {*} selectionContext
@@ -886,14 +910,21 @@
   // TODO (?) This does not handle/highlight prohibited clusters. For now we just keep it in here
   let recommendedClients = []
   let recommendedServers = []
+  // Collecting optional client and server clusters
+  let optionalClients = []
+  let optionalServers = []
 
   data.forEach((record) => {
     if (record.includeClient) recommendedClients.push(record.clusterRef)
     if (record.includeServer) recommendedServers.push(record.clusterRef)
+    if (!record.lockClient) optionalClients.push(record.clusterRef)
+    if (!record.lockServer) optionalServers.push(record.clusterRef)
   })
   context.commit(`setRecommendedClusterList`, {
     recommendedClients: recommendedClients,
-    recommendedServers: recommendedServers
+    recommendedServers: recommendedServers,
+    optionalClients: optionalClients,
+    optionalServers: optionalServers
   })
 }
 
diff --git a/src/store/zap/mutations.js b/src/store/zap/mutations.js
index a8fa102..96a53b5 100644
--- a/src/store/zap/mutations.js
+++ b/src/store/zap/mutations.js
@@ -524,6 +524,19 @@
 }
 
 /**
+ * Update the device Type Clusters For Selected Endpoint in endpoint type view state.
+ * @param {*} state
+ * @param {*} deviceTypeClustersForSelectedEndpoint
+ */
+export function updateDeviceTypeClustersForSelectedEndpoint(
+  state,
+  deviceTypeClustersForSelectedEndpoint
+) {
+  state.endpointTypeView.deviceTypeClustersForSelectedEndpoint =
+    deviceTypeClustersForSelectedEndpoint
+}
+
+/**
  * Remove endpoint type details from the endpoint type view of the state.
  * @param {*} state
  * @param {*} endpointType
@@ -644,6 +657,8 @@
 export function setRecommendedClusterList(state, data) {
   vue3Set(state.clustersView, 'recommendedClients', data.recommendedClients)
   vue3Set(state.clustersView, 'recommendedServers', data.recommendedServers)
+  vue3Set(state.clustersView, 'optionalClients', data.optionalClients)
+  vue3Set(state.clustersView, 'optionalServers', data.optionalServers)
 }
 
 /**
@@ -809,7 +824,12 @@
     const openDomainValue =
       state.clusterManager.filterString === ''
         ? filter.domainFilterFn(domainName, state.clusterManager.openDomains, {
-            enabledClusters: filterEnabledClusterPair.enabledClusters
+            enabledClusters: filterEnabledClusterPair.enabledClusters,
+            relevantClusters: filterEnabledClusterPair.relevantClusters,
+            deviceTypeRefsForSelectedEndpoint:
+              filterEnabledClusterPair.deviceTypeRefsForSelectedEndpoint,
+            deviceTypeClustersForSelectedEndpoint:
+              filterEnabledClusterPair.deviceTypeClustersForSelectedEndpoint
           })
         : true
     setOpenDomain(state, {
@@ -1131,6 +1151,15 @@
 }
 
 /**
+ * Set the relevant clusters of the state.
+ * @param {*} state
+ * @param {*} relevantClusters
+ */
+export function setRelevantClusters(state, relevantClusters) {
+  state.relevantClusters = relevantClusters
+}
+
+/**
  * Updates the entire list of device type features.
  * @param {*} state
  * @param {*} data
diff --git a/src/store/zap/state.js b/src/store/zap/state.js
index 85f5811..1c39e04 100644
--- a/src/store/zap/state.js
+++ b/src/store/zap/state.js
@@ -85,10 +85,26 @@
         },
         {
           label: 'Legal Clusters',
-          domainFilterFn: (domain, currentOpenDomains, context) =>
-            context.enabledClusters.map((a) => a.domainName).includes(domain),
-          clusterFilterFn: (cluster, context) =>
-            context.enabledClusters.find((a) => cluster.id == a.id) != undefined
+          domainFilterFn: (domain, currentOpenDomains, context) => {
+            let clusterRefsFromDeviceTypes =
+              context.deviceTypeClustersForSelectedEndpoint.map(
+                (dtc) => dtc.clusterRef
+              )
+            return context.relevantClusters
+              .filter((c) => clusterRefsFromDeviceTypes.includes(c.id))
+              .map((a) => a.domainName)
+              .includes(domain)
+          },
+          clusterFilterFn: (cluster, context) => {
+            let clusterRefsFromDeviceTypes =
+              context.deviceTypeClustersForSelectedEndpoint.map(
+                (dtc) => dtc.clusterRef
+              )
+            return context.relevantClusters
+              .filter((c) => clusterRefsFromDeviceTypes.includes(c.id))
+              .map((c) => c.id)
+              .includes(cluster.id)
+          }
         }
       ],
       actionOptions: [
@@ -115,7 +131,8 @@
       name: {},
       deviceTypeRef: {},
       deviceVersion: {},
-      deviceIdentifier: {}
+      deviceIdentifier: {},
+      deviceTypeClustersForSelectedEndpoint: {}
     },
     clustersView: {
       selected: [],
@@ -123,7 +140,9 @@
       selectedClients: [],
       // These are based off of the selected ZCL Endpoints Device Type
       recommendedClients: [],
-      recommendedServers: []
+      recommendedServers: [],
+      optionalClients: [],
+      optionalServers: []
     },
     attributeView: {
       selectedAttributes: [],
@@ -179,6 +198,7 @@
       deviceIdentifier: null
     },
     notificationCount: 0,
-    enabledClusters: []
+    enabledClusters: [],
+    relevantClusters: []
   }
 }
diff --git a/src/tutorials/CMPTour.vue b/src/tutorials/CMPTour.vue
index 7c55009..62638fd 100644
--- a/src/tutorials/CMPTour.vue
+++ b/src/tutorials/CMPTour.vue
@@ -202,6 +202,10 @@
                   }
                 })
               this.$store.dispatch('zap/updateSelectedEndpoint', res.id)
+              this.$store.dispatch(
+                'zap/updateDeviceTypeClustersForSelectedEndpoint',
+                this.endpointDeviceTypeRef[this.endpointType[res.id]]
+              )
               resolve()
             })
         })
diff --git a/src/tutorials/EndpointTour.vue b/src/tutorials/EndpointTour.vue
index 9df6d46..32b323d 100644
--- a/src/tutorials/EndpointTour.vue
+++ b/src/tutorials/EndpointTour.vue
@@ -170,6 +170,10 @@
                   }
                 })
               this.$store.dispatch('zap/updateSelectedEndpoint', res.id)
+              this.$store.dispatch(
+                'zap/updateDeviceTypeClustersForSelectedEndpoint',
+                this.endpointDeviceTypeRef[this.endpointType[res.id]]
+              )
               resolve()
             })
         })
diff --git a/src/util/common-mixin.js b/src/util/common-mixin.js
index 4568940..22950c6 100644
--- a/src/util/common-mixin.js
+++ b/src/util/common-mixin.js
@@ -40,6 +40,12 @@
         return this.$store.state.zap.endpointTypeView.deviceTypeRef
       }
     },
+    deviceTypeClustersForSelectedEndpoint: {
+      get() {
+        return this.$store.state.zap.endpointTypeView
+          .deviceTypeClustersForSelectedEndpoint
+      }
+    },
     endpointDeviceVersion: {
       get() {
         return this.$store.state.zap.endpointTypeView.deviceVersion
@@ -225,6 +231,10 @@
         deviceTypeRefs: deviceTypeRefs,
         endpointTypeRef: endpointReference
       })
+      this.$store.dispatch(
+        'zap/updateDeviceTypeClustersForSelectedEndpoint',
+        deviceTypeRefs
+      )
     },
     sdkExtClusterCode(extEntry) {
       return extEntry ? extEntry.entityCode : ''
@@ -402,7 +412,7 @@
         return zclProperty.category
       } else {
         zclProperty = this.$store.state.zap.packages.find(
-          (item) => item.pkg.id === packageRef && item.pkg.category
+          (item) => item.pkg.id === packageRef
         )
         return zclProperty.pkg?.category
       }
diff --git a/test/custom-matter-xml.test.js b/test/custom-matter-xml.test.js
index 8bd1805..b0d5bc9 100644
--- a/test/custom-matter-xml.test.js
+++ b/test/custom-matter-xml.test.js
@@ -114,7 +114,7 @@
 
     let result = await zclLoader.loadIndividualFile(
       db,
-      testUtil.testMattterCustomXml,
+      testUtil.testMatterCustomXml,
       sid
     )
     if (!result.succeeded) {
@@ -169,7 +169,7 @@
     // second xml adds 2 attributes and 2 commands to prevoiusly extended cluster
     let result = await zclLoader.loadIndividualFile(
       db,
-      testUtil.testMattterCustomXml2,
+      testUtil.testMatterCustomXml2,
       sid
     )
     if (!result.succeeded) {
@@ -204,7 +204,7 @@
 
     let result = await zclLoader.loadIndividualFile(
       db,
-      testUtil.testMattterCustomXml,
+      testUtil.testMatterCustomXml,
       sid
     )
 
@@ -244,7 +244,7 @@
     /* re-adding the custom xml package should re-enable it */
     result = await zclLoader.loadIndividualFile(
       db,
-      testUtil.testMattterCustomXml,
+      testUtil.testMatterCustomXml,
       sid
     )
     expect(result.succeeded).toBeTruthy()
@@ -430,6 +430,8 @@
     expect(sdkExt).toContain(
       "/ command: 0x0006 / 0xFFF201 => SampleMfgSpecificToggleWithTransition2, test extension: ''"
     )
+    expect(sdkExt).toContain('transitionTime - int16u')
+    expect(sdkExt).toContain('transitionTime - int16u - default_value=0x0003')
     // checking if baseType for command arguments derived from custom xml is accurate
     expect(sdkExt).toContain(
       'Sample Custom Cluster - AddArgumentsResponse\n    returnValue - int8u'
@@ -444,6 +446,10 @@
       '{ (uint16_t)0x0, (uint16_t)0x0, (uint16_t)0xFFFF }, /* Sample Mfg Specific Attribute 2 */ \\'
     )
 
+    let endpointOut = genResult.content['endpoints.out']
+    expect(endpointOut).not.toBeNull()
+    expect(endpointOut).toContain('- SampleMfgSpecificOnWithTransition2: /')
+
     // delete custom xml and generate again
     sessionPartitionInfo =
       await querySession.selectSessionPartitionInfoFromPackageId(
@@ -493,18 +499,18 @@
     expect(state.endpointTypes[0].clusters.length).toBe(8)
 
     // Modify custom xml and reupload
-    const originalData = fs.readFileSync(testUtil.testMattterCustomXml, 'utf8')
+    const originalData = fs.readFileSync(testUtil.testMatterCustomXml, 'utf8')
 
     try {
       const modifiedData = originalData.replace(
         '<name>Sample Custom Cluster</name>',
         '<name>Sample Custom Changed</name>'
       )
-      fs.writeFileSync(testUtil.testMattterCustomXml, modifiedData, 'utf8')
+      fs.writeFileSync(testUtil.testMatterCustomXml, modifiedData, 'utf8')
 
       const result = await zclLoader.loadIndividualFile(
         db,
-        testUtil.testMattterCustomXml,
+        testUtil.testMatterCustomXml,
         sid
       )
       expect(result.succeeded).toBeTruthy()
@@ -541,7 +547,7 @@
       let customXmlPackages = await dbApi.dbAll(
         db,
         'SELECT * FROM PACKAGE WHERE PATH = ?',
-        [testUtil.testMattterCustomXml]
+        [testUtil.testMatterCustomXml]
       )
       expect(customXmlPackages.length).toEqual(2)
       expect(
@@ -549,7 +555,7 @@
       ).toBeTruthy()
     } finally {
       // restore original custom xml
-      fs.writeFileSync(testUtil.testMattterCustomXml, originalData, 'utf8')
+      fs.writeFileSync(testUtil.testMatterCustomXml, originalData, 'utf8')
     }
   },
   testUtil.timeout.long()
@@ -561,7 +567,7 @@
     // adding bad custom xml with type contradiction should throw warning
     let result = await zclLoader.loadIndividualFile(
       db,
-      testUtil.testBadMattterCustomXml,
+      testUtil.testBadMatterCustomXml,
       sid
     )
     expect(result.succeeded).toBeTruthy()
@@ -624,7 +630,7 @@
 
     let result = await zclLoader.loadIndividualFile(
       db,
-      testUtil.testMattterCustomXml,
+      testUtil.testMatterCustomXml,
       conflictSid
     )
     expect(result.succeeded).toBeTruthy()
diff --git a/test/custom-xml-device-type.test.js b/test/custom-xml-device-type.test.js
new file mode 100644
index 0000000..b5a4a94
--- /dev/null
+++ b/test/custom-xml-device-type.test.js
@@ -0,0 +1,286 @@
+/**
+ *
+ *    Copyright (c) 2025 Silicon Labs
+ *
+ *    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.
+ *
+ *
+ * @jest-environment node
+ */
+
+/**
+ * This file tests device types through custom XML files.
+ *
+ * Tests are dependent on each other, please be cautious when changing or adding tests.
+ */
+
+const fs = require('fs')
+const dbApi = require('../src-electron/db/db-api')
+const zclLoader = require('../src-electron/zcl/zcl-loader')
+const env = require('../src-electron/util/env')
+const testUtil = require('./test-util')
+const testQuery = require('./test-query')
+const querySession = require('../src-electron/db/query-session')
+const queryPackage = require('../src-electron/db/query-package')
+const queryPackageNotification = require('../src-electron/db/query-package-notification')
+const querySessionNotification = require('../src-electron/db/query-session-notification')
+const queryDeviceType = require('../src-electron/db/query-device-type')
+const queryConfig = require('../src-electron/db/query-config')
+const queryEndpoint = require('../src-electron/db/query-endpoint')
+const queryZcl = require('../src-electron/db/query-zcl')
+const queryAttribute = require('../src-electron/db/query-attribute')
+const exportJs = require('../src-electron/importexport/export')
+const util = require('../src-electron/util/util')
+const restApi = require('../src-shared/rest-api.js')
+const genEngine = require('../src-electron/generator/generation-engine')
+const importJs = require('../src-electron/importexport/import')
+const {
+  loadIndividualSilabsFile
+} = require('../src-electron/zcl/zcl-loader-silabs.js')
+let db
+let sid
+let mainPackageId
+let customDeviceType
+let templateContext
+
+beforeAll(async () => {
+  env.setDevelopmentEnv()
+  let file = env.sqliteTestFile('custom-xml-device-type')
+  db = await dbApi.initDatabaseAndLoadSchema(
+    file,
+    env.schemaFile(),
+    env.zapVersion()
+  )
+  ctx = await zclLoader.loadZcl(db, env.builtinSilabsZclMetafile())
+  mainPackageId = ctx.packageId
+  let uuid = util.createUuid()
+  sid = await testQuery.createSession(
+    db,
+    'USER',
+    uuid,
+    env.builtinSilabsZclMetafile()
+  )
+  // loading templates
+  templateContext = await genEngine.loadTemplates(
+    db,
+    testUtil.testTemplate.zigbee
+  )
+}, testUtil.timeout.medium())
+
+afterAll(() => dbApi.closeDatabase(db), testUtil.timeout.short())
+
+test('Load custom xml with Device Type', async () => {
+  // load first custom xml (device type being loaded refers to cluster from this file)
+  let result = await zclLoader.loadIndividualFile(
+    db,
+    testUtil.testCustomXml2,
+    sid
+  )
+  expect(result.succeeded).toBe(true)
+
+  // load custom xml with device type
+  result = await zclLoader.loadIndividualFile(
+    db,
+    testUtil.testCustomXmlDeviceType,
+    sid
+  )
+
+  // Check if device type is loaded into the database
+  customDeviceType = await queryDeviceType.selectDeviceTypeByCodeAndName(
+    db,
+    result.packageId,
+    0x0001,
+    'DUT-Client'
+  )
+  expect(customDeviceType).not.toBeNull()
+  expect(customDeviceType.name).toBe('DUT-Client')
+
+  // Check if device type clusters are correctly populated
+  let deviceTypeClusters =
+    await queryDeviceType.selectDeviceTypeClustersByDeviceTypeRef(
+      db,
+      customDeviceType.id
+    )
+  expect(deviceTypeClusters.length).toBe(4)
+
+  // Ensure each deviceTypeCluster has a non-null clusterRef
+  deviceTypeClusters.forEach((cluster) => {
+    expect(cluster.clusterRef).not.toBeNull()
+  })
+
+  let customDeviceTypeCluster = deviceTypeClusters.find(
+    (cluster) => cluster.clusterName === 'Custom Cluster'
+  )
+  expect(customDeviceTypeCluster).not.toBeNull()
+
+  let deviceTypeAttributes =
+    await queryDeviceType.selectDeviceTypeCommandsByDeviceTypeRef(
+      db,
+      customDeviceType.id
+    )
+
+  expect(deviceTypeAttributes.length).toBe(2)
+})
+
+test('Generation with custom xml with Device Type', async () => {
+  let sessionPartitionInfo =
+    await querySession.selectSessionPartitionInfoFromDeviceType(
+      db,
+      sid,
+      customDeviceType.id
+    )
+
+  // Inserting endpoint type with custom xml device type
+  let eptTypeId = await queryConfig.insertEndpointType(
+    db,
+    sessionPartitionInfo[0],
+    'EPT',
+    customDeviceType.id,
+    customDeviceType.code,
+    0,
+    true
+  )
+  expect(eptTypeId).not.toBeNull()
+
+  eptId = await queryEndpoint.insertEndpoint(db, sid, 1, eptTypeId, 0, 0)
+
+  let genResult = await genEngine.generate(
+    db,
+    sid,
+    templateContext.packageId,
+    {},
+    {
+      generateOnly: [
+        'sdk-extension.out',
+        'zap-config.h',
+        'zap-config-version-2.h'
+      ],
+      disableDeprecationWarnings: true
+    }
+  )
+  expect(genResult.hasErrors).toBeFalsy()
+
+  // Check if the generated files contain the expected content
+  let sdkExt = genResult.content['sdk-extension.out']
+  expect(sdkExt).toContain(
+    "// device type: CUSTOM_DUT / 0x0001 => DUT-Client // extension: ''"
+  )
+  expect(sdkExt).toContain(
+    "// device type: CUSTOM_DUT / 0x0002 => DUT-Server // extension: ''"
+  )
+
+  let zapConfig = genResult.content['zap-config.h']
+  expect(zapConfig).toContain(
+    '{ 0x00000000, ZAP_ATTRIBUTE_INDEX(0), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: Basic (client) */ \\'
+  )
+  expect(zapConfig).toContain(
+    '{ 0x00000006, ZAP_ATTRIBUTE_INDEX(0), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: On/off (client) */ \\'
+  )
+  expect(zapConfig).toContain(
+    '{ 0x10E0FCA7, ZAP_ATTRIBUTE_INDEX(0), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: Custom Cluster (client) */ \\'
+  )
+  expect(zapConfig).toContain(
+    '{ 0xABCDFFCD, ZAP_ATTRIBUTE_INDEX(0), 0, 0, ZAP_CLUSTER_MASK(CLIENT), NULL }, /* Endpoint: 1, Cluster: Test Cluster - Device Type (client) */ \\'
+  )
+
+  let zapConfigVer2 = genResult.content['zap-config-version-2.h']
+  expect(zapConfigVer2).toContain(
+    '{ 0x0302, ZCL_INT8U_ATTRIBUTE_TYPE, 1, (ATTRIBUTE_MASK_MANUFACTURER_SPECIFIC| ATTRIBUTE_MASK_CLIENT), { (uint8_t*)0  } }, /* 2 Cluster: Custom Cluster, Attribute: A9, Side: client*/ \\'
+  )
+  expect(zapConfigVer2).toContain(
+    '{ 0x0006, 0x02, COMMAND_MASK_OUTGOING_CLIENT }, /* 2, Cluster: On/off, Command: Toggle*/ \\'
+  )
+  expect(zapConfigVer2).toContain(
+    '{ 0xFFCD, 0x00, COMMAND_MASK_OUTGOING_CLIENT | COMMAND_MASK_MANUFACTURER_SPECIFIC }, /* 15, Cluster: Test Cluster - Device Type, Command: CommandOne*/ \\'
+  )
+})
+
+test('Load same custom xml with different zcl file', async () => {
+  await zclLoader.loadZcl(db, env.builtinMatterZclMetafile())
+  let uuid = util.createUuid()
+  let newSid = await testQuery.createSession(
+    db,
+    'USER',
+    uuid,
+    env.builtinMatterZclMetafile()
+  )
+
+  // load custom xml with device type
+  result = await zclLoader.loadIndividualFile(
+    db,
+    testUtil.testCustomXmlDeviceType,
+    newSid
+  )
+  expect(result.succeeded).toBe(true)
+
+  // Check if new device type cluster is correctly added
+  // There should be a new device type cluster for on/off with clusterRef from the matter zcl file
+  let deviceTypeClusters =
+    await queryDeviceType.selectDeviceTypeClustersByDeviceTypeRef(
+      db,
+      customDeviceType.id
+    )
+  expect(deviceTypeClusters.length).toBe(5)
+
+  // Check if correct errors are thrown for unlinked clusters
+  let sessionNotif = await querySessionNotification.getNotification(db, newSid)
+  expect(
+    sessionNotif.some(
+      (notif) =>
+        notif.type === 'ERROR' &&
+        notif.message.includes(
+          'Cluster "Basic" in device type DUT-Client is not found in the current session'
+        ) &&
+        notif.message.includes('custom-device-type.xml')
+    )
+  ).toBeTruthy()
+})
+
+test(`Load .zap file with custom xml with Device Type`, async () => {
+  let newSid = await querySession.createBlankSession(db)
+
+  // importing a zap file that has an endpoint with custom xml device type
+  let importResult = await importJs.importDataFromFile(
+    db,
+    testUtil.testMatterCustomZap2,
+    {
+      sessionId: newSid
+    }
+  )
+
+  expect(importResult.templateIds.length).toBe(1)
+
+  let genResult = await genEngine.generate(
+    db,
+    newSid,
+    importResult.templateIds[0],
+    {},
+    {
+      generateOnly: ['endpoint-config.c', 'endpoints.out'],
+      disableDeprecationWarnings: true
+    }
+  )
+  expect(genResult.hasErrors).toBeFalsy()
+
+  // Check if the generated files contain the expected content
+  let endpoints = genResult.content['endpoints.out']
+  expect(endpoints).toContain('  >> device: DUT-Server [2]')
+
+  let endpointConfig = genResult.content['endpoint-config.c']
+  expect(endpointConfig).toContain(
+    '{ 0x00000000, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_SIMPLE_DEFAULT(0) }, /* OnOff */  \\'
+  )
+  expect(endpointConfig).toContain(
+    '/* Endpoint: 1, Cluster: Test Cluster - Device Type (server) */ \\'
+  )
+})
diff --git a/test/gen-matter-1.test.js b/test/gen-matter-1.test.js
index 93e6190..590c42c 100644
--- a/test/gen-matter-1.test.js
+++ b/test/gen-matter-1.test.js
@@ -293,6 +293,21 @@
     expect(simpleTest).toContain(
       'zcl command arguments do not exist for AddSceneResponse command.'
     )
+
+    // Testing default values for command arguments, event fields and struct items
+    expect(sdkExt).toContain('ProductID - int16u - default_value=0x01')
+    expect(sdkExt).toContain(
+      'RequestorCanConsent - boolean - default_value=false'
+    )
+    expect(sdkExt).toContain(
+      'Struct name: ChannelInfoStruct, Struct Item Name: MajorNumber, Struct Item Type: int16u, Struct Default Value: 0xFFFF'
+    )
+    expect(sdkExt).not.toContain('SoftwareVersion - int32u - default_value=')
+    let eventOut = genResult.content['events.out']
+    expect(eventOut).toContain(
+      '> Field: SoftwareVersion  default_value=0x00000000'
+    )
+    expect(eventOut).not.toContain('> Field: ProductID  default_value=')
   },
   testUtil.timeout.long()
 )
diff --git a/test/gen-matter-3-1.test.js b/test/gen-matter-3-1.test.js
index 4920f70..90d53e3 100644
--- a/test/gen-matter-3-1.test.js
+++ b/test/gen-matter-3-1.test.js
@@ -29,6 +29,7 @@
 const queryEndpoint = require('../src-electron/db/query-endpoint')
 const queryEndpointType = require('../src-electron/db/query-endpoint-type')
 const queryConfig = require('../src-electron/db/query-config')
+const queryZcl = require('../src-electron/db/query-zcl')
 const queryDeviceType = require('../src-electron/db/query-device-type')
 const util = require('../src-electron/util/util')
 const testQuery = require('./test-query')
@@ -521,6 +522,51 @@
       'SemanticTagStruct item 3 from Identify cluster: Label'
     )
     expect(ept).not.toContain('SemanticTagStruct item 4 from Identify cluster')
+
+    // Testing selectStructByNameAndClusterName for struct names
+    let globalStruct = await queryZcl.selectStructByNameAndClusterName(
+      db,
+      'SemanticTagStruct',
+      'Descriptor',
+      zclPackageId
+    )
+    let clusterStruct = await await queryZcl.selectStructByNameAndClusterName(
+      db,
+      'SemanticTagStruct',
+      'Mode Select',
+      zclPackageId
+    )
+    expect(globalStruct.id).not.toEqual(clusterStruct.id)
+
+    // Testing selectEnumByNameAndClusterName for enum names
+    let globalEnum = await queryZcl.selectEnumByNameAndClusterName(
+      db,
+      'enumTest',
+      'Descriptor',
+      zclPackageId
+    )
+    let clusterEnum = await queryZcl.selectEnumByNameAndClusterName(
+      db,
+      'enumTest',
+      'Mode Select',
+      zclPackageId
+    )
+    expect(globalEnum.id).not.toEqual(clusterEnum.id)
+
+    // Testing selectBitmapByNameAndClusterName for bitmap names
+    let globalBitmap = await queryZcl.selectBitmapByNameAndClusterName(
+      db,
+      'bitmapTest',
+      'Descriptor',
+      zclPackageId
+    )
+    let clusterBitmap = await queryZcl.selectBitmapByNameAndClusterName(
+      db,
+      'bitmapTest',
+      'Mode Select',
+      zclPackageId
+    )
+    expect(globalBitmap.id).not.toEqual(clusterBitmap.id)
   },
   testUtil.timeout.long()
 )
diff --git a/test/gen-template/matter/events.zapt b/test/gen-template/matter/events.zapt
index a6dd685..d1b6053 100644
--- a/test/gen-template/matter/events.zapt
+++ b/test/gen-template/matter/events.zapt
@@ -3,6 +3,6 @@
 {{#zcl_events}}
 >> Event: {{name}}
 {{#zcl_event_fields}}
-    > Field: {{name}} {{#if_is_enum type}}[ENUM]{{/if_is_enum}}{{#if_is_bitmap type}}[BITMAP]{{/if_is_bitmap}}
+    > Field: {{name}} {{#if_is_enum type}}[ENUM]{{/if_is_enum}}{{#if_is_bitmap type}}[BITMAP]{{/if_is_bitmap}} {{#if defaultValue}}default_value={{defaultValue}}{{/if}}
 {{/zcl_event_fields}}
 {{/zcl_events}}
\ No newline at end of file
diff --git a/test/gen-template/matter/sdk-ext.zapt b/test/gen-template/matter/sdk-ext.zapt
index 8f097d6..4a436ac 100644
--- a/test/gen-template/matter/sdk-ext.zapt
+++ b/test/gen-template/matter/sdk-ext.zapt
@@ -23,7 +23,7 @@
 {{#zcl_commands_with_arguments sortBy="signature"}}
 {{clusterName}} - {{commandName}}
 {{#zcl_command_arguments}}
-    {{label}} - {{baseType}}
+    {{label}} - {{baseType}} {{#if defaultValue}}- default_value={{defaultValue}}{{/if}}
 {{/zcl_command_arguments}}
 {{/zcl_commands_with_arguments}}
 
@@ -54,3 +54,9 @@
 
 IMPLEMENTED_COMMANDS2>{{#all_user_clusters}}{{#all_user_cluster_commands_irrespective_of_manufaturing_specification name side}}{{#if_command_extension_true property="implementedCommands"}}{{name}},{{/if_command_extension_true}}{{/all_user_cluster_commands_irrespective_of_manufaturing_specification}}{{/all_user_clusters}}<END2
 
+------------------- Structs -------------------
+{{#zcl_structs}}
+{{#zcl_struct_items}}
+Struct name: {{../name}}, Struct Item Name: {{./name}}, Struct Item Type: {{./type}}, {{#if defaultValue}}Struct Default Value: {{defaultValue}}{{/if}}
+{{/zcl_struct_items}}
+{{/zcl_structs}}
\ No newline at end of file
diff --git a/test/gen-zigbee-7.test.js b/test/gen-zigbee-7.test.js
index 4579b65..94b19a0 100644
--- a/test/gen-zigbee-7.test.js
+++ b/test/gen-zigbee-7.test.js
@@ -148,7 +148,7 @@
         db,
         customDeviceType.id
       )
-    expect(deviceTypeClusters.length).toBe(2) // 2 device type clusters associated with this device type.
+    expect(deviceTypeClusters.length).toBe(4) // 4 device type clusters associated with this device type.
   },
   testUtil.timeout.long()
 )
diff --git a/test/helpers.test.js b/test/helpers.test.js
index 7f0fab1..bf949a1 100644
--- a/test/helpers.test.js
+++ b/test/helpers.test.js
@@ -479,6 +479,28 @@
 )
 
 test(
+  'Generated Macro for 4 byte integer little endian',
+  () => {
+    let options = { hash: { endian: 'little' } }
+    return zclHelper
+      .as_generated_default_macro('1600', 4, options)
+      .then((res) => expect(res).toBe('0x40, 0x06,  0x00, 0x00,'))
+  },
+  testUtil.timeout.short()
+)
+
+test(
+  'Generated Macro for 4 byte integer big endian',
+  () => {
+    let options = { hash: { endian: 'big' } }
+    return zclHelper
+      .as_generated_default_macro('1600', 4, options)
+      .then((res) => expect(res).toBe('0x00, 0x00,  0x06, 0x40,'))
+  },
+  testUtil.timeout.short()
+)
+
+test(
   'Generated Macro for string',
   () => {
     let options = { hash: { endian: 'big' } }
diff --git a/test/resource/custom-cluster/custom-device-type.xml b/test/resource/custom-cluster/custom-device-type.xml
index 869574e..cd1271f 100644
--- a/test/resource/custom-cluster/custom-device-type.xml
+++ b/test/resource/custom-cluster/custom-device-type.xml
@@ -8,8 +8,19 @@
     <profileId editable="false">0xC001</profileId>
     <deviceId editable="false">0x0001</deviceId>
     <clusters lockOthers="true">
-      <include client="true" server="false"  clientLocked="true"  serverLocked="true" >Test Cluster</include>
+      <!-- Cluster from same file  -->
+      <include cluster="Test Cluster - Device Type" client="true" server="false"  clientLocked="true"  serverLocked="true" >
+        <requireCommand>CommandOne</requireCommand>
+      </include>
+
+      <!-- Cluster from primary zcl file -->
       <include cluster="Basic" client="true" server="false" clientLocked="true" serverLocked="true"></include>
+      <include cluster="On/Off" client="true" server="false" clientLocked="true" serverLocked="true"></include>
+
+      <!-- Cluster from other custom xml -->
+      <include cluster="Custom Cluster" client="true" server="false" clientLocked="true" serverLocked="true">
+        <requireCommand>C1</requireCommand>
+      </include>
 	</clusters>
   </deviceType>
   <deviceType>
@@ -20,8 +31,38 @@
     <profileId editable="false">0xC001</profileId>
     <deviceId editable="false">0x0002</deviceId>
     <clusters lockOthers="true">
-      <include client="false" server="true"  clientLocked="true"  serverLocked="true" >Test Cluster</include>
+      <!-- Cluster from same file  -->
+      <include cluster="Test Cluster - Device Type" client="false" server="true"  clientLocked="true"  serverLocked="true" >
+        <requireAttribute>sample attribute</requireAttribute>
+      </include>
+
+      <!-- Cluster from primary zcl file -->
       <include cluster="Basic" client="false" server="true" clientLocked="true" serverLocked="true"></include>
+      <include cluster="On/Off" client="false" server="true" clientLocked="true" serverLocked="true"></include>
+
+      <!-- Cluster from other custom xml -->
+      <include cluster="Custom Cluster" client="false" server="true" clientLocked="true" serverLocked="true"></include>
 	</clusters>
-  </deviceType>  
+  </deviceType>
+
+  <cluster manufacturerCode="0xABCD">
+    <name>Test Cluster - Device Type</name>
+    <domain>Ember</domain>
+    <description> This cluster is used to test device types through custom xml file
+    </description>
+    <!-- Cluster Id must be within the mfg spec range 0xfc00 - 0xffff -->
+    <code>0xFFCD</code>
+    <define>TEST_CLUSTER_DEVICE_TYPE</define>
+    <client init="false" tick="false">true</client>
+    <server init="false" tick="false">true</server>
+    <attribute side="server" code="0x0000" define="ATTRIBUTE_ONE" type="INT8U" min="0x00" max="0xFF" writable="true" default="0x00" optional="true">sample attribute</attribute>
+    <attribute side="server" code="0x0001" define="ATTRIBUTE_TWO" type="INT8U" min="0x00" max="0xFF" writable="true" default="0x00" optional="true">sample attribute 2</attribute>
+    <command source="client" code="0x00" name="CommandOne" optional="true">
+      <description>
+        A sample manufacturer specific command within the sample cluster.
+      </description>
+      <arg name="argOne" type="INT8U"/>
+    </command>
+  </cluster>
+
 </configurator>
diff --git a/test/resource/custom-cluster/custom-dut.xml b/test/resource/custom-cluster/custom-dut.xml
index f11c568..e9821b7 100644
--- a/test/resource/custom-cluster/custom-dut.xml
+++ b/test/resource/custom-cluster/custom-dut.xml
@@ -129,6 +129,10 @@
       type="INT16U" min="0" writable="false"
       default="0" optional="true">A8</attribute>
 
+    <attribute manufacturerCode="0x10e0" side="client" code="0x0302" define="A9"
+      type="INT8U" min="0" max="0xFF" writable="false"
+      default="0" optional="false">A9</attribute>
+
     <!-- COMMANDS -->
     <!-- Client Commands -->
     <command source="client" code="0x00"
diff --git a/test/resource/custom-cluster/matter-custom.xml b/test/resource/custom-cluster/matter-custom.xml
index beda6e9..67c1468 100644
--- a/test/resource/custom-cluster/matter-custom.xml
+++ b/test/resource/custom-cluster/matter-custom.xml
@@ -15,7 +15,7 @@
 limitations under the License.
 -->
 <configurator>
-<domain name="CHIP"/>   
+<domain name="CHIP"/>
 <cluster>
     <domain>General</domain>
     <name>Sample Custom Cluster</name>
@@ -24,9 +24,9 @@
     <description>The Sample MEI cluster showcases cluster manufacturer extensions</description>
         <!-- Attributes -->
         <!-- A simple boolean attribute that flips or flops -->
-        <attribute side="server" code="0x0000" define="FLIP_FLOP" type="BOOLEAN" writable="true" default="false" optional="false">FlipFlop</attribute>
+        <attribute side="server" code="0x0000" define="FLIP_FLOP" type="BOOLEAN" writable="true" default="false">FlipFlop</attribute>
         <!-- Command Responses -->
-        <command source="server" code="0x01" name="AddArgumentsResponse" optional="false" disableDefaultResponse="true">
+        <command source="server" code="0x01" name="AddArgumentsResponse"  disableDefaultResponse="true">
         <description>
             Response for AddArguments that returns the sum.
         </description>
@@ -34,7 +34,7 @@
         </command>
 
         <!-- Commands -->
-        <command source="client" code="0x02" name="AddArguments" response="AddArgumentsResponse" optional="false">
+        <command source="client" code="0x02" name="AddArguments" response="AddArgumentsResponse">
         <description>
             Command that takes two uint8 arguments and returns their sum.
         </description>
@@ -42,7 +42,7 @@
         <arg name="arg2" type="INT8U"/>
         </command>
 
-        <command source="client" code="0x00" name="Ping" optional="false">
+        <command source="client" code="0x00" name="Ping">
         <description>
             Simple command without any parameters and without a response.
         </description>
@@ -54,9 +54,11 @@
 <clusterExtension code="0x0006">
     <attribute side="server" code="0xFFF10000" define="SAMPLE_MFG_SPECIFIC_TRANSITION_TIME_2" type="INT8U" min="0x0000" max="0xFFFF" writable="true" default="0x0000" optional="true">Sample Mfg Specific Attribute 2</attribute>
     <attribute side="server" code="0xFFF10001" define="SAMPLE_MFG_SPECIFIC_TRANSITION_TIME_4" type="INT16U" min="0x0000" max="0xFFFF" writable="true" default="0x0000" optional="true">Sample Mfg Specific Attribute 4</attribute>
-    <command source="client" code="0xFFF100" name="SampleMfgSpecificOnWithTransition2" optional="true">
+    <command source="client" code="0xFFF100" name="SampleMfgSpecificOnWithTransition2">
         <description>Client command that turns the device on with a transition given
         by the transition time in the Ember Sample transition time attribute.</description>
+        <arg name="transitionMode"  type="INT8U"/>
+        <arg name="transitionTime"  type="INT16U" default="0x0003"/>
     </command>
     <command source="client" code="0xFFF101" name="SampleMfgSpecificToggleWithTransition2" optional="true">
         <description>Client command that toggles the device with a transition given
diff --git a/test/resource/custom-cluster/matterCustomDeviceType.zap b/test/resource/custom-cluster/matterCustomDeviceType.zap
new file mode 100644
index 0000000..138bf54
--- /dev/null
+++ b/test/resource/custom-cluster/matterCustomDeviceType.zap
@@ -0,0 +1,2691 @@
+{
+  "fileFormat": 2,
+  "featureLevel": 106,
+  "creator": "zap",
+  "keyValuePairs": [
+    {
+      "key": "commandDiscovery",
+      "value": "1"
+    },
+    {
+      "key": "defaultResponsePolicy",
+      "value": "always"
+    },
+    {
+      "key": "manufacturerCodes",
+      "value": "0x1002"
+    }
+  ],
+  "package": [
+    {
+      "pathRelativity": "relativeToZap",
+      "path": "../../../zcl-builtin/matter/zcl.json",
+      "type": "zcl-properties",
+      "category": "matter",
+      "version": 1,
+      "description": "Matter SDK ZCL data"
+    },
+    {
+      "pathRelativity": "relativeToZap",
+      "path": "../../gen-template/matter/gen-test.json",
+      "type": "gen-templates-json",
+      "category": "matter",
+      "version": "test-matter"
+    },
+    {
+      "pathRelativity": "relativeToZap",
+      "path": "custom-device-type.xml",
+      "type": "zcl-xml-standalone"
+    }
+  ],
+  "endpointTypes": [
+    {
+      "id": 1,
+      "name": "MA-rootdevice",
+      "deviceTypeRef": {
+        "code": 22,
+        "profileId": 259,
+        "label": "MA-rootdevice",
+        "name": "MA-rootdevice",
+        "deviceTypeOrder": 0
+      },
+      "deviceTypes": [
+        {
+          "code": 22,
+          "profileId": 259,
+          "label": "MA-rootdevice",
+          "name": "MA-rootdevice",
+          "deviceTypeOrder": 0
+        }
+      ],
+      "deviceVersions": [
+        1
+      ],
+      "deviceIdentifiers": [
+        22
+      ],
+      "deviceTypeName": "MA-rootdevice",
+      "deviceTypeCode": 22,
+      "deviceTypeProfileId": 259,
+      "clusters": [
+        {
+          "name": "Descriptor",
+          "code": 29,
+          "mfgCode": null,
+          "define": "DESCRIPTOR_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "DeviceTypeList",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ServerList",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClientList",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "PartsList",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Access Control",
+          "code": 31,
+          "mfgCode": null,
+          "define": "ACCESS_CONTROL_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "ACL",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Extension",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SubjectsPerAccessControlEntry",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "TargetsPerAccessControlEntry",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AccessControlEntriesPerFabric",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Basic Information",
+          "code": 40,
+          "mfgCode": null,
+          "define": "BASIC_INFORMATION_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "DataModelRevision",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "VendorName",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "VendorID",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "vendor_id",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ProductName",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ProductID",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "NodeLabel",
+              "code": 5,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Location",
+              "code": 6,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "HardwareVersion",
+              "code": 7,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "HardwareVersionString",
+              "code": 8,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SoftwareVersion",
+              "code": 9,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int32u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SoftwareVersionString",
+              "code": 10,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "CapabilityMinima",
+              "code": 19,
+              "mfgCode": null,
+              "side": "server",
+              "type": "CapabilityMinimaStruct",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 1,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Localization Configuration",
+          "code": 43,
+          "mfgCode": null,
+          "define": "LOCALIZATION_CONFIGURATION_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "ActiveLocale",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SupportedLocales",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Time Format Localization",
+          "code": 44,
+          "mfgCode": null,
+          "define": "TIME_FORMAT_LOCALIZATION_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "HourFormat",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "HourFormat",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 0,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Unit Localization",
+          "code": 45,
+          "mfgCode": null,
+          "define": "UNIT_LOCALIZATION_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "General Commissioning",
+          "code": 48,
+          "mfgCode": null,
+          "define": "GENERAL_COMMISSIONING_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "commands": [
+            {
+              "name": "ArmFailSafe",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "ArmFailSafeResponse",
+              "code": 1,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "SetRegulatoryConfig",
+              "code": 2,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "SetRegulatoryConfigResponse",
+              "code": 3,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "CommissioningComplete",
+              "code": 4,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "CommissioningCompleteResponse",
+              "code": 5,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            }
+          ],
+          "attributes": [
+            {
+              "name": "Breadcrumb",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int64u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0x0000000000000000",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "BasicCommissioningInfo",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "BasicCommissioningInfo",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "RegulatoryConfig",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "RegulatoryLocationType",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "LocationCapability",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "RegulatoryLocationType",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SupportsConcurrentConnection",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "boolean",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Network Commissioning",
+          "code": 49,
+          "mfgCode": null,
+          "define": "NETWORK_COMMISSIONING_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "MaxNetworks",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Networks",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "InterfaceEnabled",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "boolean",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "LastNetworkingStatus",
+              "code": 5,
+              "mfgCode": null,
+              "side": "server",
+              "type": "NetworkCommissioningStatus",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "LastNetworkID",
+              "code": 6,
+              "mfgCode": null,
+              "side": "server",
+              "type": "octet_string",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "LastConnectErrorValue",
+              "code": 7,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int32s",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "General Diagnostics",
+          "code": 51,
+          "mfgCode": null,
+          "define": "GENERAL_DIAGNOSTICS_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "commands": [
+            {
+              "name": "TestEventTrigger",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            }
+          ],
+          "attributes": [
+            {
+              "name": "NetworkInterfaces",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "RebootCount",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "TestEventTriggersEnabled",
+              "code": 8,
+              "mfgCode": null,
+              "side": "server",
+              "type": "boolean",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Administrator Commissioning",
+          "code": 60,
+          "mfgCode": null,
+          "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "commands": [
+            {
+              "name": "OpenCommissioningWindow",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "RevokeCommissioning",
+              "code": 2,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            }
+          ],
+          "attributes": [
+            {
+              "name": "WindowStatus",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "CommissioningWindowStatusEnum",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AdminFabricIndex",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "fabric_idx",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AdminVendorId",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Operational Credentials",
+          "code": 62,
+          "mfgCode": null,
+          "define": "OPERATIONAL_CREDENTIALS_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "commands": [
+            {
+              "name": "AttestationRequest",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "AttestationResponse",
+              "code": 1,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "CertificateChainRequest",
+              "code": 2,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "CertificateChainResponse",
+              "code": 3,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "CSRRequest",
+              "code": 4,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "CSRResponse",
+              "code": 5,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "AddNOC",
+              "code": 6,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "UpdateNOC",
+              "code": 7,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "NOCResponse",
+              "code": 8,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "UpdateFabricLabel",
+              "code": 9,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "RemoveFabric",
+              "code": 10,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "AddTrustedRootCertificate",
+              "code": 11,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            }
+          ],
+          "attributes": [
+            {
+              "name": "NOCs",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Fabrics",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "SupportedFabrics",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "CommissionedFabrics",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "TrustedRootCertificates",
+              "code": 4,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "CurrentFabricIndex",
+              "code": 5,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Group Key Management",
+          "code": 63,
+          "mfgCode": null,
+          "define": "GROUP_KEY_MANAGEMENT_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "commands": [
+            {
+              "name": "KeySetWrite",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "KeySetRead",
+              "code": 1,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "KeySetReadResponse",
+              "code": 2,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            },
+            {
+              "name": "KeySetRemove",
+              "code": 3,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "KeySetReadAllIndices",
+              "code": 4,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "KeySetReadAllIndicesResponse",
+              "code": 5,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
+            }
+          ],
+          "attributes": [
+            {
+              "name": "GroupKeyMap",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GroupTable",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "MaxGroupsPerFabric",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "MaxGroupKeysPerFabric",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "id": 2,
+      "name": "Anonymous Endpoint Type",
+      "deviceTypeRef": {
+        "code": 2,
+        "profileId": 49153,
+        "label": "DUT-Server",
+        "name": "DUT-Server",
+        "deviceTypeOrder": 0
+      },
+      "deviceTypes": [
+        {
+          "code": 2,
+          "profileId": 49153,
+          "label": "DUT-Server",
+          "name": "DUT-Server",
+          "deviceTypeOrder": 0
+        }
+      ],
+      "deviceVersions": [
+        1
+      ],
+      "deviceIdentifiers": [
+        2
+      ],
+      "deviceTypeName": "DUT-Server",
+      "deviceTypeCode": 2,
+      "deviceTypeProfileId": 49153,
+      "clusters": [
+        {
+          "name": "On/Off",
+          "code": 6,
+          "mfgCode": null,
+          "define": "ON_OFF_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "commands": [
+            {
+              "name": "Off",
+              "code": 0,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "On",
+              "code": 1,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "Toggle",
+              "code": 2,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            }
+          ],
+          "attributes": [
+            {
+              "name": "OnOff",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "boolean",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "4",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
+          "name": "Test Cluster - Device Type",
+          "code": 65485,
+          "mfgCode": 43981,
+          "define": "TEST_CLUSTER_DEVICE_TYPE",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "endpoints": [
+    {
+      "endpointTypeName": "MA-rootdevice",
+      "endpointTypeIndex": 0,
+      "profileId": 259,
+      "endpointId": 0,
+      "networkId": null,
+      "parentEndpointIdentifier": null
+    },
+    {
+      "endpointTypeName": "Anonymous Endpoint Type",
+      "endpointTypeIndex": 1,
+      "profileId": 49153,
+      "endpointId": 1,
+      "networkId": 0,
+      "parentEndpointIdentifier": null
+    }
+  ]
+}
\ No newline at end of file
diff --git a/test/test-util.js b/test/test-util.js
index d562b64..bb256ca 100644
--- a/test/test-util.js
+++ b/test/test-util.js
@@ -159,11 +159,10 @@
   './test/resource/custom-cluster/custom-bead-cluster.xml'
 exports.badTestCustomXml = './test/resource/custom-cluster/bad-test-custom.xml'
 
-exports.testMattterCustomXml =
-  './test/resource/custom-cluster/matter-custom.xml'
-exports.testMattterCustomXml2 =
+exports.testMatterCustomXml = './test/resource/custom-cluster/matter-custom.xml'
+exports.testMatterCustomXml2 =
   './test/resource/custom-cluster/matter-custom2.xml'
-exports.testBadMattterCustomXml =
+exports.testBadMatterCustomXml =
   './test/resource/custom-cluster/matter-bad-custom.xml'
 exports.testMatterConflict =
   './test/resource/custom-cluster/matter-conflict.xml'
@@ -171,6 +170,8 @@
   './test/resource/custom-cluster/matterMissingCustomXml.zap'
 exports.testMatterCustomZap =
   './test/resource/custom-cluster/matterCustomXml.zap'
+exports.testMatterCustomZap2 =
+  './test/resource/custom-cluster/matterCustomDeviceType.zap'
 
 exports.totalClusterCount = 111
 exports.totalDomainCount = 20
diff --git a/zcl-builtin/matter/data-model/chip/channel-cluster.xml b/zcl-builtin/matter/data-model/chip/channel-cluster.xml
index 47ac01d..5969ec4 100644
--- a/zcl-builtin/matter/data-model/chip/channel-cluster.xml
+++ b/zcl-builtin/matter/data-model/chip/channel-cluster.xml
@@ -54,7 +54,7 @@
 
   <struct name="ChannelInfoStruct">
     <cluster code="0x0504"/>
-    <item name="MajorNumber"       type="INT16U"/>
+    <item name="MajorNumber"       type="INT16U" default="0xFFFF"/>
     <item name="MinorNumber"       type="INT16U"/>
     <item name="Name"              type="CHAR_STRING" optional="true"/>
     <item name="CallSign"          type="CHAR_STRING" optional="true"/>
diff --git a/zcl-builtin/matter/data-model/chip/chip-ota.xml b/zcl-builtin/matter/data-model/chip/chip-ota.xml
index f14d6df..5fb7197 100644
--- a/zcl-builtin/matter/data-model/chip/chip-ota.xml
+++ b/zcl-builtin/matter/data-model/chip/chip-ota.xml
@@ -47,7 +47,7 @@
         <command source="client" code="0x00" name="QueryImage" response="QueryImageResponse" optional="false" cli="chip ota queryimage">
             <description>Determine availability of a new Software Image</description>
             <arg name="VendorID" type="vendor_id"/>
-            <arg name="ProductID" type="INT16U"/>
+            <arg name="ProductID" type="INT16U" default="0x01"/>
             <arg name="SoftwareVersion" type="INT32U"/>
             <arg name="ProtocolsSupported" type="OTADownloadProtocol" array="true"/>
             <arg name="HardwareVersion" type="INT16U" optional="true"/>
@@ -95,10 +95,10 @@
         <item name="Querying" value="0x2"/>
         <item name="DelayedOnQuery" value="0x3"/>
         <item name="Downloading" value="0x4"/>
-        <item name="Applying" value="0x5"/>       
+        <item name="Applying" value="0x5"/>
         <item name="DelayedOnApply" value="0x6"/>
         <item name="RollingBack" value="0x7"/>
-        <item name="DelayedOnUserConsent" value="0x8"/>            
+        <item name="DelayedOnUserConsent" value="0x8"/>
     </enum>
     <enum name="OTAChangeReasonEnum" type="ENUM8">
         <cluster code="0x002a"/>
@@ -139,18 +139,18 @@
           <field id="1" name="NewState" type="OTAUpdateStateEnum"/>
           <field id="2" name="Reason" type="OTAChangeReasonEnum"/>
           <field id="3" name="TargetSoftwareVersion" type="INT32U" isNullable="true"/>
-        </event> 
+        </event>
         <event side="server" code="0x01" name="VersionApplied" priority="critical" optional="false">
           <description>This event SHALL be generated whenever a new version starts executing after being applied due to a software update.</description>
-          <field id="0" name="SoftwareVersion" type="INT32U"/> 
+          <field id="0" name="SoftwareVersion" type="INT32U" default="0x00000000"/>
           <field id="1" name="ProductID" type="INT16U"/>
         </event>
         <event side="server" code="0x02" name="DownloadError" priority="info" optional="false">
           <description>This event SHALL be generated whenever an error occurs during OTA Requestor download operation.</description>
-          <field id="0" name="SoftwareVersion" type="INT32U"/> 
+          <field id="0" name="SoftwareVersion" type="INT32U"/>
           <field id="1" name="BytesDownloaded" type="INT64U"/>
           <field id="2" name="ProgressPercent" type="INT8U" min="0" max="100" isNullable="true"/>
           <field id="3" name="PlatformCode" type="INT64S" isNullable="true"/>
-        </event>                     
+        </event>
     </cluster>
 </configurator>
diff --git a/zcl-builtin/matter/data-model/chip/descriptor-cluster.xml b/zcl-builtin/matter/data-model/chip/descriptor-cluster.xml
index e91beba..ef8d357 100644
--- a/zcl-builtin/matter/data-model/chip/descriptor-cluster.xml
+++ b/zcl-builtin/matter/data-model/chip/descriptor-cluster.xml
@@ -30,6 +30,16 @@
     <item name="Revision" type="INT16U"/>
   </struct>
 
+  <enum name="enumTest" type="ENUM8">
+    <item name="enumTest1" value="0x0"/>
+    <item name="enumTest2" value="0x1"/>
+  </enum>
+
+  <bitmap name="bitmapTest" type="BITMAP8">
+    <field name="bitmapFieldTest1" mask="0x1"/>
+    <field name="bitmapFieldTest2" mask="0x2"/>
+  </bitmap>
+
   <cluster>
     <domain>General</domain>
     <name>Descriptor</name>
diff --git a/zcl-builtin/matter/data-model/chip/mode-select-cluster.xml b/zcl-builtin/matter/data-model/chip/mode-select-cluster.xml
index b4ff95c..cc4fc5d 100644
--- a/zcl-builtin/matter/data-model/chip/mode-select-cluster.xml
+++ b/zcl-builtin/matter/data-model/chip/mode-select-cluster.xml
@@ -30,6 +30,16 @@
     <item name="SemanticTags" type="SemanticTagStruct" array="true" optional="false"/>
   </struct>
 
+  <enum name="enumTest" type="ENUM8">
+    <cluster code="0x0050"/>
+    <item name="enumTest1" value="0x0"/>
+  </enum>
+
+  <bitmap name="bitmapTest" type="BITMAP8">
+    <cluster code="0x0050"/>
+    <field name="bitmapFieldTest1" mask="0x1"/>
+  </bitmap>
+
   <cluster>
     <domain>General</domain>
     <name>Mode Select</name>