Skip to content

Commit

Permalink
Enable Multiple Endpoints and Device Types in Device Composition Inse…
Browse files Browse the repository at this point in the history
…rtion (project-chip#1489)

* enabling ZAP to load multiple devices for an endpoint composition

* fixing code so there can be multiple endpoints with different consraints and conformance if necessary

* remove debug test

* PR review cleanup
  • Loading branch information
paulr34 authored Nov 22, 2024
1 parent 8a3df83 commit 3879080
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 27 deletions.
9 changes: 5 additions & 4 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4066,16 +4066,17 @@ Retrieves the endpoint composition ID for a given device type code.
<a name="module_DB API_ zcl loading queries..insertDeviceComposition"></a>

### DB API: zcl loading queries~insertDeviceComposition(db, deviceType, endpointCompositionId) ⇒ <code>Promise</code>
Inserts a device composition record into the DEVICE_COMPOSITION table.
Inserts device composition records for each deviceType into the DEVICE_COMPOSITION table
for all endpoints in the deviceType, including endpoint-specific constraint and conformance values.

This function constructs an SQL INSERT query to add a new record to the
DEVICE_COMPOSITION table. It handles the insertion of the device code,
endpoint composition reference, conformance, and constraint values.
DEVICE_COMPOSITION table for each deviceType in each endpoint. It handles the insertion
of the device code, endpoint composition reference, conformance, and constraint values.
Note that the "CONSTRAINT" column name is escaped with double quotes
to avoid conflicts with the SQL reserved keyword.

**Kind**: inner method of [<code>DB API: zcl loading queries</code>](#module_DB API_ zcl loading queries)
**Returns**: <code>Promise</code> - A promise that resolves when the insertion is complete.
**Returns**: <code>Promise</code> - A promise that resolves when all insertions are complete.

| Param | Type | Description |
| --- | --- | --- |
Expand Down
72 changes: 55 additions & 17 deletions src-electron/db/query-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1151,35 +1151,73 @@ async function getEndpointCompositionIdByCode(db, deviceType) {
}

/**
* Inserts a device composition record into the DEVICE_COMPOSITION table.
* Inserts device composition records for each deviceType into the DEVICE_COMPOSITION table
* for all endpoints in the deviceType, including endpoint-specific constraint and conformance values.
*
* This function constructs an SQL INSERT query to add a new record to the
* DEVICE_COMPOSITION table. It handles the insertion of the device code,
* endpoint composition reference, conformance, and constraint values.
* DEVICE_COMPOSITION table for each deviceType in each endpoint. It handles the insertion
* of the device code, endpoint composition reference, conformance, and constraint values.
* Note that the "CONSTRAINT" column name is escaped with double quotes
* to avoid conflicts with the SQL reserved keyword.
*
* @param {Object} db - The database connection object.
* @param {Object} deviceType - The device type object containing the data to be inserted.
* @param {number} endpointCompositionId - The ID of the endpoint composition.
* @returns {Promise} A promise that resolves when the insertion is complete.
* @returns {Promise} A promise that resolves when all insertions are complete.
*/
function insertDeviceComposition(db, deviceType, endpointCompositionId) {
const insertQuery = `
INSERT INTO DEVICE_COMPOSITION (CODE, ENDPOINT_COMPOSITION_REF, CONFORMANCE, DEVICE_CONSTRAINT)
VALUES (?, ?, ?, ?)
`
try {
return dbApi.dbInsert(db, insertQuery, [
parseInt(deviceType.childDeviceId, 16),
endpointCompositionId,
deviceType.conformance,
// Ensure that deviceType and its necessary properties are defined
if (!deviceType?.composition?.endpoint) {
throw new Error('Invalid deviceType object or endpoint data')
}

// Make sure 'deviceType.composition.endpoint' is always an array, even if there's only one endpoint
const endpoints = Array.isArray(deviceType.composition.endpoint)
? deviceType.composition.endpoint
: [deviceType.composition.endpoint]

// Prepare an array to hold all insert queries
const insertQueries = []

// Iterate over all endpoints in the deviceType and their respective deviceTypes
for (let endpoint of endpoints) {
// Ensure deviceType is present and handle both single value or array
const deviceTypes = Array.isArray(endpoint.deviceType)
? endpoint.deviceType
: endpoint.deviceType
? [endpoint.deviceType]
: [] // Default to empty array if undefined

// Use the $ to get the endpoint-specific conformance and constraint values
const endpointConformance =
endpoint.endpointComposition?.endpoint?.$.conformance ||
deviceType.conformance
const endpointConstraint =
endpoint.endpointComposition?.endpoint?.$.constraint ||
deviceType.constraint
])
} catch (error) {
console.error('Error inserting device composition:', error)
throw error // Re-throw the error after logging it

// Create insert queries for each deviceType in this endpoint and add them to the insertQueries array
for (let device of deviceTypes) {
insertQueries.push(
dbApi.dbInsert(
db,
`
INSERT INTO DEVICE_COMPOSITION (CODE, ENDPOINT_COMPOSITION_REF, CONFORMANCE, DEVICE_CONSTRAINT)
VALUES (?, ?, ?, ?)
`,
[
parseInt(device, 16), // Convert deviceType to integer, assuming it is hex
endpointCompositionId,
endpointConformance, // Use the endpoint's specific conformance if available
endpointConstraint // Use the endpoint's specific constraint if available
]
)
)
}
}

// Return the promise for executing all queries concurrently
return Promise.all(insertQueries)
}

/**
Expand Down
7 changes: 1 addition & 6 deletions src-electron/zcl/zcl-loader-silabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1665,12 +1665,7 @@ function prepareDeviceType(deviceType) {
if ('endpointComposition' in deviceType) {
try {
ret.compositionType = deviceType.endpointComposition[0].compositionType[0]
ret.conformance =
deviceType.endpointComposition[0].endpoint[0].$.conformance
ret.constraint =
deviceType.endpointComposition[0].endpoint[0].$.constraint
ret.childDeviceId =
deviceType.endpointComposition[0].endpoint[0].deviceType[0]
ret.composition = deviceType.endpointComposition[0]
} catch (error) {
console.error('Error processing endpoint composition:', error)
}
Expand Down

0 comments on commit 3879080

Please sign in to comment.