From f3bf51a3da0f45a9fea8f1b7049a9237f6f3b8fe Mon Sep 17 00:00:00 2001 From: brdandu Date: Thu, 31 Oct 2024 15:38:20 -0400 Subject: [PATCH] Add helper to determine the atomic identifier for attribute Id given - as_underlying_atomic_identifier_for_attributeId checks for the attribute type and returns the atomic identifier associated with it. - JIRA: ZAPP-1385 --- apack.json | 2 +- docs/api.md | 13 +++ docs/helpers.md | 13 +++ src-electron/generator/helper-attribute.js | 88 +++++++++++++++++++ .../zigbee/zap-config-version-3.zapt | 2 +- test/multi-protocol.test.js | 31 ++++--- zcl-builtin/silabs/multi-protocol.json | 11 +++ 7 files changed, 147 insertions(+), 13 deletions(-) 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 + } } ] },