Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding to zcl_attributes_server and enabled_attributes_for_cluster_and_side helpers to replace chip_server_cluster_attributes #899

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,593 changes: 1,282 additions & 311 deletions docs/api.md

Large diffs are not rendered by default.

77 changes: 54 additions & 23 deletions src-electron/db/db-mapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

const dbApi = require('./db-api.js')
const dbEnums = require('../../src-shared/db-enum.js')
const bin = require('../util/bin')

exports.map = {
package: (x) => {
Expand Down Expand Up @@ -93,7 +94,7 @@ exports.map = {
manufacturerCode: x.MANUFACTURER_CODE,
name: x.NAME,
label: x.NAME,
type: x.TYPE,
type: x.TYPE != 'array' ? x.TYPE : x.ARRAY_TYPE,
side: x.SIDE,
define: x.DEFINE,
min: x.MIN,
Expand All @@ -105,15 +106,20 @@ exports.map = {
reportableChange: x.REPORTABLE_CHANGE,
reportableChangeLength: x.REPORTABLE_CHANGE_LENGTH,
isWritable: dbApi.fromDbBool(x.IS_WRITABLE),
isWritableAttribute: dbApi.fromDbBool(x.IS_WRITABLE),
isNullable: dbApi.fromDbBool(x.IS_NULLABLE),
defaultValue: x.DEFAULT_VALUE,
isOptional: dbApi.fromDbBool(x.IS_OPTIONAL),
isReportable:
x.REPORTING_POLICY == dbEnums.reportingPolicy.mandatory ||
x.REPORTING_POLICY == dbEnums.reportingPolicy.suggested,
isReportableAttribute:
x.REPORTING_POLICY == dbEnums.reportingPolicy.mandatory ||
x.REPORTING_POLICY == dbEnums.reportingPolicy.suggested,
reportingPolicy: x.REPORTING_POLICY,
isSceneRequired: dbApi.fromDbBool(x.IS_SCENE_REQUIRED),
entryType: x.ARRAY_TYPE,
isArray: x.ARRAY_TYPE ? 1 : 0,
mustUseTimedWrite: dbApi.fromDbBool(x.MUST_USE_TIMED_WRITE),
}
},
Expand Down Expand Up @@ -475,36 +481,61 @@ exports.map = {
endpointTypeAttributeExtended: (x) => {
if (x == null) return undefined
return {
endpointTypeRef: x.ENDPOINT_TYPE_REF,
clusterRef: x.CLUSTER_REF,
arrayType: x.ARRAY_TYPE,
attributeRef: x.ATTRIBUTE_REF,
included: dbApi.fromDbBool(x.INCLUDED),
storageOption: x.STORAGE_OPTION,
singleton: dbApi.fromDbBool(x.SINGLETON),
bounded: dbApi.fromDbBool(x.BOUNDED),
defaultValue: x.DEFAULT_VALUE,
includedReportable: dbApi.fromDbBool(x.INCLUDED_REPORTABLE),
minInterval: x.MIN_INTERVAL,
maxInterval: x.MAX_INTERVAL,
reportableChange: x.REPORTABLE_CHANGE,
name: x.NAME, // Attribute Name
code: x.CODE, // Attribute Code
side: x.SIDE, // Attribute Side
define: x.DEFINE, // Attribute define
type: x.TYPE, // Attribute type
mfgCode: x.MANUFACTURER_CODE
? x.MANUFACTURER_CODE
: x.CLUSTER_MANUFACTURER_CODE, // Attribute manufacturer code
clusterDefine: x.CLUSTER_DEFINE,
clusterMfgCode: x.CLUSTER_MANUFACTURER_CODE,
clusterName: x.CLUSTER_NAME,
clusterDefine: x.CLUSTER_DEFINE,
isSingleton: dbApi.fromDbBool(x.SINGLETON), // Endpoint type attribute is singleton or not
clusterRef: x.CLUSTER_REF,
clusterSide: x.SIDE,
code: x.CODE, // Attribute Code
defaultValue: x.DEFAULT_VALUE,
define: x.DEFINE, // Attribute define
endpointId: x.ENDPOINT_IDENTIFIER, // Endpoint type attribute's endpoint Id
endpointTypeRef: x.ENDPOINT_TYPE_REF,
entryType: x.ARRAY_TYPE,
hexCode: '0x' + bin.int16ToHex(x['CODE'] ? x['CODE'] : 0), // Attribute code in hex
id: x.ATTRIBUTE_ID, // Attribute id
included: dbApi.fromDbBool(x.INCLUDED),
includedReportable: dbApi.fromDbBool(x.INCLUDED_REPORTABLE), // Is attribute reportable
isArray: x.IS_ARRAY, // Is attribute of type array
isBound: dbApi.fromDbBool(x.BOUNDED), // Is endpoint type attribute bounded
isClusterEnabled: x.ENABLED,
isGlobalAttribute: x.IS_GLOBAL_ATTRIBUTE, // Is attribute global
isIncluded: dbApi.fromDbBool(x.INCLUDED), // Is endpoint type attribute included
isManufacturingSpecific: dbApi.toDbBool(
x.MANUFACTURER_CODE | x.CLUSTER_MANUFACTURER_CODE
), // Is Attribute mfg specific or not
endpointId: x.ENDPOINT_IDENTIFIER, // Endpoint type attribute's endpoint Id
tokenId: x.TOKEN_ID, // Endpoint type attribute's token id
isNullable: dbApi.fromDbBool(x.IS_NULLABLE), // Is attribute nullable
isOptionalAttribute: dbApi.fromDbBool(x.IS_OPTIONAL),
isReportableAttribute: dbApi.fromDbBool(x.INCLUDED_REPORTABLE), // Is attribute reportable
isSceneRequired: dbApi.fromDbBool(x.IS_SCENE_REQUIRED),
isSingleton: dbApi.fromDbBool(x.SINGLETON), // Endpoint type attribute is singleton or not
isWritable: dbApi.fromDbBool(x.IS_WRITABLE), // Is attribute writable
isWritableAttribute: dbApi.fromDbBool(x.IS_WRITABLE), // Is attribute writable
manufacturerCode: x.MANUFACTURER_CODE
? x.MANUFACTURER_CODE
: x.CLUSTER_MANUFACTURER_CODE, // Attribute manufacturer code
max: x.MAX, // Attribute max value
maxInterval: x.MAX_INTERVAL,
maxLength: x.MAX_LENGTH, // Attribute max length
mfgCode: x.MANUFACTURER_CODE
? x.MANUFACTURER_CODE
: x.CLUSTER_MANUFACTURER_CODE, // Attribute manufacturer code
min: x.MIN, // Attribute min value
minInterval: x.MIN_INTERVAL,
minLength: x.MIN_LENGTH, // Attribute min length
mustUseTimedWrite: dbApi.fromDbBool(x.MUST_USE_TIMED_WRITE),
name: x.NAME, // Attribute Name
reportableChange: x.REPORTABLE_CHANGE,
side: x.SIDE, // Attribute Side
singleton: dbApi.fromDbBool(x.SINGLETON),
smallestEndpointIdentifier: x.SMALLEST_ENDPOINT_IDENTIFIER, // Smallest endpoint Id in which the attribute is present
storage: x.STORAGE_OPTION,
storageOption: x.STORAGE_OPTION,
tokenId: x.TOKEN_ID, // Endpoint type attribute's token id
type: x.TYPE != 'array' ? x.TYPE : x.ARRAY_TYPE, // Attribute type
}
},

Expand Down
77 changes: 53 additions & 24 deletions src-electron/db/query-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,6 @@ const dbApi = require('./db-api.js')
const dbMapping = require('./db-mapping.js')
const dbCache = require('./db-cache')

function attributeExportMapping(x) {
return {
id: x.ATTRIBUTE_ID,
name: x.NAME,
code: x.CODE,
side: x.SIDE,
type: x.TYPE,
define: x.DEFINE,
mfgCode: x.MANUFACTURER_CODE,
clusterSide: x.SIDE,
clusterName: x.CLUSTER_NAME,
isClusterEnabled: x.ENABLED,
}
}

/**
* Promises to select all endpoint type attributes filtered by EndpointTypeRef and ClusterRef.
*
Expand Down Expand Up @@ -147,13 +132,19 @@ async function duplicateEndpointTypeAttribute(
* @param {*} db
* @param {*} endpointTypeId
* @param {*} packageIds
* @param {*} side
* @returns Promise that resolves with the attribute data.
*/
async function selectAllAttributeDetailsFromEnabledClusters(
db,
endpointsAndClusters,
packageIds
packageIds,
side = null
) {
let sideFilter = ''
if (side) {
sideFilter = ` AND ATTRIBUTE.SIDE = '${side}' `
}
let endpointTypeClusterRef = endpointsAndClusters
.map((ep) => ep.endpointTypeClusterRef)
.toString()
Expand All @@ -171,21 +162,59 @@ async function selectAllAttributeDetailsFromEnabledClusters(
ATTRIBUTE.MANUFACTURER_CODE,
ENDPOINT_TYPE_CLUSTER.SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
ENDPOINT_TYPE_CLUSTER.ENABLED
ENDPOINT_TYPE_CLUSTER.ENABLED,
CASE
WHEN
ATTRIBUTE.ARRAY_TYPE IS NOT NULL
THEN
1
ELSE
0
END AS IS_ARRAY,
ATTRIBUTE.IS_WRITABLE,
ATTRIBUTE.IS_NULLABLE,
ATTRIBUTE.MAX_LENGTH,
ATTRIBUTE.MIN_LENGTH,
ATTRIBUTE.MIN,
ATTRIBUTE.MAX,
ATTRIBUTE.ARRAY_TYPE,
ATTRIBUTE.MUST_USE_TIMED_WRITE,
ATTRIBUTE.IS_SCENE_REQUIRED,
ATTRIBUTE.IS_OPTIONAL,
CASE
WHEN
ATTRIBUTE.CLUSTER_REF IS NULL
THEN
1
ELSE
0
END AS IS_GLOBAL_ATTRIBUTE,
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED_REPORTABLE,
ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION,
ENDPOINT_TYPE_ATTRIBUTE.SINGLETON,
ENDPOINT_TYPE_ATTRIBUTE.BOUNDED,
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED,
ENDPOINT_TYPE_ATTRIBUTE.DEFAULT_VALUE,
ENDPOINT_TYPE_ATTRIBUTE.MIN_INTERVAL,
ENDPOINT_TYPE_ATTRIBUTE.MAX_INTERVAL,
ENDPOINT_TYPE_ATTRIBUTE.REPORTABLE_CHANGE
FROM ATTRIBUTE
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN CLUSTER
ON ATTRIBUTE.CLUSTER_REF = CLUSTER.CLUSTER_ID
INNER JOIN ENDPOINT_TYPE_CLUSTER
ON CLUSTER.CLUSTER_ID = ENDPOINT_TYPE_CLUSTER.CLUSTER_REF
ON ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
INNER JOIN CLUSTER
ON ENDPOINT_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID
WHERE ENDPOINT_TYPE_CLUSTER.CLUSTER_REF IN (${endpointTypeClusterRef})
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1
AND ATTRIBUTE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
GROUP BY ATTRIBUTE.NAME
AND ENDPOINT_TYPE_CLUSTER.ENABLED = 1
AND ATTRIBUTE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)})
${sideFilter}
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.CODE, ATTRIBUTE.SIDE
ORDER BY ATTRIBUTE.CODE
`
)
.then((rows) => rows.map(attributeExportMapping))
.then((rows) => rows.map(dbMapping.map.endpointTypeAttributeExtended))
}

/**
Expand Down Expand Up @@ -248,7 +277,7 @@ async function selectAttributeDetailsFromAllEndpointTypesAndClustersUtil(
GROUP BY ATTRIBUTE.NAME
`
)
.then((rows) => rows.map(attributeExportMapping))
.then((rows) => rows.map(dbMapping.map.endpointTypeAttributeExtended))
brdandu marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
37 changes: 37 additions & 0 deletions src-electron/db/query-bitmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
const dbApi = require('./db-api')
const dbCache = require('./db-cache')
const dbMapping = require('./db-mapping')
const queryUtil = require('./query-util')

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

/**
* Select a bitmap matched by name and clusterId.
* @param {*} db
* @param {*} name
* @param {*} clusterId
* @param {*} packageIds
* @returns bitmap information or undefined
*/
async function selectBitmapByNameAndClusterId(db, name, clusterId, packageIds) {
let queryWithoutClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
'bitmap',
null,
packageIds
)
let queryWithClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId(
'bitmap',
clusterId,
packageIds
)

let res = await dbApi
.dbAll(db, queryWithoutClusterId, [name, name.toLowerCase()])
.then((rows) => rows.map(dbMapping.map.bitmap))

if (res && res.length == 1) {
return res[0]
} else {
return dbApi
.dbGet(db, queryWithClusterId, [name, name.toLowerCase(), clusterId])
.then(dbMapping.map.bitmap)
}
}

