Skip to content

Commit

Permalink
+ flag for auto disabling UC component when ZCL cluster is disabled
Browse files Browse the repository at this point in the history
+ disableUcComponentOnZclClusterUpdate option flag 

When running embedded as part of Studio, ZAP will enable the
corresponding UC component if an ZCL cluster server/client is enabled.
In reverse, similar behavior will apply.

If there are only a single endpoint, disabling a ZCL cluster will cause
an UC component to be disabled.

If there are multiple endpoints, disabling the last enabled cluster
across all endpoints will trigger the corresponding UC component to be
disabled.

* associate current sessionId with correct packageId, when multiple gen/zcl templates are loaded (e.g. zigbee + matter)
* fix very well hiden dispatch issue
* fix unit test error

BUG: ZAPP-1254
  • Loading branch information
Jing T authored Sep 13, 2023
1 parent 9881ae9 commit 7fbc396
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 32 deletions.
54 changes: 45 additions & 9 deletions src-electron/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,14 @@ async function ensurePackagesAndPopulateSessionOptions(
)
} else if (rows.length == 0) {
env.logError(`No zcl.properties found for session.`)
queryNotification.setNotification(db, "WARNING", `No zcl.properties found for session.`, sessionId, 2, 0)
queryNotification.setNotification(
db,
'WARNING',
`No zcl.properties found for session.`,
sessionId,
2,
0
)
packageId = null
} else {
rows.forEach((p) => {
Expand All @@ -116,8 +123,14 @@ async function ensurePackagesAndPopulateSessionOptions(
env.logWarning(
`${sessionId}, ${zclFile}: Multiple toplevel zcl.properties found. Using the first one from args: ${packageId}`
)
queryNotification.setNotification(db, "WARNING", `${sessionId}, ${zclFile}: Multiple toplevel zcl.properties found. Using the first one from args: ${packageId}`,
sessionId, 2, 0)
queryNotification.setNotification(
db,
'WARNING',
`${sessionId}, ${zclFile}: Multiple toplevel zcl.properties found. Using the first one from args: ${packageId}`,
sessionId,
2,
0
)
}
if (packageId != null) {
return queryPackage.insertSessionPackage(
Expand Down Expand Up @@ -162,14 +175,27 @@ async function ensurePackagesAndPopulateSessionOptions(
env.logWarning(
`Multiple toplevel generation template metafiles found. Using the one from args: ${packageId}`
)
queryNotification.setNotification(db, "WARNING", `Multiple toplevel generation template metafiles found. Using the one from args: ${packageId}`,
sessionId, 2, 0)
queryNotification.setNotification(
db,
'WARNING',
`Multiple toplevel generation template metafiles found. Using the one from args: ${packageId}`,
sessionId,
2,
0
)
} else {
packageId = rows[0].id
env.logWarning(
`Multiple toplevel generation template metafiles found. Using the first one.`
)
queryNotification.setNotification(db, "WARNING", `Multiple toplevel generation template metafiles found. Using the first one.`, sessionId, 2, 0)
queryNotification.setNotification(
db,
'WARNING',
`Multiple toplevel generation template metafiles found. Using the first one.`,
sessionId,
2,
0
)
}
}
if (packageId != null) {
Expand All @@ -183,9 +209,19 @@ async function ensurePackagesAndPopulateSessionOptions(
})
}
if (packageId == null && rows.length > 0) {
// If package id is not resolved and there are gen-template packages available
// then pick the first one available
packageId = rows[0].id
// If package id is not resolved and there are gen-template packages available,
// find one with matching category. if nothing is found, blindly pick the first one available

let packageId
if (selectedZclPropertyPackage) {
const matchBySelectedCategory = rows.find(
(r) => r?.category === selectedZclPropertyPackage.category
);
packageId = matchBySelectedCategory?.id || rows[0].id;
} else {
packageId = rows[0].id
}

return queryPackage.insertSessionPackage(
db,
sessionId,
Expand Down
1 change: 1 addition & 0 deletions src-shared/db-enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ exports.generatorOptions = {
postProcessConditionalFile: 'postProcessConditionalFile',
enabled: 'enabled',
shareClusterStatesAcrossEndpoints: 'shareClusterStatesAcrossEndpoints',
disableUcComponentOnZclClusterUpdate: 'disableUcComponentOnZclClusterUpdate',
}

exports.sessionOption = {
Expand Down
33 changes: 12 additions & 21 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,31 +72,22 @@ async function initLoad(store) {
})
)
promises.push(
store.dispatch(
('zap/loadOptions',
{
key: 'manufacturerCodes',
type: 'object',
})
)
store.dispatch('zap/loadOptions', {
key: 'manufacturerCodes',
type: 'object',
})
)
promises.push(
store.dispatch(
('zap/loadOptions',
{
key: 'profileCodes',
type: 'object',
})
)
store.dispatch('zap/loadOptions', {
key: 'profileCodes',
type: 'object',
})
)
promises.push(
store.dispatch(
('zap/loadOptions',
{
key: 'generator',
type: 'object',
})
)
store.dispatch('zap/loadOptions', {
key: 'generator',
type: 'object',
})
)
promises.push(store.dispatch('zap/loadSessionKeyValues'))

Expand Down
7 changes: 6 additions & 1 deletion src/components/ZclDomainClusterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ export default {
}
},
doesClusterHaveAnyWarnings(clusterData) {
// check if UC component data have been loaded or not.
if (this.$store.state.zap.studio.ucComponents.length == 0) {
return false
}

let id = clusterData.id
if (this.isRequiredClusterMissingForId(id)) return true
if (this.missingRequiredUcComponents(clusterData).length) return true
Expand Down Expand Up @@ -450,7 +455,7 @@ export default {
this.updateSelectedComponentRequest(args)
}

if (removeRoles.length) {
if (removeRoles.length && this.disableUcComponentOnZclClusterUpdate()) {
// send Uc Comp Remove Req if no other endpoints have specific cluster/role enabled.
let endpointsClusterInfo = await Promise.all(
Object.keys(this.endpointId).map((id) =>
Expand Down
27 changes: 27 additions & 0 deletions src/util/common-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,33 @@ export default {
}
},

/**
* While running in Studio / ZAP integration mode,
* this flag determines whether disabling a ZCL cluster (server / client) triggers disabling of a
* corresponding UC component. The disabling will only be issued if
*
* e.g.
* If an SDK config has 1 endpoint, disabling a ZCL cluster will cause
* the corresponding UC component to be disabled.
*
* If an SDK config has 2 or more endpoints, disabling the last enabled cluster
* across all endpoints will trigger the corresponding UC component to be
* disabled.
*/
disableUcComponentOnZclClusterUpdate() {
let res = this.$store.state.zap.genericOptions?.generator?.filter(
(x) =>
x.optionCode ==
DbEnum.generatorOptions.disableUcComponentOnZclClusterUpdate
)

if (res?.length) {
return res[0].optionLabel === 'true'
} else {
return false
}
},

/**
* Enable components by pinging backend, which pings Studio jetty server.
* @param {*} params
Expand Down
24 changes: 24 additions & 0 deletions test/gen-matter-1.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ const dbApi = require('../src-electron/db/db-api')
const queryAttribute = require('../src-electron/db/query-attribute')
const querySession = require('../src-electron/db/query-session')
const queryZcl = require('../src-electron/db/query-zcl')
const queryPackage = require('../src-electron/db/query-package')
const zclLoader = require('../src-electron/zcl/zcl-loader')
const importJs = require('../src-electron/importexport/import')
const testUtil = require('./test-util')
const testQuery = require('./test-query')
const dbEnum = require('../src-shared/db-enum')

let db
let templateContext
Expand Down Expand Up @@ -95,6 +97,28 @@ test(
testUtil.timeout.medium()
)

test(
'Verify specific generator setting for session is present.',
() =>
queryPackage
.getPackagesByType(db, dbEnum.packageType.genTemplatesJson)
.then((packages) => {
expect(packages.length).toBe(1)
let pkgId = packages.shift().id

queryPackage
.selectAllOptionsValues(db, pkgId, 'generator')
.then((generatorConfigurations) => {
expect(generatorConfigurations.length).toBe(1)
expect(generatorConfigurations[0].optionCode).toBe(
'disableUcComponentOnZclClusterUpdate'
)
expect(generatorConfigurations[0].optionLabel).toBe('true')
})
}),
testUtil.timeout.short()
)

test(
`Zap file generation: ${path.relative(__dirname, testFile)}`,
async () => {
Expand Down
5 changes: 4 additions & 1 deletion test/gen-template/matter/gen-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
"code5": "label5"
},
"externalOption": "externalOptions.json",
"cli": "cli.json"
"cli": "cli.json",
"generator": {
"disableUcComponentOnZclClusterUpdate": "true"
}
},
"zcl": {
"event": {
Expand Down

0 comments on commit 7fbc396

Please sign in to comment.