UNPKG

inventoresed

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

119 lines (108 loc) 3 kB
import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core"; import { clamp } from "alcalzone-shared/math"; import type { SetbackSpecialState, SetbackState, Switchpoint, Timezone, } from "./_Types"; export const setbackSpecialStateValues: Record<SetbackSpecialState, number> = { "Frost Protection": 0x79, "Energy Saving": 0x7a, Unused: 0x7f, }; /** * @publicAPI * Encodes a setback state to use in a ThermostatSetbackCC */ export function encodeSetbackState(state: SetbackState): number { if (typeof state === "string") return setbackSpecialStateValues[state]; state = clamp(state, -12.8, 12); return Math.round(state * 10); } /** * @publicAPI * Decodes a setback state used in a ThermostatSetbackCC */ export function decodeSetbackState(val: number): SetbackState | undefined { if (val > 120) { // Special state, try to look it up const foundEntry = Object.entries(setbackSpecialStateValues).find( ([, v]) => val === v, ); if (!foundEntry) return; return foundEntry[0] as SetbackSpecialState; } else { return val / 10; } } /** * @publicAPI * Decodes a switch point used in a ClimateControlScheduleCC */ export function decodeSwitchpoint(data: Buffer): Switchpoint { return { hour: data[0] & 0b000_11111, minute: data[1] & 0b00_111111, state: decodeSetbackState(data[2]), }; } /** * @publicAPI * Encodes a switch point to use in a ClimateControlScheduleCC */ export function encodeSwitchpoint(point: Switchpoint): Buffer { if (point.state == undefined) throw new ZWaveError( "The given Switchpoint is not valid!", ZWaveErrorCodes.CC_Invalid, ); return Buffer.from([ point.hour & 0b000_11111, point.minute & 0b00_111111, encodeSetbackState(point.state), ]); } /** * @publicAPI * Decodes timezone information used in time related CCs */ export function parseTimezone(data: Buffer): Timezone { const hourSign = !!(data[0] & 0b1000_0000); const hour = data[0] & 0b0111_1111; const minute = data[1]; const standardOffset = (hourSign ? -1 : 1) * (hour * 60 + minute); const deltaSign = !!(data[2] & 0b1000_0000); const deltaMinutes = data[2] & 0b0111_1111; const dstOffset = standardOffset + (deltaSign ? -1 : 1) * deltaMinutes; return { standardOffset, dstOffset, }; } /** * @publicAPI * Decodes timezone information used in time related CCs */ export function encodeTimezone(tz: Timezone): Buffer { if ( Math.abs(tz.standardOffset) >= 24 * 60 || Math.abs(tz.dstOffset) >= 24 * 60 ) { throw new ZWaveError( "The given timezone is not valid!", ZWaveErrorCodes.CC_Invalid, ); } const minutes = Math.abs(tz.standardOffset) % 60; const hour = Math.floor(Math.abs(tz.standardOffset) / 60); const hourSign = tz.standardOffset < 0 ? 1 : 0; const delta = tz.dstOffset - tz.standardOffset; const deltaMinutes = Math.abs(delta); const deltaSign = delta < 0 ? 1 : 0; return Buffer.from([ (hourSign << 7) | (hour & 0b0111_1111), minutes, (deltaSign << 7) | (deltaMinutes & 0b0111_1111), ]); }