async function selectBitmapById(db, id) {
return dbApi
.dbGet(
Expand All @@ -88,3 +122,6 @@ WHERE BITMAP_ID = ?`,
exports.selectBitmapById = selectBitmapById
exports.selectAllBitmaps = selectAllBitmaps
exports.selectBitmapByName = dbCache.cacheQuery(selectBitmapByName)
exports.selectBitmapByNameAndClusterId = dbCache.cacheQuery(
selectBitmapByNameAndClusterId
)
68 changes: 68 additions & 0 deletions src-electron/db/query-data-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,71 @@ async function selectDataTypeByName(db, name, packageIds) {
.then(dbMapping.map.dataType)
}

/**
* Gathers the data type information based on data type name and
* clusterId along with its actual type from disciminator table.
* @param db
* @param name
* @param clusterId
* @param packageIds
* @returns Data type information
*/
async function selectDataTypeByNameAndClusterId(
db,
name,
clusterId,
packageIds
) {
let selectQueryString = `
SELECT
DATA_TYPE.DATA_TYPE_ID,
DATA_TYPE.NAME AS NAME,
DATA_TYPE.DESCRIPTION,
DATA_TYPE.DISCRIMINATOR_REF,
DATA_TYPE.PACKAGE_REF,
DISCRIMINATOR.NAME AS DISCRIMINATOR_NAME
FROM
DATA_TYPE
INNER JOIN
DISCRIMINATOR
ON
DATA_TYPE.DISCRIMINATOR_REF = DISCRIMINATOR.DISCRIMINATOR_ID `

let clusterQueryExtension = `
INNER JOIN
DATA_TYPE_CLUSTER
ON
DATA_TYPE.DATA_TYPE_ID = DATA_TYPE_CLUSTER.DATA_TYPE_REF `

let whereClause = `
WHERE
(DATA_TYPE.NAME = ? OR DATA_TYPE.NAME = ?)
AND DATA_TYPE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)}) `

let whereClauseClusterExtension = `
AND DATA_TYPE_CLUSTER.CLUSTER_REF = ?`

let queryWithoutClusterId = selectQueryString + whereClause
let queryWithClusterId =
selectQueryString +
clusterQueryExtension +
whereClause +
whereClauseClusterExtension

let smallCaseName = name.toLowerCase()
let res = await dbApi
.dbAll(db, queryWithoutClusterId, [name, smallCaseName])
.then((rows) => rows.map(dbMapping.map.dataType))

if (res && res.length == 1) {
return res[0]
} else {
return dbApi
.dbGet(db, queryWithClusterId, [name, smallCaseName, clusterId])
.then(dbMapping.map.dataType)
}
}

/**
* Gathers All the data types
* @param db
Expand Down Expand Up @@ -186,3 +251,6 @@ exports.selectDataTypeById = selectDataTypeById
exports.selectDataTypeByName = dbCache.cacheQuery(selectDataTypeByName)
exports.selectAllDataTypes = selectAllDataTypes
exports.selectSizeFromType = selectSizeFromType
exports.selectDataTypeByNameAndClusterId = dbCache.cacheQuery(
selectDataTypeByNameAndClusterId
)
Loading