Skip to content

Commit

Permalink
fix: checks on sendCommand api (#816)
Browse files Browse the repository at this point in the history
* fix: `sendCommand` api checks

* docs: fix typo

* fix: lint issues

* docs: add link to CCs

* fix: cleaner error
  • Loading branch information
robertsLando authored Mar 4, 2021
1 parent 6bbbef1 commit 92d502a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
5 changes: 4 additions & 1 deletion docs/guide/mqtt.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ This are the available apis:
- `beginFirmwareUpdate(nodeId, fileName, data, target)`: Starts a firmware update of a node. The `fileName` is used to check the extension (used to detect the firmware file type) and data is a `Buffer`
- `abortFirmwareUpdate(nodeId)`: Aborts a firmware update
- `writeValue(valueId, value)`: Write a specific value to a [valueId](https://zwave-js.github.io/node-zwave-js/#/api/valueid?id=valueid)
- `sendCommand(valueId, command, args)`: Send a custom command
- `sendCommand(ctx, command, args)`: Send a custom command.
- `ctx`:context to get the instance to send the command (`{ nodeId: number, endpoint: number, commandClass: number }`)
- `command`: the command name. Check available commands by selecting a CC [here](https://zwave-js.github.io/node-zwave-js/#/api/CCs/index)
- `args`: array of arguments to pass to the command

### Api call examples

Expand Down
38 changes: 22 additions & 16 deletions lib/ZwaveClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -2376,45 +2376,51 @@ ZwaveClient.prototype.hardReset = async function () {

throw Error('Driver is closed')
}

ZwaveClient.prototype.sendCommand = async function (valueId, command, args) {
/**
* Send a command
*
* @param {{nodeId: number, endpoint: number, commandClass: number}} ctx context to get the instance to send the command
* @param {string} command command name
* @param {any[]} args args to pass to `command`
* @returns {Promise<any>}
*/
ZwaveClient.prototype.sendCommand = async function (ctx, command, args) {
if (this.driver && !this.closed) {
if (typeof valueId.nodeId !== 'number') {
if (typeof ctx.nodeId !== 'number') {
throw Error('nodeId must be a number')
}

const error = utils.isValueId(valueId)

if (typeof error === 'string') {
throw Error(error)
}

if (args !== undefined && !Array.isArray(args)) {
throw Error('if args is given, it must be an array')
}

const node = this.getNode(valueId.nodeId)
// get node instance
const node = this.getNode(ctx.nodeId)
if (!node) {
throw Error(`Node ${valueId.nodeId} was not found!`)
throw Error(`Node ${ctx.nodeId} was not found!`)
}
const endpoint = node.getEndpoint(valueId.endpoint || 0)

// get the endpoint instance
const endpoint = node.getEndpoint(ctx.endpoint || 0)
if (!endpoint) {
throw Error(
`Endpoint ${valueId.endpoint} does not exist on Node ${valueId.nodeId}!`
`Endpoint ${ctx.endpoint} does not exist on Node ${ctx.nodeId}!`
)
}
const api = endpoint.commandClasses[valueId.commandClass]

// get the command class instance to send the command
const api = endpoint.commandClasses[ctx.commandClass]
if (!api || !api.isSupported()) {
throw Error(
`Node ${valueId.nodeId} (Endpoint ${valueId.endpoint}) does not support CC ${valueId.commandClass}`
`Node ${ctx.nodeId} (Endpoint ${ctx.endpoint}) does not support CC ${ctx.commandClass} or it has not been implemented yet`
)
} else if (!(command in api)) {
throw Error(
`The command ${command} does not exist for CC ${valueId.commandClass}`
`The command ${command} does not exist for CC ${ctx.commandClass}`
)
}

// send the command with args
const method = api[command].bind(api)
const result = args ? await method(...args) : await method()
return result
Expand Down
6 changes: 5 additions & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,11 @@ export interface ZwaveClient extends EventEmitter {
...args: any
): Promise<{ success: boolean; message: string; result: any; args: any[] }>
writeValue(valueId: Z2MValueId, value: number | string): Promise<void>
sendCommand(valueId: Z2MValueId, command: string, args: any[]): Promise<any>
sendCommand(
ctx: { nodeId: number; endpoint: number; commandClass: number },
command: string,
args: any[]
): Promise<any>
}

export interface Z2MGateway {
Expand Down

0 comments on commit 92d502a

Please sign in to comment.