diff --git a/apack.json b/apack.json
index 30505b1279..85195410e1 100644
--- a/apack.json
+++ b/apack.json
@@ -4,7 +4,7 @@
"description": "Graphical configuration tool for application and libraries based on Zigbee Cluster Library.",
"path": [".", "node_modules/.bin/", "ZAP.app/Contents/MacOS"],
"requiredFeatureLevel": "apack.core:9",
- "featureLevel": 105,
+ "featureLevel": 106,
"uc.triggerExtension": "zap",
"executable": {
"zap:win32.x86_64": {
diff --git a/docs/api.md b/docs/api.md
index 364030a459..8d29c318e5 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -8448,6 +8448,7 @@ This module contains the API for templating. For more detailed instructions, rea
* [Templating API: Attribute helpers](#module_Templating API_ Attribute helpers)
* [~featureBits(options)](#module_Templating API_ Attribute helpers..featureBits) ⇒
* [~attributeDefault()](#module_Templating API_ Attribute helpers..attributeDefault) ⇒
+ * [~as_underlying_atomic_identifier_for_attribute_id(attributeId)](#module_Templating API_ Attribute helpers..as_underlying_atomic_identifier_for_attribute_id)
@@ -8468,6 +8469,18 @@ Valid within a cluster context, requires code.
**Kind**: inner method of [Templating API: Attribute helpers
](#module_Templating API_ Attribute helpers)
**Returns**: Produces attribute defaults.
+
+
+### Templating API: Attribute helpers~as\_underlying\_atomic\_identifier\_for\_attribute\_id(attributeId)
+Given an attribute Id determine its corresponding atomic identifier from the
+atomic table.
+
+**Kind**: inner method of [Templating API: Attribute helpers
](#module_Templating API_ Attribute helpers)
+
+| Param | Type |
+| --- | --- |
+| attributeId | \*
|
+
## Templating API: C formatting helpers
diff --git a/docs/helpers.md b/docs/helpers.md
index 8b0eec8b8e..c86404f8f9 100644
--- a/docs/helpers.md
+++ b/docs/helpers.md
@@ -127,6 +127,7 @@ This module contains the API for templating. For more detailed instructions, rea
* [Templating API: Attribute helpers](#module_Templating API_ Attribute helpers)
* [~featureBits(options)](#module_Templating API_ Attribute helpers..featureBits) ⇒
* [~attributeDefault()](#module_Templating API_ Attribute helpers..attributeDefault) ⇒
+ * [~as_underlying_atomic_identifier_for_attribute_id(attributeId)](#module_Templating API_ Attribute helpers..as_underlying_atomic_identifier_for_attribute_id)
@@ -147,6 +148,18 @@ Valid within a cluster context, requires code.
**Kind**: inner method of [Templating API: Attribute helpers
](#module_Templating API_ Attribute helpers)
**Returns**: Produces attribute defaults.
+
+
+### Templating API: Attribute helpers~as\_underlying\_atomic\_identifier\_for\_attribute\_id(attributeId)
+Given an attribute Id determine its corresponding atomic identifier from the
+atomic table.
+
+**Kind**: inner method of [Templating API: Attribute helpers
](#module_Templating API_ Attribute helpers)
+
+| Param | Type |
+| --- | --- |
+| attributeId | \*
|
+
## Templating API: C formatting helpers
diff --git a/src-electron/generator/helper-attribute.js b/src-electron/generator/helper-attribute.js
index 870f730975..8bd716274c 100644
--- a/src-electron/generator/helper-attribute.js
+++ b/src-electron/generator/helper-attribute.js
@@ -22,7 +22,10 @@
*/
const queryAttribute = require('../db/query-attribute')
+const queryZcl = require('../db/query-zcl')
const templateUtil = require('./template-util')
+const zclUtil = require('../util/zcl-util')
+const dbEnum = require('../../src-shared/db-enum')
/**
* Get feature bits from the given context.
@@ -76,6 +79,89 @@ async function attributeDefault(options) {
return templateUtil.templatePromise(this.global, p)
}
+/**
+ * Given an attribute Id determine its corresponding atomic identifier from the
+ * atomic table.
+ * @param {*} attributeId
+ */
+async function as_underlying_atomic_identifier_for_attribute_id(attributeId) {
+ let attributeDetails =
+ await queryZcl.selectAttributeByAttributeIdAndClusterRef(
+ this.global.db,
+ attributeId,
+ null
+ )
+ let atomicInfo = attributeDetails
+ ? await queryZcl.selectAtomicType(
+ this.global.db,
+ [attributeDetails.packageRef],
+ attributeDetails.type
+ )
+ : null
+ // If attribute type directly points to the atomic type then return that
+ if (atomicInfo) {
+ // All types in the number and string table should be found here.
+ return atomicInfo.atomicId
+ } else {
+ // If attribute type does not point to atomic type
+ let dataType = await queryZcl.selectDataTypeByNameAndClusterId(
+ this.global.db,
+ attributeDetails.type,
+ attributeDetails.clusterRef,
+ [attributeDetails.packageRef]
+ )
+ if (dataType.discriminatorName.toLowerCase() == dbEnum.zclType.enum) {
+ let enumInfo = await queryZcl.selectEnumByNameAndClusterId(
+ this.global.db,
+ attributeDetails.type,
+ attributeDetails.clusterRef,
+ [attributeDetails.packageRef]
+ )
+ atomicInfo = await queryZcl.selectAtomicType(
+ this.global.db,
+ [attributeDetails.packageRef],
+ dbEnum.zclType.enum + enumInfo.size * 8
+ )
+ return atomicInfo ? atomicInfo.atomicId : null
+ } else if (
+ dataType.discriminatorName.toLowerCase() == dbEnum.zclType.bitmap
+ ) {
+ let bitmapInfo = await queryZcl.selectBitmapByNameAndClusterId(
+ this.global.db,
+ attributeDetails.type,
+ attributeDetails.clusterRef,
+ [attributeDetails.packageRef]
+ )
+ atomicInfo = await queryZcl.selectAtomicType(
+ this.global.db,
+ [attributeDetails.packageRef],
+ dbEnum.zclType.bitmap + bitmapInfo.size * 8
+ )
+ return atomicInfo ? atomicInfo.atomicId : null
+ } else if (
+ dataType.discriminatorName.toLowerCase() == dbEnum.zclType.struct
+ ) {
+ atomicInfo = await queryZcl.selectAtomicType(
+ this.global.db,
+ [attributeDetails.packageRef],
+ dbEnum.zclType.struct
+ )
+ return atomicInfo ? atomicInfo.atomicId : null
+ } else if (
+ dataType.discriminatorName.toLowerCase() == dbEnum.zclType.array
+ ) {
+ atomicInfo = await queryZcl.selectAtomicType(
+ this.global.db,
+ [attributeDetails.packageRef],
+ dbEnum.zclType.array
+ )
+ return atomicInfo ? atomicInfo.atomicId : null
+ } else {
+ return null
+ }
+ }
+}
+
// WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
//
// Note: these exports are public API. Templates that might have been created in the past and are
@@ -84,3 +170,5 @@ async function attributeDefault(options) {
exports.global_attribute_default = attributeDefault
exports.feature_bits = featureBits
+exports.as_underlying_atomic_identifier_for_attribute_id =
+ as_underlying_atomic_identifier_for_attribute_id
diff --git a/test/gen-template/zigbee/zap-config-version-3.zapt b/test/gen-template/zigbee/zap-config-version-3.zapt
index 51b1a0cfef..27e60f1131 100644
--- a/test/gen-template/zigbee/zap-config-version-3.zapt
+++ b/test/gen-template/zigbee/zap-config-version-3.zapt
@@ -298,7 +298,7 @@
#define GENERATED_MULTI_PROTOCOL_ATTRIBUTE_MAPPING
{
{{#all_multi_protocol_attributes}}
- { {{clusterCode1}}, {{clusterMfgCode1}}, {{clusterCode2}}, {{clusterMfgCode2}}, {{attributeCode1}}, {{attributeMfgCode1}}, {{attributeCode2}}, {{attributeMfgCode2}} },
+ { {{clusterCode1}}, {{clusterMfgCode1}}, {{clusterCode2}}, {{clusterMfgCode2}}, {{attributeCode1}}, {{attributeMfgCode1}}, {{as_underlying_atomic_identifier_for_attribute_id attributeRef1}}, {{attributeCode2}}, {{attributeMfgCode2}}, {{as_underlying_atomic_identifier_for_attribute_id attributeRef2}} },
{{/all_multi_protocol_attributes}}
}
{{/if_multi_protocol_attributes_enabled}}
diff --git a/test/multi-protocol.test.js b/test/multi-protocol.test.js
index 80e6ab0696..a5c7969c41 100644
--- a/test/multi-protocol.test.js
+++ b/test/multi-protocol.test.js
@@ -159,9 +159,18 @@ test(
expect(zigbeeEndpointConfigGen).toContain(
'#define GENERATED_MULTI_PROTOCOL_ATTRIBUTE_MAPPING'
)
- expect(zigbeeEndpointConfigGen).toContain('{ 6, 0, 6, 0, 0, 0, 0, 0 },')
- expect(zigbeeEndpointConfigGen).toContain('{ 8, 0, 8, 0, 0, 0, 0, 0 },')
- expect(zigbeeEndpointConfigGen).toContain('{ 8, 0, 8, 0, 1, 0, 1, 0 },')
+ expect(zigbeeEndpointConfigGen).toContain(
+ '{ 6, 0, 6, 0, 0, 0, 16, 0, 0, 16 },'
+ )
+ expect(zigbeeEndpointConfigGen).toContain(
+ '{ 8, 0, 8, 0, 0, 0, 32, 0, 0, 32 },'
+ )
+ expect(zigbeeEndpointConfigGen).toContain(
+ '{ 8, 0, 8, 0, 1, 0, 33, 1, 0, 33 },'
+ )
+ expect(zigbeeEndpointConfigGen).toContain(
+ '{ 6, 0, 6, 0, 16387, 0, 48, 16387, 0, 48 },'
+ )
// Notifications test when opening multi-protocol zap file
let sessionNotifications = await querySessionNotice.getNotification(
@@ -220,7 +229,7 @@ test(
let importRes = await importJs.importDataFromFile(
db,
multiProtocolTestFile,
- { sessionId: null },
+ { sessionId: null }
)
// Get all session attributes
@@ -242,14 +251,14 @@ test(
// Check both of them are the same
expect(parseInt(zigbeeEndpointTypeAttribute.defaultValue)).toEqual(0)
expect(parseInt(zigbeeEndpointTypeAttribute.defaultValue)).toEqual(
- parseInt(matterEndpointTypeAttribute.defaultValue),
+ parseInt(matterEndpointTypeAttribute.defaultValue)
)
// Change zigbee ETA and check for the change in the corresponding Matter ETA.
await queryConfig.updateEndpointTypeAttribute(
db,
zigbeeEndpointTypeAttribute.endpointTypeAttributeId,
- [['defaultValue', 1]],
+ [['defaultValue', 1]]
)
let allEndpointTypeAttributesAfterChange =
await queryConfig.selectAllSessionAttributes(db, importRes.sessionId)
@@ -263,7 +272,7 @@ test(
}
expect(parseInt(zigbeeEndpointTypeAttribute.defaultValue)).toEqual(1)
expect(parseInt(zigbeeEndpointTypeAttribute.defaultValue)).toEqual(
- parseInt(matterEndpointTypeAttribute.defaultValue),
+ parseInt(matterEndpointTypeAttribute.defaultValue)
)
// Negative test: Check that none of the other Endpoint Type Attribute values are not changed. Only the ones intended i.e. on/off
@@ -273,7 +282,7 @@ test(
allEndpointTypeAttributes[i].name.toLowerCase() != 'onoff'
) {
expect(allEndpointTypeAttributes[i].defaultValue).toEqual(
- allEndpointTypeAttributesAfterChange[i].defaultValue,
+ allEndpointTypeAttributesAfterChange[i].defaultValue
)
}
}
@@ -282,7 +291,7 @@ test(
await queryConfig.updateEndpointTypeAttribute(
db,
matterEndpointTypeAttribute.endpointTypeAttributeId,
- [['defaultValue', 0]],
+ [['defaultValue', 0]]
)
allEndpointTypeAttributesAfterChange =
await queryConfig.selectAllSessionAttributes(db, importRes.sessionId)
@@ -296,8 +305,8 @@ test(
}
expect(parseInt(matterEndpointTypeAttribute.defaultValue)).toEqual(0)
expect(parseInt(matterEndpointTypeAttribute.defaultValue)).toEqual(
- parseInt(zigbeeEndpointTypeAttribute.defaultValue),
+ parseInt(zigbeeEndpointTypeAttribute.defaultValue)
)
},
- testUtil.timeout.long(),
+ testUtil.timeout.long()
)
diff --git a/zcl-builtin/silabs/multi-protocol.json b/zcl-builtin/silabs/multi-protocol.json
index ca452169e6..850d4b6b7c 100644
--- a/zcl-builtin/silabs/multi-protocol.json
+++ b/zcl-builtin/silabs/multi-protocol.json
@@ -22,6 +22,17 @@
"code": "0x0000",
"manufacturerCode": null
}
+ },
+ {
+ "id": 2,
+ "matter": {
+ "code": "0x4003",
+ "manufacturerCode": null
+ },
+ "zigbee": {
+ "code": "0x4003",
+ "manufacturerCode": null
+ }
}
]
},