blob: ec37740f8e010a31f274e30b9329d165e25cb029 [file] [log] [blame]
/**
*
* 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 contains the API functions for the post-load
* scripting functionality.
*
* @module JS API: post-import.
*/
const queryEndpoint = require('../db/query-endpoint.js')
const queryConfig = require('../db/query-config.js')
const dbEnum = require('../../src-shared/db-enum.js')
const querySessionZcl = require('../db/query-session-zcl.js')
const restApi = require('../../src-shared/rest-api.js')
/**
* Prints a text to console.
*
* @param {*} text
*/
function print(text) {
console.log(text)
}
/**
* Prints error message to the console.
*
* @param {*} text
*/
function printError(text) {
console.log(`⛔ SCRIPT API ERROR: ${text}`)
}
/**
* Returns an array of endpoints.
*
* @param {*} context
*/
async function endpoints(context) {
return queryEndpoint.selectAllEndpoints(
context.db,
context.sessionId,
context.script.category
)
}
/**
* Deletes an endpoint
*
* @param {*} context
* @param {*} endpoint
*/
async function deleteEndpoint(context, endpoint) {
return queryEndpoint.deleteEndpoint(context.db, endpoint.id)
}
/**
* Returns an array of clusters defined on a given endpoint.
*
* @param {*} context
* @param {*} endpoint
*/
async function clusters(context, endpoint) {
return queryEndpoint.selectEndpointClusters(
context.db,
endpoint.endpointTypeRef
)
}
/**
* Returns an array of attributes for a given cluster.
* The cluster input is required to come from a script-api in this module.
*
* @param {*} context
* @param {*} endpoint
* @param {*} cluster
*/
async function attributes(context, endpoint, cluster) {
return queryEndpoint.selectEndpointClusterAttributes(
context.db,
cluster.clusterId,
cluster.side,
endpoint.endpointTypeRef
)
}
/**
* Returns an array of commands for a given cluster
* The clusters input is required to come from a script-api in this module.
*
* @param {*} context
* @param {*} endpoint
* @param {*} cluster
*/
async function commands(context, endpoint, cluster) {
return queryEndpoint.selectEndpointClusterCommands(
context.db,
cluster.clusterId,
endpoint.endpointTypeRef
)
}
/**
* Returns array of function names available in this module.
*/
function functions() {
return Object.keys(exports)
}
/**
* Returns the session id in the context.
*
* @param {*} context
* @returns sessionId
*/
function sessionId(context) {
return context.sessionId
}
/**
*
* @returns dbEnum
*/
function dbEnums() {
return dbEnum
}
/**
* Returns all available clusters.
*
* @param {*} context
* @returns all available clusters
*/
async function availableClusters(context) {
return querySessionZcl.selectAllSessionClusters(context.db, context.sessionId)
}
/**
* Finds the cluster database primary key from code,manufacturing code, and context.
* Note that by default, a standard ZCL library cluster will have manufacturing code of null
* in the database.
* @param {*} context
* @param {*} code
* @param {*} mfgCode
* @returns promise of cluster details
*/
async function findCluster(context, code, mfgCode = null) {
return querySessionZcl.selectSessionClusterByCode(
context.db,
context.sessionId,
code,
mfgCode
)
}
/**
* find attribute using the given arguments.
*
* @param {*} context
* @param {*} clusterCode
* @param {*} side
* @param {*} attributeCode
* @param {*} mfgCode
* @returns promise of attribute details
*/
async function findAttribute(
context,
clusterCode,
side,
attributeCode,
mfgCode = null
) {
return querySessionZcl.selectSessionAttributeByCode(
context.db,
context.sessionId,
clusterCode,
side,
attributeCode,
mfgCode
)
}
/**
* find command using the given arguments.
*
* @param {*} context
* @param {*} clusterCode
* @param {*} commandCode
* @param {*} source
* @returns promise of command details
*/
async function findCommand(context, clusterCode, commandCode, source) {
return querySessionZcl.selectSessionCommandByCode(
context.db,
context.sessionId,
clusterCode,
commandCode,
source
)
}
/**
* Non-public, common function to modify cluster.
*
* @param {*} context
* @param {*} endpoint
* @param {*} code
* @param {*} side
* @param {*} enabled
* @returns promise of an updated or inserted cluster
*/
async function modifyCluster(context, endpoint, code, side, enabled) {
let cluster = await findCluster(context, code)
if (cluster == null) {
printError(`Cluster 0x${code.toString(16)} does not exist.`)
return null
}
return queryConfig.insertOrReplaceClusterState(
context.db,
endpoint.endpointTypeRef,
cluster.id,
side,
enabled
)
}
/**
* Non-public, common function to modify attribute.
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} attributeCode
* @param {*} side
* @param {*} enable
* @returns promise of an updated or inserted attribute
*/
async function modifyAttribute(
context,
endpoint,
clusterCode,
attributeCode,
side,
enable
) {
let cluster = await findCluster(context, clusterCode)
if (cluster == null) {
printError(`Cluster 0x${clusterCode.toString(16)} does not exist.`)
return null
}
let attribute = await findAttribute(context, clusterCode, side, attributeCode)
if (attribute == null) {
printError(
`Attribute 0x${attributeCode.toString(
16
)} in cluster 0x${clusterCode.toString(16)} does not exist.`
)
return null
}
let params = [
{
key: restApi.updateKey.attributeSelected,
value: enable
}
]
return queryConfig.insertOrUpdateAttributeState(
context.db,
endpoint.endpointTypeRef,
cluster.id,
side,
attribute.id,
params,
attribute.reportMinInterval,
attribute.reportMaxInterval,
attribute.reportableChange
)
}
/**
* Update an attribute with given parameters.
*
* @param {*} context
* @param {*} endpoint
* @param {*} cluster
* @param {*} attribute
* @param {*} params
* @returns promise of an updated or inserted attribute with parameters provided
*/
async function updateAttribute(context, endpoint, cluster, attribute, params) {
return queryConfig.insertOrUpdateAttributeState(
context.db,
endpoint.endpointTypeRef,
cluster.id,
attribute.side,
attribute.id,
params,
attribute.reportMinInterval,
attribute.reportMaxInterval,
attribute.reportableChange
)
}
/**
* Non-public, common function to modify command.
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} commandCode
* @param {*} source
* @param {*} isIncoming
* @param {*} enable
* @returns promise of an updated or inserted command
*/
async function modifyCommand(
context,
endpoint,
clusterCode,
commandCode,
source,
isIncoming,
enable
) {
let cluster = await findCluster(context, clusterCode)
if (cluster == null) {
printError(`Cluster 0x${clusterCode.toString(16)} does not exist.`)
return null
}
let command = await findCommand(context, clusterCode, commandCode, source)
if (command == null) {
printError(
`Command 0x${commandCode.toString(
16
)} in cluster 0x${clusterCode.toString(16)} does not exist.`
)
return null
}
return queryConfig.insertOrUpdateCommandState(
context.db,
endpoint.endpointTypeRef,
cluster.id,
command.source,
command.id,
enable ? 1 : 0,
isIncoming
)
}
/**
* Disables the client cluster on an endpoint.
* @param {*} context
* @param {*} endpoint
* @param {*} code
*/
async function disableClientCluster(context, endpoint, code) {
return modifyCluster(context, endpoint, code, dbEnum.side.client, false)
}
/**
* Disables the server cluster on an endpoint.
* @param {*} context
* @param {*} endpoint
* @param {*} code
*/
async function disableServerCluster(context, endpoint, code) {
return modifyCluster(context, endpoint, code, dbEnum.side.server, false)
}
/**
* Enables the client cluster on an endpoint.
* @param {*} context
* @param {*} endpoint
* @param {*} code
*/
async function enableClientCluster(context, endpoint, code) {
return modifyCluster(context, endpoint, code, dbEnum.side.client, true)
}
/**
* Enables the server cluster on an endpoint.
* @param {*} context
* @param {*} endpoint
* @param {*} code
*/
async function enableServerCluster(context, endpoint, code) {
return modifyCluster(context, endpoint, code, dbEnum.side.server, true)
}
/**
* Disable client attribute.
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} attributeCode
*/
async function disableClientAttribute(
context,
endpoint,
clusterCode,
attributeCode
) {
return modifyAttribute(
context,
endpoint,
clusterCode,
attributeCode,
dbEnum.side.client,
false
)
}
/**
* Enable client attribute.
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} attributeCode
*/
async function enableClientAttribute(
context,
endpoint,
clusterCode,
attributeCode
) {
return modifyAttribute(
context,
endpoint,
clusterCode,
attributeCode,
dbEnum.side.client,
true
)
}
/**
* Disable server attribute.
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} attributeCode
*/
async function disableServerAttribute(
context,
endpoint,
clusterCode,
attributeCode
) {
return modifyAttribute(
context,
endpoint,
clusterCode,
attributeCode,
dbEnum.side.server,
false
)
}
/**
* Enable server attribute.
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} attributeCode
*/
async function enableServerAttribute(
context,
endpoint,
clusterCode,
attributeCode
) {
return modifyAttribute(
context,
endpoint,
clusterCode,
attributeCode,
dbEnum.side.server,
true
)
}
/**
* Disable incoming commands.
* Source should be derived from dbEnums().source.client/server
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} commandCode
* @param {*} source
*/
async function disableIncomingCommand(
context,
endpoint,
clusterCode,
commandCode,
source
) {
return modifyCommand(
context,
endpoint,
clusterCode,
commandCode,
source,
true,
false
)
}
/**
* Enable incoming commands.
* Source should be derived from dbEnums().source.client/server
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} commandCode
* @param {*} source
*/
async function enableIncomingCommand(
context,
endpoint,
clusterCode,
commandCode,
source
) {
return modifyCommand(
context,
endpoint,
clusterCode,
commandCode,
source,
true,
true
)
}
/**
* Disable outgoing commands.
* Source should be derived from dbEnums().source.client/server
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} commandCode
* @param {*} source
*/
async function disableOutgoingCommand(
context,
endpoint,
clusterCode,
commandCode,
source
) {
return modifyCommand(
context,
endpoint,
clusterCode,
commandCode,
source,
false,
false
)
}
/**
* Enable outgoing commands.
* Source should be derived from dbEnums().source.client/server
*
* @param {*} context
* @param {*} endpoint
* @param {*} clusterCode
* @param {*} commandCode
* @param {*} source
*/
async function enableOutgoingCommand(
context,
endpoint,
clusterCode,
commandCode,
source
) {
return modifyCommand(
context,
endpoint,
clusterCode,
commandCode,
source,
false,
true
)
}
exports.availableClusters = availableClusters
exports.print = print
exports.functions = functions
exports.sessionId = sessionId
exports.dbEnums = dbEnums
exports.endpoints = endpoints
exports.deleteEndpoint = deleteEndpoint
exports.clusters = clusters
exports.attributes = attributes
exports.commands = commands
exports.findCluster = findCluster
exports.disableClientCluster = disableClientCluster
exports.disableServerCluster = disableServerCluster
exports.enableClientCluster = enableClientCluster
exports.enableServerCluster = enableServerCluster
exports.disableClientAttribute = disableClientAttribute
exports.enableClientAttribute = enableClientAttribute
exports.disableServerAttribute = disableServerAttribute
exports.enableServerAttribute = enableServerAttribute
exports.disableClientAttribute = disableClientAttribute
exports.enableClientAttribute = enableClientAttribute
exports.disableServerAttribute = disableServerAttribute
exports.enableServerAttribute = enableServerAttribute
exports.disableIncomingCommand = disableIncomingCommand
exports.enableIncomingCommand = enableIncomingCommand
exports.disableOutgoingCommand = disableOutgoingCommand
exports.enableOutgoingCommand = enableOutgoingCommand
exports.updateAttribute = updateAttribute
// Constants that are used a lot
exports.client = dbEnum.source.client
exports.server = dbEnum.source.server