UNPKG

zwave-js

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

124 lines 5.47 kB
import { Powerlevel, PowerlevelTestStatus, } from "@zwave-js/cc"; import { CommandClasses, EncapsulationFlags, ZWaveError, ZWaveErrorCodes, } from "@zwave-js/core"; import { noop, pick } from "@zwave-js/shared"; export function handlePowerlevelSet(driver, node, command) { // Check if the powerlevel is valid if (!(command.powerlevel in Powerlevel)) { throw new ZWaveError(`Invalid powerlevel ${command.powerlevel}.`, ZWaveErrorCodes.CC_OperationFailed); } // CC:0073.01.01.11.001: A supporting node MAY decide not to change its actual Tx configuration. // In any case, the value received in this Command MUST be returned in a Powerlevel Report Command // in response to a Powerlevel Get Command as if the power setting was accepted for the indicated duration. driver.controller.powerlevel = { powerlevel: command.powerlevel, until: command.timeout ? new Date(Date.now() + command.timeout * 1000) : new Date(), }; } export async function handlePowerlevelGet(driver, node, command) { const endpoint = node.getEndpoint(command.endpointIndex) ?? node; // We are being queried, so the device may actually not support the CC, just control it. // Using the commandClasses property would throw in that case const api = endpoint .createAPI(CommandClasses.Powerlevel, false) .withOptions({ // Answer with the same encapsulation as asked, but omit // Supervision as it shouldn't be used for Get-Report flows encapsulationFlags: command.encapsulationFlags & ~EncapsulationFlags.Supervision, }); const { powerlevel, until } = driver.controller.powerlevel; if ( // Setting elapsed until.getTime() < Date.now() // or it is already set to normal power || powerlevel === Powerlevel["Normal Power"]) { await api.reportPowerlevel({ powerlevel: Powerlevel["Normal Power"], }); } else { const timeoutSeconds = Math.max(0, Math.min(Math.round((until.getTime() - Date.now()) / 1000), 255)); await api.reportPowerlevel({ powerlevel, timeout: timeoutSeconds, }); } } export async function handlePowerlevelTestNodeSet(driver, node, command) { // Check if the powerlevel is valid if (!(command.powerlevel in Powerlevel)) { throw new ZWaveError(`Invalid powerlevel ${command.powerlevel}.`, ZWaveErrorCodes.CC_OperationFailed); } else if (command.testFrameCount < 1) { throw new ZWaveError("testFrameCount must be at least 1", ZWaveErrorCodes.CC_OperationFailed); } const endpoint = node.getEndpoint(command.endpointIndex) ?? node; // We are being queried, so the device may actually not support the CC, just control it. // Using the commandClasses property would throw in that case const api = endpoint .createAPI(CommandClasses.Powerlevel, false) .withOptions({ // Answer with the same encapsulation as asked, but omit // Supervision as it shouldn't be used for Get-Report flows encapsulationFlags: command.encapsulationFlags & ~EncapsulationFlags.Supervision, }); try { const acknowledgedFrames = await driver.sendNOPPowerFrames(command.testNodeId, command.powerlevel, command.testFrameCount); // Test results are in, send report void api.sendNodeTestReport({ status: acknowledgedFrames > 0 ? PowerlevelTestStatus.Success : PowerlevelTestStatus.Failed, testNodeId: command.testNodeId, acknowledgedFrames, }).catch(noop); } catch { // Test failed for some reason (e.g. invalid node) void api.sendNodeTestReport({ status: PowerlevelTestStatus.Failed, testNodeId: command.testNodeId, acknowledgedFrames: 0, }).catch(noop); } } export async function handlePowerlevelTestNodeGet(driver, node, command) { const endpoint = node.getEndpoint(command.endpointIndex) ?? node; // We are being queried, so the device may actually not support the CC, just control it. // Using the commandClasses property would throw in that case const api = endpoint .createAPI(CommandClasses.Powerlevel, false) .withOptions({ // Answer with the same encapsulation as asked, but omit // Supervision as it shouldn't be used for Get-Report flows encapsulationFlags: command.encapsulationFlags & ~EncapsulationFlags.Supervision, }); const status = driver.getNOPPowerTestStatus(); if (status) { await api.sendNodeTestReport({ status: status.inProgress ? PowerlevelTestStatus["In Progress"] : status.acknowledgedFrames > 0 ? PowerlevelTestStatus.Success : PowerlevelTestStatus.Failed, ...status, }); } else { // No test was done await api.sendNodeTestReport({ status: PowerlevelTestStatus.Success, testNodeId: 0, acknowledgedFrames: 0, }); } } export function handlePowerlevelTestNodeReport(ctx, node, command) { // Notify listeners node.emit("notification", node, CommandClasses.Powerlevel, pick(command, ["testNodeId", "status", "acknowledgedFrames"])); } //# sourceMappingURL=PowerlevelCC.js.map