8000 Endpoint Composition - rootNode on Endpoint 0 (fullFamily) by paulr34 · Pull Request #1423 · project-chip/zap · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Endpoint Composition - rootNode on Endpoint 0 (fullFamily) #1423

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

Merged
merged 5 commits into from
Sep 24, 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
24 changes: 17 additions & 7 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4034,18 +4034,15 @@ If they do not match, it performs an insert with the composition's type.
<a name="module_DB API_ zcl loading queries..getEndpointCompositionIdByCode"></a>

### DB API: zcl loading queries~getEndpointCompositionIdByCode(db, deviceType) ⇒ <code>Promise.&lt;(number\|null)&gt;</code>
Retrieves the endpoint composition ID by device code.

This function executes a SQL query to fetch the endpoint composition ID
associated with a given device code. If the query fails, an error is logged.
Retrieves the endpoint composition ID for a given device type code.

**Kind**: inner method of [<code>DB API: zcl loading queries</code>](#module_DB API_ zcl loading queries)
**Returns**: <code>Promise.&lt;(number\|null)&gt;</code> - The endpoint composition ID or null if not found.
**Returns**: <code>Promise.&lt;(number\|null)&gt;</code> - - A promise that resolves to the endpoint composition ID or null if not found.

| Param | Type | Description |
| --- | --- | --- |
| db | <code>Object</code> | The database connection object. |
| deviceType | <code>Object</code> | The device type object containing the device code. |
| db | <code>\*</code> | The database connection object. |
| deviceType | <code>Object</code> | The device type object containing the code. |

<a name="module_DB API_ zcl loading queries..insertDeviceComposition"></a>

Expand Down Expand Up @@ -15065,6 +15062,7 @@ This module provides the REST API to the user specific data.
* [~httpPostEndpoint(db)](#module_REST API_ endpoint..httpPostEndpoint) ⇒
* [~httpPatchEndpoint(db)](#module_REST API_ endpoint..httpPatchEndpoint) ⇒
* [~httpPostEndpointType(db)](#module_REST API_ endpoint..httpPostEndpointType) ⇒
* [~httpGetInitialComposition(db)](#module_REST API_ endpoint..httpGetInitialComposition) ⇒ <code>function</code>
* [~httpPatchEndpointType(db)](#module_REST API_ endpoint..httpPatchEndpointType) ⇒

<a name="module_REST API_ endpoint..httpDeleteEndpoint"></a>
Expand Down Expand Up @@ -15127,6 +15125,18 @@ HTTP POST endpoint type
| --- | --- |
| db | <code>\*</code> |

<a name="module_REST API_ endpoint..httpGetInitialComposition"></a>

### REST API: endpoint~httpGetInitialComposition(db) ⇒ <code>function</code>
Handles the HTTP GET request to retrieve the root node.

**Kind**: inner method of [<code>REST API: endpoint</code>](#module_REST API_ endpoint)
**Returns**: <code>function</code> - - An async function that handles the HTTP request and response.

| Param | Type | Description |
| --- | --- | --- |
| db | <code>Object</code> | The database connection object. |

<a name="module_REST API_ endpoint..httpPatchEndpointType"></a>

### REST API: endpoint~httpPatchEndpointType(db) ⇒
Expand Down
10 changes: 10 additions & 0 deletions src-electron/db/db-mapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,16 @@ exports.map = {
}
},

rootNode: (x) => {
if (x == null) return undefined
return {
deviceTypeRef: x.DEVICE_TYPE_REF,
code: x.CODE,
name: x.NAME,
type: x.TYPE
}
},

user: (x) => {
if (x == null) return undefined
return {
Expand Down
35 changes: 35 additions & 0 deletions src-electron/db/query-endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
const dbApi = require('./db-api.js')
const bin = require('../util/bin')
const dbMapping = require('./db-mapping.js')
const dbEnum = require('../../src-shared/db-enum.js')

/**
* Returns a promise resolving into all endpoints.
Expand Down Expand Up @@ -59,6 +60,39 @@ ORDER BY E1.ENDPOINT_IDENTIFIER
return rows.map(dbMapping.map.endpoint)
}

/**
* Retrieves the root node device type references from the ENDPOINT_COMPOSITION table
* for the given package IDs.
*
* @param {*} db - The database connection object.
* @param {Array<number>} packageIds - An array of package IDs to query.
* @returns {Promise<Array>} - A promise that resolves to an array of rows containing DEVICE_TYPE_REF.
*/
async function getRootNode(db, packageIds) {
const query = `
SELECT
EC.DEVICE_TYPE_REF,
EC.CODE,
EC.TYPE,
DT.NAME,
DT.PACKAGE_REF
FROM
ENDPOINT_COMPOSITION EC
JOIN
DEVICE_TYPE DT ON EC.DEVICE_TYPE_REF = DT.DEVICE_TYPE_ID
WHERE
EC.TYPE = ? AND
DT.PACKAGE_REF IN (${packageIds.map(() => '?').join(', ')})
`

let result = await dbApi.dbAll(db, query, [
dbEnum.composition.rootNode,
...packageIds
])

return result.map(dbMapping.map.rootNode)
}

/**
* Returns a promise resolving into all endpoints based on the template
* category(eg zigbee/matter).
Expand Down Expand Up @@ -593,3 +627,4 @@ exports.getParentEndpointRef = getParentEndpointRef
exports.getParentEndpointIdentifier = getParentEndpointIdentifier
exports.selectAllEndpointsBasedOnTemplateCategory =
selectAllEndpointsBasedOnTemplateCategory
exports.getRootNode = getRootNode
49 changes: 18 additions & 31 deletions src-electron/db/query-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1029,46 +1029,33 @@ async function insertAtomics(db, packageId, data) {
* @returns A promise resolved with the result of the database insert operation.
*/
async function insertEndpointComposition(db, composition, context) {
try {
if (parseInt(context.mandatoryDeviceTypes, 16) === composition.code) {
return await dbApi.dbInsert(
db,
'INSERT INTO ENDPOINT_COMPOSITION (TYPE, CODE) VALUES (?, ?)',
[dbEnum.composition.mandatoryEndpoint, composition.code]
)
} else {
return await dbApi.dbInsert(
db,
'INSERT INTO ENDPOINT_COMPOSITION (TYPE, CODE) VALUES (?, ?)',
[composition.compositionType, composition.code]
)
}
} catch (error) {
console.error('Error inserting endpoint composition:', error)
throw error // Re-throw the error after logging it
if (parseInt(context.mandatoryDeviceTypes, 16) === composition.code) {
return dbApi.dbInsert(
db,
'INSERT INTO ENDPOINT_COMPOSITION (TYPE, CODE) VALUES (?, ?)',
[dbEnum.composition.rootNode, composition.code]
)
} else {
return dbApi.dbInsert(
db,
'INSERT INTO ENDPOINT_COMPOSITION (TYPE, CODE) VALUES (?, ?)',
[composition.compositionType, composition.code]
)
}
}

/**
* Retrieves the endpoint composition ID by device code.
* Retrieves the endpoint composition ID for a given device type code.
*
* This function executes a SQL query to fetch the endpoint composition ID
* associated with a given device code. If the query fails, an error is logged.
*
* @param {Object} db - The database connection object.
* @param {Object} deviceType - The device type object containing the device code.
* @returns {Promise<number|null>} The endpoint composition ID or null if not found.
* @param {*} db - The database connection object.
* @param {Object} deviceType - The device type object containing the code.
* @returns {Promise<number|null>} - A promise that resolves to the endpoint composition ID or null if not found.
*/
async function getEndpointCompositionIdByCode(db, deviceType) {
const query =
'SELECT ENDPOINT_COMPOSITION_ID FROM ENDPOINT_COMPOSITION WHERE CODE = ?'
try {
const result = await dbApi.dbGet(db, query, [deviceType.code])
return result ? result.ENDPOINT_COMPOSITION_ID : null
} catch (error) {
console.error('Error retrieving endpoint composition ID:', error)
return null
}
const result = await dbApi.dbGet(db, query, [deviceType.code])
return result ? result.ENDPOINT_COMPOSITION_ID : null
}

/**
Expand Down
27 changes: 26 additions & 1 deletion src-electron/rest/endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const queryEndpointType = require('../db/query-endpoint-type.js')
const queryEndpoint = require('../db/query-endpoint.js')
const queryConfig = require('../db/query-config.js')
const querySession = require('../db/query-session.js')
const queryPackage = require('../db/query-package.js')
const validation = require('../validation/validation.js')
const restApi = require('../../src-shared/rest-api.js')
const notification = require('../db/query-session-notification.js')
Expand Down Expand Up @@ -201,6 +202,25 @@ function httpPostEndpointType(db) {
}
}

/**
* Handles the HTTP GET request to retrieve the root node.
*
* @param {Object} db - The database connection object.
* @returns {Function} - An async function that handles the HTTP request and response.
*/
function httpGetInitialComposition(db) {
return async (request, response) => {
let sessionId = request.zapSessionId
let packages = await queryPackage.getPackageSessionPackagePairBySessionId(
db,
sessionId
)
let packageIds = packages.map((item) => item.pkg.id)
let rootNode = await queryEndpoint.getRootNode(db, packageIds)
response.status(StatusCodes.OK).json(rootNode[0])
}
}

/**
* HTTP POST: endpoint type update
*
Expand Down Expand Up @@ -234,7 +254,12 @@ function httpPatchEndpointType(db) {
})
}
}

exports.get = [
{
uri: restApi.uri.loadComposition,
callback: httpGetInitialComposition
}
]
exports.post = [
{
uri: restApi.uri.endpoint,
Expand Down
9 changes: 8 additions & 1 deletion src-shared/db-enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ exports.packageType = {
jsonExtension: 'json-extension'
}

exports.rootNode = {
endpointId: 0,
getParentEndpointIdentifier: null,
deviceVersion: 1,
type: 'rootNode'
}

exports.packageOptionCategory = {
manufacturerCodes: 'manufacturerCodes',
typeMap: 'typeMap',
Expand Down Expand Up @@ -78,7 +85,7 @@ exports.storageOption = {
exports.composition = {
fullFamily: 'fullFamily',
tree: 'tree',
mandatoryEndpoint: 'mandatoryEndpoint'
rootNode: 'rootNode'
}

exports.zclType = {
Expand Down
3 changes: 2 additions & 1 deletion src-shared/rest-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ const uri = {
sessionCreate: '/zcl/sessionCreate',
reloadSession: '/zcl/reloadSession',
init: '/init',
forcedExternal: '/zcl/forcedExternal'
forcedExternal: '/zcl/forcedExternal',
loadComposition: '/zcl/loadComposition'
}

const uiMode = {
Expand Down
49 changes: 48 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { defineComponent } from 'vue'
import { QSpinnerGears } from 'quasar'
import ZclTour from './tutorials/ZclTour.vue'
import CommonMixin from './util/common-mixin'
import uiOptions from './util/ui-options'

const rendApi = require(`../src-shared/rend-api.js`)
const restApi = require(`../src-shared/rest-api.js`)
Expand Down Expand Up @@ -136,8 +137,18 @@ export default defineComponent({
components: {
ZclTour
},
mixins: [CommonMixin],
mixins: [CommonMixin, uiOptions],
computed: {
endpointType: {
get() {
return this.$store.state.zap.endpointView.endpointType
}
},
endpointDeviceTypeRef: {
get() {
return this.$store.state.zap.endpointTypeView.deviceTypeRef
}
},
showExceptionIcon() {
return this.$store.state.zap.showExceptionIcon
},
Expand Down Expand Up @@ -219,6 +230,39 @@ export default defineComponent({
this.$store.dispatch('zap/setDefaultUiMode', 'general')
this.$store.commit('zap/toggleShowExceptionIcon', false)
},
async loadInitialEndpoints() {
let endpoint = await this.$store.dispatch('zap/loadComposition')
if (endpoint) {
this.$store.dispatch('zap/updateSelectedEndpointType', {
endpointType: this.endpointType[endpoint.id],
deviceTypeRef:
this.endpointDeviceTypeRef[this.endpointType[endpoint.id]]
})
this.$store.dispatch('zap/updateClusters')
let info = await this.$store.dispatch(
'zap/endpointTypeClustersInfo',
this.endpointType[endpoint.id]
)
if (info.data) {
const clusterStates = info.data
const enabledClusterStates = clusterStates.filter((x) => x.enabled)
for (const states of enabledClusterStates) {
const { endpointTypeRef, clusterRef, side, enabled } = states

const arg = {
side: [side],
clusterId: clusterRef,
added: enabled
}

console.log(`Enabling UC component ${JSON.stringify(arg)}`)
this.updateSelectedComponentRequest(arg)
}
}
this.$store.dispatch('zap/updateSelectedEndpoint', endpoint.id)
this.$store.commit('zap/toggleEndpointModal', false)
}
},
getAppData() {
if (this.$serverGet != null) {
this.$serverGet(restApi.uri.uiOptions).then((res) => {
Expand Down Expand Up @@ -283,6 +327,9 @@ export default defineComponent({

// load initial UC component state
this.$store.dispatch(`zap/loadUcComponentState`)
if (query[`newConfig`]) {
this.loadInitialEndpoints()
}

// handles UC component state change events
this.$onWebSocket(
Expand Down
3 changes: 2 additions & 1 deletion src/components/ZclClusterManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ export default {
this.$store.dispatch('zap/setFilterString', filterString)
},
updateDeviceTypeFeatures() {
let deviceTypeRefs = this.endpointDeviceTypeRef[this.selectedEndpointId]
let deviceTypeRefs =
this.endpointDeviceTypeRef[this.selectedEndpointTypeId]
this.$store.dispatch(
'zap/updateSelectedDeviceTypeFeatures',
deviceTypeRefs
Expand Down
10 changes: 4 additions & 6 deletions src/components/ZclCreateModifyEndpoint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,6 @@ export default {
return this.$store.state.zap.endpointTypeView.deviceVersion
}
},
endpointDeviceTypeRef: {
get() {
return this.$store.state.zap.endpointTypeView.deviceTypeRef
}
},
endpointDeviceId: {
get() {
return this.$store.state.zap.endpointTypeView.deviceIdentifier
Expand Down Expand Up @@ -693,7 +688,10 @@ export default {
}
})

this.$store.dispatch('zap/updateSelectedEndpoint', res.id)
this.$store.dispatch(
'zap/updateSelectedEndpoint',
res.endpointType
)
this.$store.commit('zap/toggleEndpointModal', false)
})
})
Expand Down
Loading
Loading
0