Skip to content

Commit feb352c

Browse files
authored
Adding to enabled_attributes_for_cluster_and_side and zcl_attributes_server helper to replace chip_server_cluster_attributes (#899)
- chip_server_cluster_attributes is returning server attributes which are not actually enabled because the server side cluster is disabled. - The reason chip_server_cluster_attributes is picking the server side attributes which are not enabled is because those are enabled in the .zap file(Which is the case for saving user selections and ease of use). However the helper is not actually checking if the cluster is enabled as well. - enabled_attributes_for_cluster_and_side is solving this issue correctly and actually only showing attributes which are truly enabled. - Extending endpointTypeAttributeExtended such that there is a common place for an attribute map - Updating endpointTypeAttributeExtended with everything that attributeExportMapping had such that it can act as a common place for all other temporary maps that have been created across our code. Also sorting endpointTypeAttributeExtended for easier readability and avoiding duplicate keys - Updating zcl_attributes_server block helper such that it can behave like chip_server_cluster_attributes. - Updating attribute map such that it can be used more widely - Adding additional helpers to remove the stateful helpers - Adding removeKeys option for removing certain columns which are not needed in a block helper such as enabled_attributes_for_cluster_and_side and zcl_attributes_server - Adding if_unsupported_attribute_type and if_attribute_complex to check for unsupported and complex zcl data types - Deprecating old stateful helpers with new stateless helpers - Adding select data type using type name and cluster id to data_types, enums, bitmap, numbers and structs - Adding if_unsupported_attribute_callback helper and if_basic_attribute if helpers for java code generation - Deprecating java and python zcl type helpers with new zcl type helpers such that they do not need any stateful information coming from parent block helpers. For eg chipType and chipCallback.type - Adding tests for all the newly introduced helpers. - Updating Api documentation - Adding if_is_data_type_signed and as_zcl_data_type_size to determine sign and size of zcl data types - if_is_data_type_signed and as_zcl_data_type_size take type name and cluster id to return size and sign of the zcl data types - Github: ZAP#898
1 parent f630679 commit feb352c

File tree

20 files changed

+2251
-397
lines changed

20 files changed

+2251
-397
lines changed

docs/api.md

Lines changed: 1282 additions & 311 deletions
Large diffs are not rendered by default.

src-electron/db/db-mapping.js

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
const dbApi = require('./db-api.js')
2525
const dbEnums = require('../../src-shared/db-enum.js')
26+
const bin = require('../util/bin')
2627

2728
exports.map = {
2829
package: (x) => {
@@ -93,7 +94,7 @@ exports.map = {
9394
manufacturerCode: x.MANUFACTURER_CODE,
9495
name: x.NAME,
9596
label: x.NAME,
96-
type: x.TYPE,
97+
type: x.TYPE != 'array' ? x.TYPE : x.ARRAY_TYPE,
9798
side: x.SIDE,
9899
define: x.DEFINE,
99100
min: x.MIN,
@@ -105,15 +106,20 @@ exports.map = {
105106
reportableChange: x.REPORTABLE_CHANGE,
106107
reportableChangeLength: x.REPORTABLE_CHANGE_LENGTH,
107108
isWritable: dbApi.fromDbBool(x.IS_WRITABLE),
109+
isWritableAttribute: dbApi.fromDbBool(x.IS_WRITABLE),
108110
isNullable: dbApi.fromDbBool(x.IS_NULLABLE),
109111
defaultValue: x.DEFAULT_VALUE,
110112
isOptional: dbApi.fromDbBool(x.IS_OPTIONAL),
111113
isReportable:
112114
x.REPORTING_POLICY == dbEnums.reportingPolicy.mandatory ||
113115
x.REPORTING_POLICY == dbEnums.reportingPolicy.suggested,
116+
isReportableAttribute:
117+
x.REPORTING_POLICY == dbEnums.reportingPolicy.mandatory ||
118+
x.REPORTING_POLICY == dbEnums.reportingPolicy.suggested,
114119
reportingPolicy: x.REPORTING_POLICY,
115120
isSceneRequired: dbApi.fromDbBool(x.IS_SCENE_REQUIRED),
116121
entryType: x.ARRAY_TYPE,
122+
isArray: x.ARRAY_TYPE ? 1 : 0,
117123
mustUseTimedWrite: dbApi.fromDbBool(x.MUST_USE_TIMED_WRITE),
118124
}
119125
},
@@ -475,36 +481,61 @@ exports.map = {
475481
endpointTypeAttributeExtended: (x) => {
476482
if (x == null) return undefined
477483
return {
478-
endpointTypeRef: x.ENDPOINT_TYPE_REF,
479-
clusterRef: x.CLUSTER_REF,
484+
arrayType: x.ARRAY_TYPE,
480485
attributeRef: x.ATTRIBUTE_REF,
481-
included: dbApi.fromDbBool(x.INCLUDED),
482-
storageOption: x.STORAGE_OPTION,
483-
singleton: dbApi.fromDbBool(x.SINGLETON),
484486
bounded: dbApi.fromDbBool(x.BOUNDED),
485-
defaultValue: x.DEFAULT_VALUE,
486-
includedReportable: dbApi.fromDbBool(x.INCLUDED_REPORTABLE),
487-
minInterval: x.MIN_INTERVAL,
488-
maxInterval: x.MAX_INTERVAL,
489-
reportableChange: x.REPORTABLE_CHANGE,
490-
name: x.NAME, // Attribute Name
491-
code: x.CODE, // Attribute Code
492-
side: x.SIDE, // Attribute Side
493-
define: x.DEFINE, // Attribute define
494-
type: x.TYPE, // Attribute type
495-
mfgCode: x.MANUFACTURER_CODE
496-
? x.MANUFACTURER_CODE
497-
: x.CLUSTER_MANUFACTURER_CODE, // Attribute manufacturer code
487+
clusterDefine: x.CLUSTER_DEFINE,
498488
clusterMfgCode: x.CLUSTER_MANUFACTURER_CODE,
499489
clusterName: x.CLUSTER_NAME,
500-
clusterDefine: x.CLUSTER_DEFINE,
501-
isSingleton: dbApi.fromDbBool(x.SINGLETON), // Endpoint type attribute is singleton or not
490+
clusterRef: x.CLUSTER_REF,
491+
clusterSide: x.SIDE,
492+
code: x.CODE, // Attribute Code
493+
defaultValue: x.DEFAULT_VALUE,
494+
define: x.DEFINE, // Attribute define
495+
endpointId: x.ENDPOINT_IDENTIFIER, // Endpoint type attribute's endpoint Id
496+
endpointTypeRef: x.ENDPOINT_TYPE_REF,
497+
entryType: x.ARRAY_TYPE,
498+
hexCode: '0x' + bin.int16ToHex(x['CODE'] ? x['CODE'] : 0), // Attribute code in hex
499+
id: x.ATTRIBUTE_ID, // Attribute id
500+
included: dbApi.fromDbBool(x.INCLUDED),
501+
includedReportable: dbApi.fromDbBool(x.INCLUDED_REPORTABLE), // Is attribute reportable
502+
isArray: x.IS_ARRAY, // Is attribute of type array
503+
isBound: dbApi.fromDbBool(x.BOUNDED), // Is endpoint type attribute bounded
504+
isClusterEnabled: x.ENABLED,
505+
isGlobalAttribute: x.IS_GLOBAL_ATTRIBUTE, // Is attribute global
506+
isIncluded: dbApi.fromDbBool(x.INCLUDED), // Is endpoint type attribute included
502507
isManufacturingSpecific: dbApi.toDbBool(
503508
x.MANUFACTURER_CODE | x.CLUSTER_MANUFACTURER_CODE
504509
), // Is Attribute mfg specific or not
505-
endpointId: x.ENDPOINT_IDENTIFIER, // Endpoint type attribute's endpoint Id
506-
tokenId: x.TOKEN_ID, // Endpoint type attribute's token id
510+
isNullable: dbApi.fromDbBool(x.IS_NULLABLE), // Is attribute nullable
511+
isOptionalAttribute: dbApi.fromDbBool(x.IS_OPTIONAL),
512+
isReportableAttribute: dbApi.fromDbBool(x.INCLUDED_REPORTABLE), // Is attribute reportable
513+
isSceneRequired: dbApi.fromDbBool(x.IS_SCENE_REQUIRED),
514+
isSingleton: dbApi.fromDbBool(x.SINGLETON), // Endpoint type attribute is singleton or not
515+
isWritable: dbApi.fromDbBool(x.IS_WRITABLE), // Is attribute writable
516+
isWritableAttribute: dbApi.fromDbBool(x.IS_WRITABLE), // Is attribute writable
517+
manufacturerCode: x.MANUFACTURER_CODE
518+
? x.MANUFACTURER_CODE
519+
: x.CLUSTER_MANUFACTURER_CODE, // Attribute manufacturer code
520+
max: x.MAX, // Attribute max value
521+
maxInterval: x.MAX_INTERVAL,
522+
maxLength: x.MAX_LENGTH, // Attribute max length
523+
mfgCode: x.MANUFACTURER_CODE
524+
? x.MANUFACTURER_CODE
525+
: x.CLUSTER_MANUFACTURER_CODE, // Attribute manufacturer code
526+
min: x.MIN, // Attribute min value
527+
minInterval: x.MIN_INTERVAL,
528+
minLength: x.MIN_LENGTH, // Attribute min length
529+
mustUseTimedWrite: dbApi.fromDbBool(x.MUST_USE_TIMED_WRITE),
530+
name: x.NAME, // Attribute Name
531+
reportableChange: x.REPORTABLE_CHANGE,
532+
side: x.SIDE, // Attribute Side
533+
singleton: dbApi.fromDbBool(x.SINGLETON),
507534
smallestEndpointIdentifier: x.SMALLEST_ENDPOINT_IDENTIFIER, // Smallest endpoint Id in which the attribute is present
535+
storage: x.STORAGE_OPTION,
536+
storageOption: x.STORAGE_OPTION,
537+
tokenId: x.TOKEN_ID, // Endpoint type attribute's token id
538+
type: x.TYPE != 'array' ? x.TYPE : x.ARRAY_TYPE, // Attribute type
508539
}
509540
},
510541

src-electron/db/query-attribute.js

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,6 @@ const dbApi = require('./db-api.js')
2424
const dbMapping = require('./db-mapping.js')
2525
const dbCache = require('./db-cache')
2626

27-
function attributeExportMapping(x) {
28-
return {
29-
id: x.ATTRIBUTE_ID,
30-
name: x.NAME,
31-
code: x.CODE,
32-
side: x.SIDE,
33-
type: x.TYPE,
34-
define: x.DEFINE,
35-
mfgCode: x.MANUFACTURER_CODE,
36-
clusterSide: x.SIDE,
37-
clusterName: x.CLUSTER_NAME,
38-
isClusterEnabled: x.ENABLED,
39-
}
40-
}
41-
4227
/**
4328
* Promises to select all endpoint type attributes filtered by EndpointTypeRef and ClusterRef.
4429
*
@@ -147,13 +132,19 @@ async function duplicateEndpointTypeAttribute(
147132
* @param {*} db
148133
* @param {*} endpointTypeId
149134
* @param {*} packageIds
135+
* @param {*} side
150136
* @returns Promise that resolves with the attribute data.
151137
*/
152138
async function selectAllAttributeDetailsFromEnabledClusters(
153139
db,
154140
endpointsAndClusters,
155-
packageIds
141+
packageIds,
142+
side = null
156143
) {
144+
let sideFilter = ''
145+
if (side) {
146+
sideFilter = ` AND ATTRIBUTE.SIDE = '${side}' `
147+
}
157148
let endpointTypeClusterRef = endpointsAndClusters
158149
.map((ep) => ep.endpointTypeClusterRef)
159150
.toString()
@@ -171,21 +162,59 @@ async function selectAllAttributeDetailsFromEnabledClusters(
171162
ATTRIBUTE.MANUFACTURER_CODE,
172163
ENDPOINT_TYPE_CLUSTER.SIDE,
173164
CLUSTER.NAME AS CLUSTER_NAME,
174-
ENDPOINT_TYPE_CLUSTER.ENABLED
165+
ENDPOINT_TYPE_CLUSTER.ENABLED,
166+
CASE
167+
WHEN
168+
ATTRIBUTE.ARRAY_TYPE IS NOT NULL
169+
THEN
170+
1
171+
ELSE
172+
0
173+
END AS IS_ARRAY,
174+
ATTRIBUTE.IS_WRITABLE,
175+
ATTRIBUTE.IS_NULLABLE,
176+
ATTRIBUTE.MAX_LENGTH,
177+
ATTRIBUTE.MIN_LENGTH,
178+
ATTRIBUTE.MIN,
179+
ATTRIBUTE.MAX,
180+
ATTRIBUTE.ARRAY_TYPE,
181+
ATTRIBUTE.MUST_USE_TIMED_WRITE,
182+
ATTRIBUTE.IS_SCENE_REQUIRED,
183+
ATTRIBUTE.IS_OPTIONAL,
184+
CASE
185+
WHEN
186+
ATTRIBUTE.CLUSTER_REF IS NULL
187+
THEN
188+
1
189+
ELSE
190+
0
191+
END AS IS_GLOBAL_ATTRIBUTE,
192+
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED_REPORTABLE,
193+
ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION,
194+
ENDPOINT_TYPE_ATTRIBUTE.SINGLETON,
195+
ENDPOINT_TYPE_ATTRIBUTE.BOUNDED,
196+
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED,
197+
ENDPOINT_TYPE_ATTRIBUTE.DEFAULT_VALUE,
198+
ENDPOINT_TYPE_ATTRIBUTE.MIN_INTERVAL,
199+
ENDPOINT_TYPE_ATTRIBUTE.MAX_INTERVAL,
200+
ENDPOINT_TYPE_ATTRIBUTE.REPORTABLE_CHANGE
175201
FROM ATTRIBUTE
176202
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
177203
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
178-
INNER JOIN CLUSTER
179-
ON ATTRIBUTE.CLUSTER_REF = CLUSTER.CLUSTER_ID
180204
INNER JOIN ENDPOINT_TYPE_CLUSTER
181-
ON CLUSTER.CLUSTER_ID = ENDPOINT_TYPE_CLUSTER.CLUSTER_REF
205+
ON ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
206+
INNER JOIN CLUSTER
207+
ON ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
182208
WHERE ENDPOINT_TYPE_CLUSTER.CLUSTER_REF IN (${endpointTypeClusterRef})
183209
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1
184-
AND ATTRIBUTE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
185-
GROUP BY ATTRIBUTE.NAME
210+
AND ENDPOINT_TYPE_CLUSTER.ENABLED = 1
211+
AND ATTRIBUTE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
212+
${sideFilter}
213+
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.CODE, ATTRIBUTE.SIDE
214+
ORDER BY ATTRIBUTE.CODE
186215
`
187216
)
188-
.then((rows) => rows.map(attributeExportMapping))
217+
.then((rows) => rows.map(dbMapping.map.endpointTypeAttributeExtended))
189218
}
190219

191220
/**
@@ -248,7 +277,7 @@ async function selectAttributeDetailsFromAllEndpointTypesAndClustersUtil(
248277
GROUP BY ATTRIBUTE.NAME
249278
`
250279
)
251-
.then((rows) => rows.map(attributeExportMapping))
280+
.then((rows) => rows.map(dbMapping.map.endpointTypeAttributeExtended))
252281
}
253282

254283
/**

src-electron/db/query-bitmap.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
const dbApi = require('./db-api')
2424
const dbCache = require('./db-cache')
2525
const dbMapping = require('./db-mapping')
26+
const queryUtil = require('./query-util')
2627

2728
/**
2829
* Retrieves all the bitmaps in the database.
@@ -68,6 +69,39 @@ WHERE (DATA_TYPE.NAME = ? OR DATA_TYPE.NAME = ?) AND DATA_TYPE.PACKAGE_REF IN ($
6869
.then(dbMapping.map.bitmap)
6970
}
7071

72+
/**
73+
* Select a bitmap matched by name and clusterId.
74+
* @param {*} db
75+
* @param {*} name
76+
* @param {*} clusterId
77+
* @param {*} packageIds
78+
* @returns bitmap information or undefined
79+
*/
80+
async function selectBitmapByNameAndClusterId(db, name, clusterId, packageIds) {
81+
let queryWithoutClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
82+
'bitmap',
83+
null,
84+
packageIds
85+
)
86+
let queryWithClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
87+
'bitmap',
88+
clusterId,
89+
packageIds
90+
)
91+
92+
let res = await dbApi
93+
.dbAll(db, queryWithoutClusterId, [name, name.toLowerCase()])
94+
.then((rows) => rows.map(dbMapping.map.bitmap))
95+
96+
if (res && res.length == 1) {
97+
return res[0]
98+
} else {
99+
return dbApi
100+
.dbGet(db, queryWithClusterId, [name, name.toLowerCase(), clusterId])
101+
.then(dbMapping.map.bitmap)
102+
}
103+
}
104+
71105
async function selectBitmapById(db, id) {
72106
return dbApi
73107
.dbGet(
@@ -88,3 +122,6 @@ WHERE BITMAP_ID = ?`,
88122
exports.selectBitmapById = selectBitmapById
89123
exports.selectAllBitmaps = selectAllBitmaps
90124
exports.selectBitmapByName = dbCache.cacheQuery(selectBitmapByName)
125+
exports.selectBitmapByNameAndClusterId = dbCache.cacheQuery(
126+
selectBitmapByNameAndClusterId
127+
)

src-electron/db/query-data-type.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,71 @@ async function selectDataTypeByName(db, name, packageIds) {
9494
.then(dbMapping.map.dataType)
9595
}
9696

97+
/**
98+
* Gathers the data type information based on data type name and
99+
* clusterId along with its actual type from disciminator table.
100+
* @param db
101+
* @param name
102+
* @param clusterId
103+
* @param packageIds
104+
* @returns Data type information
105+
*/
106+
async function selectDataTypeByNameAndClusterId(
107+
db,
108+
name,
109+
clusterId,
110+
packageIds
111+
) {
112+
let selectQueryString = `
113+
SELECT
114+
DATA_TYPE.DATA_TYPE_ID,
115+
DATA_TYPE.NAME AS NAME,
116+
DATA_TYPE.DESCRIPTION,
117+
DATA_TYPE.DISCRIMINATOR_REF,
118+
DATA_TYPE.PACKAGE_REF,
119+
DISCRIMINATOR.NAME AS DISCRIMINATOR_NAME
120+
FROM
121+
DATA_TYPE
122+
INNER JOIN
123+
DISCRIMINATOR
124+
ON
125+
DATA_TYPE.DISCRIMINATOR_REF = DISCRIMINATOR.DISCRIMINATOR_ID `
126+
127+
let clusterQueryExtension = `
128+
INNER JOIN
129+
DATA_TYPE_CLUSTER
130+
ON
131+
DATA_TYPE.DATA_TYPE_ID = DATA_TYPE_CLUSTER.DATA_TYPE_REF `
132+
133+
let whereClause = `
134+
WHERE
135+
(DATA_TYPE.NAME = ? OR DATA_TYPE.NAME = ?)
136+
AND DATA_TYPE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)}) `
137+
138+
let whereClauseClusterExtension = `
139+
AND DATA_TYPE_CLUSTER.CLUSTER_REF = ?`
140+
141+
let queryWithoutClusterId = selectQueryString + whereClause
142+
let queryWithClusterId =
143+
selectQueryString +
144+
clusterQueryExtension +
145+
whereClause +
146+
whereClauseClusterExtension
147+
148+
let smallCaseName = name.toLowerCase()
149+
let res = await dbApi
150+
.dbAll(db, queryWithoutClusterId, [name, smallCaseName])
151+
.then((rows) => rows.map(dbMapping.map.dataType))
152+
153+
if (res && res.length == 1) {
154+
return res[0]
155+
} else {
156+
return dbApi
157+
.dbGet(db, queryWithClusterId, [name, smallCaseName, clusterId])
158+
.then(dbMapping.map.dataType)
159+
}
160+
}
161+
97162
/**
98163
* Gathers All the data types
99164
* @param db
@@ -186,3 +251,6 @@ exports.selectDataTypeById = selectDataTypeById
186251
exports.selectDataTypeByName = dbCache.cacheQuery(selectDataTypeByName)
187252
exports.selectAllDataTypes = selectAllDataTypes
188253
exports.selectSizeFromType = selectSizeFromType
254+
exports.selectDataTypeByNameAndClusterId = dbCache.cacheQuery(
255+
selectDataTypeByNameAndClusterId
256+
)

0 commit comments

Comments
 (0)