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

Enable Multiple Endpoints and Device Types in Device Composition Insertion #1489

Merged
merged 4 commits into from
Nov 22, 2024
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
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
Loading