更新
更旧
/**
*
* Copyright (c) 2021 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.
*/
/**
* This module provides queries related to attributes.
*
* @module DB API: attribute queries.
*/
const dbApi = require('./db-api.js')
const dbMapping = require('./db-mapping.js')
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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,
}
}
/**
* Returns a promise of data for attributes inside an endpoint type.
*
* @param {*} db
* @param {*} endpointTypeId
* @returns Promise that resolves with the attribute data.
*/
async function selectAllAttributeDetailsFromEnabledClusters(
db,
endpointsAndClusters
) {
let endpointTypeClusterRef = endpointsAndClusters
.map((ep) => ep.endpointTypeClusterRef)
.toString()
return dbApi
.dbAll(
db,
`
SELECT
ATTRIBUTE.ATTRIBUTE_ID,
ATTRIBUTE.NAME,
ATTRIBUTE.CODE,
ATTRIBUTE.SIDE,
ATTRIBUTE.TYPE,
ATTRIBUTE.DEFINE,
ATTRIBUTE.MANUFACTURER_CODE,
ENDPOINT_TYPE_CLUSTER.SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
ENDPOINT_TYPE_CLUSTER.ENABLED
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
WHERE ENDPOINT_TYPE_CLUSTER.CLUSTER_REF in (${endpointTypeClusterRef})
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1
GROUP BY ATTRIBUTE.NAME
`
)
.then((rows) => rows.map(attributeExportMapping))
}
/**
* Returns a promise of data for manufacturing/non-manufacturing specific attributes
* inside an endpoint type.
*
* @param db
* @param endpointTypeId
* @returns Promise that resolves with the manufacturing/non-manufacturing
* specific attribute data.
*/
async function selectAttributeDetailsFromAllEndpointTypesAndClustersUtil(
db,
endpointsAndClusters,
isManufacturingSpecific
) {
let endpointTypeIds = endpointsAndClusters
.map((ep) => ep.endpointId)
.toString()
let endpointClusterIds = endpointsAndClusters
.map((ep) => ep.endpointClusterId)
.toString()
return dbApi
.dbAll(
db,
`
SELECT
ATTRIBUTE.ATTRIBUTE_ID,
ATTRIBUTE.NAME,
ATTRIBUTE.CODE,
ATTRIBUTE.SIDE,
ATTRIBUTE.TYPE,
ATTRIBUTE.DEFINE,
ATTRIBUTE.MANUFACTURER_CODE,
ENDPOINT_TYPE_CLUSTER.SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
ENDPOINT_TYPE_CLUSTER.ENABLED
FROM
ATTRIBUTE
INNER JOIN
ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN
ENDPOINT_TYPE_CLUSTER
ON ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
INNER JOIN
CLUSTER
ON ATTRIBUTE.CLUSTER_REF = CLUSTER.CLUSTER_ID
WHERE
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_REF IN (${endpointTypeIds})
AND ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF in (${endpointClusterIds})
AND ATTRIBUTE.MANUFACTURER_CODE IS ` +
(isManufacturingSpecific ? `NOT ` : ``) +
`NULL
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
`
)
.then((rows) => rows.map(attributeExportMapping))
}
/**
* Returns a promise of data for manufacturing specific attributes inside an endpoint type.
*
* @param db
* @param endpointTypeId
* @returns Promise that resolves with the manufacturing specific attribute data.
*/
async function selectManufacturerSpecificAttributeDetailsFromAllEndpointTypesAndClusters(
db,
endpointsAndClusters
) {
return selectAttributeDetailsFromAllEndpointTypesAndClustersUtil(
db,
endpointsAndClusters,
true
)
}
/**
* Returns a promise of data for attributes with no manufacturing specific information inside an endpoint type.
*
* @param db
* @param endpointTypeId
* @returns Promise that resolves with the non-manufacturing specific attribute data.
*/
async function selectNonManufacturerSpecificAttributeDetailsFromAllEndpointTypesAndClusters(
db,
endpointsAndClusters
) {
return selectAttributeDetailsFromAllEndpointTypesAndClustersUtil(
db,
endpointsAndClusters,
false
)
}
/**
* Returns a promise of data for attributes inside an endpoint type
* that either have a default or a bounded attribute.
*
* @param {*} db
* @param {*} endpointTypeId
* @returns Promise that resolves with the attribute data.
*/
async function selectAttributeDetailsWithABoundFromEnabledClusters(
db,
endpointsAndClusters
) {
let endpointClusterIds = endpointsAndClusters
.map((ep) => ep.endpointClusterId)
.toString()
let mapFunction = (x) => {
return {
id: x.ATTRIBUTE_ID,
name: x.NAME,
side: x.SIDE,
clusterName: x.CLUSTER_NAME,
attributeMinValue: x.MIN,
attributeMaxValue: x.MAX,
defaultValue: x.DEFAULT_VALUE,
}
}
return dbApi
.dbAll(
db,
`
SELECT
ATTRIBUTE.ATTRIBUTE_ID,
ATTRIBUTE.NAME,
ATTRIBUTE.SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
ATTRIBUTE.MIN,
ATTRIBUTE.MAX,
ENDPOINT_TYPE_ATTRIBUTE.DEFAULT_VALUE
FROM
ATTRIBUTE
INNER JOIN
ENDPOINT_TYPE_ATTRIBUTE
ON
ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN
ENDPOINT_TYPE_CLUSTER
ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF = ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_CLUSTER_ID
CLUSTER
ON
CLUSTER.CLUSTER_ID = ENDPOINT_TYPE_CLUSTER.CLUSTER_REF
INNER JOIN
ATOMIC
ON
ATOMIC.NAME = ATTRIBUTE.TYPE
WHERE ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF in (${endpointClusterIds})
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1 AND ENDPOINT_TYPE_ATTRIBUTE.BOUNDED !=0
AND ENDPOINT_TYPE_CLUSTER.ENABLED=1
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.NAME, ATTRIBUTE.SIDE
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
`
)
.then((rows) => rows.map(mapFunction))
}
/**
* The enabled attributes details across all endpoints and clusters.
* @param db
* @param endpointsAndClusters
* @returns The enabled attributes details across all endpoints and clusters.
*/
async function selectAttributeDetailsFromEnabledClusters(
db,
endpointsAndClusters
) {
let endpointClusterIds = endpointsAndClusters
.map((ep) => ep.endpointClusterId)
.toString()
let mapFunction = (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,
isWritable: x.IS_WRITABLE,
clusterId: x.CLUSTER_ID,
clusterSide: x.CLUSTER_SIDE,
clusterName: x.CLUSTER_NAME,
clusterDefine: x.CLUSTER_DEFINE,
clusterCode: x.CLUSTER_CODE,
isAttributeBounded: x.BOUNDED,
storageOption: x.STORAGE_OPTION,
isSingleton: x.SINGLETON,
defaultValue: x.DEFAULT_VALUE,
attributeSize: x.ATOMIC_SIZE,
clusterIndex: x.CLUSTER_INDEX,
mfgAttributeCount: x.MANUFACTURING_SPECIFIC_ATTRIBUTE_COUNT,
singletonAttributeSize: x.SINGLETON_ATTRIBUTE_SIZE,
maxAttributeSize: x.MAX_ATTRIBUTE_SIZE,
}
}
return dbApi
.dbAll(
db,
`
SELECT
ATTRIBUTE.ATTRIBUTE_ID,
ATTRIBUTE.NAME,
ATTRIBUTE.CODE,
ATTRIBUTE.SIDE,
ATTRIBUTE.TYPE,
ATTRIBUTE.DEFINE,
ATTRIBUTE.MANUFACTURER_CODE,
ATTRIBUTE.IS_WRITABLE,
CLUSTER.CLUSTER_ID AS CLUSTER_ID,
ENDPOINT_TYPE_CLUSTER.SIDE AS CLUSTER_SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
CLUSTER.DEFINE AS CLUSTER_DEFINE,
CLUSTER.CODE AS CLUSTER_CODE,
ENDPOINT_TYPE_ATTRIBUTE.BOUNDED,
ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION,
ENDPOINT_TYPE_ATTRIBUTE.SINGLETON,
ENDPOINT_TYPE_ATTRIBUTE.DEFAULT_VALUE,
CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ROW_NUMBER() OVER (PARTITION BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ENDPOINT_TYPE_CLUSTER.SIDE ORDER BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE) CLUSTER_INDEX,
COUNT (ATTRIBUTE.MANUFACTURER_CODE) OVER () AS MANUFACTURING_SPECIFIC_ATTRIBUTE_COUNT,
SUM (CASE WHEN ENDPOINT_TYPE_ATTRIBUTE.SINGLETON=1 THEN
CASE WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END
ELSE 0 END) OVER () AS SINGLETON_ATTRIBUTE_SIZE,
MAX(CASE WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END) OVER () AS MAX_ATTRIBUTE_SIZE
FROM ATTRIBUTE
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN ENDPOINT_TYPE_CLUSTER
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
INNER JOIN ATOMIC
ON ATOMIC.NAME = ATTRIBUTE.TYPE
WHERE ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF IN (${endpointClusterIds})
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1 AND ENDPOINT_TYPE_CLUSTER.ENABLED=1 AND ENDPOINT_TYPE_CLUSTER.SIDE=ATTRIBUTE.SIDE
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.SIDE
ORDER BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ENDPOINT_TYPE_CLUSTER.SIDE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
`
)
.then((rows) => rows.map(mapFunction))
}
/**
*
* @param db
* @param endpointsAndClusters
* @returns
* Default values for the attributes longer than a pointer,
* in a form of a binary blob. All attribute values with size greater than 2 bytes.
* Excluding 0 values and externally saved values
* Union is used to get separate entries of attributes w.r.t to default, minimum
* and maximum values
*/
async function selectAttributeBoundDetails(db, endpointsAndClusters) {
let endpointClusterIds = endpointsAndClusters
.map((ep) => ep.endpointClusterId)
.toString()
let mapFunction = (x) => {
return {
id: x.ATTRIBUTE_ID,
name: x.NAME,
side: x.SIDE,
clusterName: x.CLUSTER_NAME,
clusterMfgCode: x.CLUSTER_MANUFACTURER_CODE,
defaultValue: x.ATT_VALUE,
attributeSize: x.ATOMIC_SIZE,
attributeValueType: x.ATTRIBUTE_VALUE_TYPE,
arrayIndex: x.ARRAY_INDEX,
isString: x.IS_STRING,
}
}
return dbApi
.dbAll(
db,
`SELECT
*, SUM(ATOMIC_SIZE) OVER (ORDER BY CLUSTER_MANUFACTURER_CODE, CLUSTER_NAME ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS ARRAY_INDEX FROM (
SELECT
ATTRIBUTE.ATTRIBUTE_ID AS ATTRIBUTE_ID,
ATTRIBUTE.NAME AS NAME,
ATTRIBUTE.SIDE AS SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
CLUSTER.MANUFACTURER_CODE AS CLUSTER_MANUFACTURER_CODE,
ENDPOINT_TYPE_ATTRIBUTE.DEFAULT_VALUE AS ATT_VALUE,
CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END AS ATOMIC_SIZE,
'DEFAULT' as ATTRIBUTE_VALUE_TYPE,
ATOMIC.IS_STRING AS IS_STRING
FROM ATTRIBUTE
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN ENDPOINT_TYPE_CLUSTER
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
INNER JOIN ATOMIC
ON ATOMIC.NAME = ATTRIBUTE.TYPE
WHERE ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF in (${endpointClusterIds})
AND ENDPOINT_TYPE_CLUSTER.SIDE = ATTRIBUTE.SIDE AND ENDPOINT_TYPE_CLUSTER.ENABLED=1
AND (CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END) > 2 AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1 AND ATT_VALUE IS NOT NULL AND ATT_VALUE != "" AND REPLACE(ATT_VALUE, '0', '')!='x' AND REPLACE(ATT_VALUE, '0', '')!=''
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.SIDE
UNION
SELECT
ATTRIBUTE.ATTRIBUTE_ID AS ATTRIBUTE_ID,
ATTRIBUTE.NAME AS NAME,
ATTRIBUTE.SIDE AS SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
CLUSTER.MANUFACTURER_CODE AS CLUSTER_MANUFACTURER_CODE,
ATTRIBUTE.MIN AS ATT_VALUE,
CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END AS ATOMIC_SIZE,
'MINIMUM' as ATTRIBUTE_VALUE_TYPE,
ATOMIC.IS_STRING AS IS_STRING
FROM ATTRIBUTE
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN ENDPOINT_TYPE_CLUSTER
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
INNER JOIN ATOMIC
ON ATOMIC.NAME = ATTRIBUTE.TYPE
WHERE ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF in (${endpointClusterIds})
AND ENDPOINT_TYPE_CLUSTER.SIDE = ATTRIBUTE.SIDE AND ENDPOINT_TYPE_CLUSTER.ENABLED=1
AND (CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END) > 2 AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1 AND ATT_VALUE IS NOT NULL AND ATT_VALUE != "" AND ENDPOINT_TYPE_ATTRIBUTE.BOUNDED !=0 AND REPLACE(ATT_VALUE, '0', '')!='x' AND REPLACE(ATT_VALUE, '0', '')!=''
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.SIDE
UNION
SELECT
ATTRIBUTE.ATTRIBUTE_ID AS ATTRIBUTE_ID,
ATTRIBUTE.NAME AS NAME,
ATTRIBUTE.SIDE AS SIDE,
CLUSTER.NAME AS CLUSTER_NAME,
CLUSTER.MANUFACTURER_CODE AS CLUSTER_MANUFACTURER_CODE,
ATTRIBUTE.MAX AS ATT_VALUE,
CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END AS ATOMIC_SIZE,
'MAXIMUM' as ATTRIBUTE_VALUE_TYPE,
ATOMIC.IS_STRING AS IS_STRING
FROM ATTRIBUTE
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN ENDPOINT_TYPE_CLUSTER
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
INNER JOIN ATOMIC
ON ATOMIC.NAME = ATTRIBUTE.TYPE
WHERE ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF in (${endpointClusterIds})
AND ENDPOINT_TYPE_CLUSTER.SIDE = ATTRIBUTE.SIDE AND ENDPOINT_TYPE_CLUSTER.ENABLED=1
AND (CASE
WHEN ATOMIC.IS_STRING=1 THEN
CASE WHEN ATOMIC.IS_LONG=0 THEN ATTRIBUTE.MAX_LENGTH+1
WHEN ATOMIC.IS_LONG=1 THEN ATTRIBUTE.MAX_LENGTH+2
ELSE ATOMIC.ATOMIC_SIZE
END
WHEN ATOMIC.ATOMIC_SIZE IS NULL THEN ATTRIBUTE.MAX_LENGTH
ELSE ATOMIC.ATOMIC_SIZE
END) > 2 AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1 AND ATT_VALUE IS NOT NULL AND ATT_VALUE != "" AND ENDPOINT_TYPE_ATTRIBUTE.BOUNDED !=0 AND REPLACE(ATT_VALUE, '0', '')!='x' AND REPLACE(ATT_VALUE, '0', '')!=''
GROUP BY CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.SIDE )
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
`
)
.then((rows) => rows.map(mapFunction))
}
/**
* The reportable attribute details per endpoint per clusters.
* @param {*} db
* @param {*} endpointsAndClusters
* @returns * The reportable attribute details per endpoint per clusters.
*/
async function selectReportableAttributeDetailsFromEnabledClustersAndEndpoints(
db,
endpointsAndClusters
) {
let endpointClusterIds = endpointsAndClusters
.map((ep) => ep.endpointClusterId)
.toString()
let mapFunction = (x) => {
return {
id: x.ATTRIBUTE_ID,
name: x.NAME,
code: x.CODE,
side: x.SIDE,
mfgCode: x.MANUFACTURER_CODE,
clusterName: x.CLUSTER_NAME,
clusterCode: x.CLUSTER_CODE,
attributeReportableMinValue: x.MIN_INTERVAL,
attributeReportableMaxValue: x.MAX_INTERVAL,
attributeReportableChange: x.REPORTABLE_CHANGE,
endpointIdentifier: x.ENDPOINT_IDENTIFIER,
}
}
return dbApi
.dbAll(
db,
`
SELECT
ATTRIBUTE.ATTRIBUTE_ID,
ATTRIBUTE.NAME,
ATTRIBUTE.CODE,
ATTRIBUTE.SIDE,
ATTRIBUTE.MANUFACTURER_CODE,
CLUSTER.NAME AS CLUSTER_NAME,
CLUSTER.CODE AS CLUSTER_CODE,
ENDPOINT_TYPE_ATTRIBUTE.MIN_INTERVAL,
ENDPOINT_TYPE_ATTRIBUTE.MAX_INTERVAL,
ENDPOINT_TYPE_ATTRIBUTE.REPORTABLE_CHANGE,
ENDPOINT.ENDPOINT_IDENTIFIER
FROM ATTRIBUTE
INNER JOIN ENDPOINT_TYPE_ATTRIBUTE
ON ATTRIBUTE.ATTRIBUTE_ID = ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF
INNER JOIN ENDPOINT_TYPE_CLUSTER
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
INNER JOIN ENDPOINT
ON ENDPOINT_TYPE_CLUSTER.ENDPOINT_TYPE_REF = ENDPOINT.ENDPOINT_TYPE_REF
INNER JOIN ATOMIC
ON ATOMIC.NAME = ATTRIBUTE.TYPE
WHERE ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF IN (${endpointClusterIds})
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED = 1 AND ENDPOINT_TYPE_CLUSTER.ENABLED=1 AND ENDPOINT_TYPE_CLUSTER.SIDE=ATTRIBUTE.SIDE
AND ENDPOINT_TYPE_ATTRIBUTE.INCLUDED_REPORTABLE = 1
GROUP BY CASE WHEN SINGLETON=0 THEN ENDPOINT.ENDPOINT_IDENTIFIER END, CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE, ATTRIBUTE.SIDE
HAVING CASE WHEN SINGLETON=1 THEN ENDPOINT.ENDPOINT_IDENTIFIER = MIN(ENDPOINT.ENDPOINT_IDENTIFIER) ELSE SINGLETON=0 END
ORDER BY ENDPOINT.ENDPOINT_IDENTIFIER, CLUSTER.MANUFACTURER_CODE, CLUSTER.CODE, ATTRIBUTE.CODE, ATTRIBUTE.MANUFACTURER_CODE
async function selectAttributeByCode(
db,
clusterCode,
attributeCode,
manufacturerCode
) {
if (clusterCode == null) {
return selectGlobalAttributeByCode(
db,
attributeCode,
manufacturerCode
)
return selectNonGlobalAttributeByCode(
db,
clusterCode,
attributeCode,
)
}
}
async function selectNonGlobalAttributeByCode(
db,
clusterCode,
attributeCode,
manufacturerCode
) {
let manufacturerCondition
let arg = [attributeCode, clusterCode]
if (manufacturerCode == null || manufacturerCode == 0) {
manufacturerCondition = 'C.MANUFACTURER_CODE IS NULL'
} else {
manufacturerCondition =
'( C.MANUFACTURER_CODE IS NULL OR C.MANUFACTURER_CODE = ? )'
arg.push(manufacturerCode)
}
return dbApi
.dbGet(
db,
`
SELECT
A.ATTRIBUTE_ID,
A.CLUSTER_REF,
A.CODE,
A.MANUFACTURER_CODE,
A.NAME,
A.TYPE,
A.SIDE,
A.DEFINE,
A.MIN,
A.MAX,
A.REPORT_MIN_INTERVAL,
A.REPORT_MAX_INTERVAL,
A.REPORTABLE_CHANGE,
A.REPORTABLE_CHANGE_LENGTH,
A.IS_WRITABLE,
A.DEFAULT_VALUE,
A.IS_OPTIONAL,

Timotej Ecimovic
已提交
A.REPORTING_POLICY,
A.ARRAY_TYPE,
A.MUST_USE_TIMED_WRITE
FROM ATTRIBUTE AS A
INNER JOIN CLUSTER AS C
ON C.CLUSTER_ID = A.CLUSTER_REF
WHERE A.PACKAGE_REF IN (${packageIds})
AND A.CODE = ?
AND C.CODE = ?
AND ${manufacturerCondition}`,
arg
)
.then(dbMapping.map.attribute)
}
async function selectGlobalAttributeByCode(
db,
attributeCode,
manufacturerCode
) {
let manufacturerCondition
let arg = [attributeCode]
if (manufacturerCode == null || manufacturerCode == 0) {
manufacturerCondition = 'A.MANUFACTURER_CODE IS NULL'
} else {
manufacturerCondition =
'( A.MANUFACTURER_CODE IS NULL OR A.MANUFACTURER_CODE = ? )'
arg.push(manufacturerCode)
}
return dbApi
.dbGet(
db,
`
SELECT
A.ATTRIBUTE_ID,
A.CLUSTER_REF,
A.CODE,
A.MANUFACTURER_CODE,
A.NAME,
A.TYPE,
A.SIDE,
A.DEFINE,
A.MIN,
A.MAX,
A.REPORT_MIN_INTERVAL,
A.REPORT_MAX_INTERVAL,
A.REPORTABLE_CHANGE,
A.REPORTABLE_CHANGE_LENGTH,
A.IS_WRITABLE,
A.DEFAULT_VALUE,
A.IS_OPTIONAL,

Timotej Ecimovic
已提交
A.REPORTING_POLICY,
A.IS_SCENE_REQUIRED,
A.ARRAY_TYPE,
A.MUST_USE_TIMED_WRITE
FROM ATTRIBUTE AS A
WHERE A.PACKAGE_REF IN (${packageIds})
AND ${manufacturerCondition}`,
arg
)
.then(dbMapping.map.attribute)
}
/**
* Retrieves the global attribute data for a given attribute code.
*
* @param {*} db
* @param {*} packageId
* @param {*} attributeCode
*/
async function selectGlobalAttributeDefaults(db, clusterRef, attributeRef) {
return dbApi
.dbAll(
db,
`
SELECT
GAD.DEFAULT_VALUE,
GAB.BIT,
GAB.VALUE,
(SELECT NAME FROM TAG WHERE TAG_ID = GAB.TAG_REF) AS TAG
FROM
GLOBAL_ATTRIBUTE_DEFAULT AS GAD
LEFT JOIN
GLOBAL_ATTRIBUTE_BIT AS GAB
ON
GAD.GLOBAL_ATTRIBUTE_DEFAULT_ID = GAB.GLOBAL_ATTRIBUTE_DEFAULT_REF
WHERE
GAD.CLUSTER_REF = ?
AND GAD.ATTRIBUTE_REF = ?
ORDER BY
GAD.CLUSTER_REF, GAD.ATTRIBUTE_REF, GAB.BIT
`,
[clusterRef, attributeRef]
)
.then((rows) =>
rows.reduce((ac, row) => {
if (!('default_value' in ac)) {
ac.defaultValue = row.DEFAULT_VALUE
}
if (row.BIT != null) {
if (!('featureBits' in ac)) {
ac.featureBits = []
}
ac.featureBits.push({ bit: row.BIT, value: row.VALUE, tag: row.TAG })
}
return ac
}, {})
)
exports.selectAllAttributeDetailsFromEnabledClusters =
selectAllAttributeDetailsFromEnabledClusters
exports.selectManufacturerSpecificAttributeDetailsFromAllEndpointTypesAndClusters =
selectManufacturerSpecificAttributeDetailsFromAllEndpointTypesAndClusters
exports.selectNonManufacturerSpecificAttributeDetailsFromAllEndpointTypesAndClusters =
selectNonManufacturerSpecificAttributeDetailsFromAllEndpointTypesAndClusters
exports.selectAttributeDetailsWithABoundFromEnabledClusters =
selectAttributeDetailsWithABoundFromEnabledClusters
exports.selectAttributeDetailsFromEnabledClusters =
selectAttributeDetailsFromEnabledClusters
exports.selectAttributeBoundDetails = selectAttributeBoundDetails
exports.selectReportableAttributeDetailsFromEnabledClustersAndEndpoints =
selectReportableAttributeDetailsFromEnabledClustersAndEndpoints
exports.selectGlobalAttributeDefaults = selectGlobalAttributeDefaults
exports.selectAttributeByCode = selectAttributeByCode