diff --git a/dist/commonjs/driver.d.ts b/dist/commonjs/driver.d.ts index 76d12bb..b846412 100644 --- a/dist/commonjs/driver.d.ts +++ b/dist/commonjs/driver.d.ts @@ -45,9 +45,11 @@ export declare const turnOff: (device: Device) => void; * Sets the temperature of your Logitech Litra device * * @param {Device} device The device to set the temperature of - * @param {number} temperatureInKelvin The temperature to set in Kelvin. Use the - * `getMinimumTemperatureInKelvinForDevice` and `getMaximumTemperatureInKelvinForDevice` - * functions to get the minimum and maximum temperature for your device. + * @param {number} temperatureInKelvin The temperature to set in Kelvin. Only + * multiples of 100 between the device's minimum and maximum temperatures + * are allowed. Use the `getMinimumTemperatureInKelvinForDevice` and + * `getMaximumTemperatureInKelvinForDevice` functions to get the minimum + * and maximum temperature for your device. */ export declare const setTemperatureInKelvin: (device: Device, temperatureInKelvin: number) => void; /** @@ -95,6 +97,13 @@ export declare const getMinimumTemperatureInKelvinForDevice: (device: Device) => * @returns {number} The maximum temperature in Kelvin supported by the device */ export declare const getMaximumTemperatureInKelvinForDevice: (device: Device) => number; +/** + * Gets all temperature values in Kelvin supported by a device + * + * @param {Device} device The device to check the allowed temperatures for + * @returns {number[]} The temperature values in Kelvin supported by the device + */ +export declare const getAllowedTemperaturesInKelvinForDevice: (device: Device) => number[]; /** * Gets the name of a device * diff --git a/dist/commonjs/driver.js b/dist/commonjs/driver.js index 3cf86a7..d1a8a95 100644 --- a/dist/commonjs/driver.js +++ b/dist/commonjs/driver.js @@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getNameForDevice = exports.getMaximumTemperatureInKelvinForDevice = exports.getMinimumTemperatureInKelvinForDevice = exports.getMaximumBrightnessInLumenForDevice = exports.getMinimumBrightnessInLumenForDevice = exports.setBrightnessPercentage = exports.setBrightnessInLumen = exports.setTemperatureInKelvin = exports.turnOff = exports.turnOn = exports.findDevices = exports.findDevice = exports.DeviceType = void 0; +exports.getNameForDevice = exports.getAllowedTemperaturesInKelvinForDevice = exports.getMaximumTemperatureInKelvinForDevice = exports.getMinimumTemperatureInKelvinForDevice = exports.getMaximumBrightnessInLumenForDevice = exports.getMinimumBrightnessInLumenForDevice = exports.setBrightnessPercentage = exports.setBrightnessInLumen = exports.setTemperatureInKelvin = exports.turnOff = exports.turnOn = exports.findDevices = exports.findDevice = exports.DeviceType = void 0; const node_hid_1 = __importDefault(require("node-hid")); const utils_1 = require("./utils"); var DeviceType; @@ -25,13 +25,10 @@ const MAXIMUM_BRIGHTNESS_IN_LUMEN_BY_DEVICE_TYPE = { [DeviceType.LitraGlow]: 250, [DeviceType.LitraBeam]: 400, }; -const MINIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE = { - [DeviceType.LitraGlow]: 2700, - [DeviceType.LitraBeam]: 2700, -}; -const MAXIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE = { - [DeviceType.LitraGlow]: 6500, - [DeviceType.LitraBeam]: 6500, +const MULTIPLES_OF_100_BETWEEN_2700_AND_6500 = (0, utils_1.multiplesWithinRange)(100, 2700, 6500); +const ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE = { + [DeviceType.LitraGlow]: MULTIPLES_OF_100_BETWEEN_2700_AND_6500, + [DeviceType.LitraBeam]: MULTIPLES_OF_100_BETWEEN_2700_AND_6500, }; const NAME_BY_DEVICE_TYPE = { [DeviceType.LitraGlow]: 'Logitech Litra Glow', @@ -103,9 +100,11 @@ exports.turnOff = turnOff; * Sets the temperature of your Logitech Litra device * * @param {Device} device The device to set the temperature of - * @param {number} temperatureInKelvin The temperature to set in Kelvin. Use the - * `getMinimumTemperatureInKelvinForDevice` and `getMaximumTemperatureInKelvinForDevice` - * functions to get the minimum and maximum temperature for your device. + * @param {number} temperatureInKelvin The temperature to set in Kelvin. Only + * multiples of 100 between the device's minimum and maximum temperatures + * are allowed. Use the `getMinimumTemperatureInKelvinForDevice` and + * `getMaximumTemperatureInKelvinForDevice` functions to get the minimum + * and maximum temperature for your device. */ const setTemperatureInKelvin = (device, temperatureInKelvin) => { if (!Number.isInteger(temperatureInKelvin)) { @@ -113,9 +112,9 @@ const setTemperatureInKelvin = (device, temperatureInKelvin) => { } const minimumTemperature = (0, exports.getMinimumTemperatureInKelvinForDevice)(device); const maximumTemperature = (0, exports.getMaximumTemperatureInKelvinForDevice)(device); - if (temperatureInKelvin < minimumTemperature || - temperatureInKelvin > maximumTemperature) { - throw `Provided temperature must be between ${minimumTemperature} and ${maximumTemperature} for this device`; + const allowedTemperatures = (0, exports.getAllowedTemperaturesInKelvinForDevice)(device); + if (!allowedTemperatures.includes(temperatureInKelvin)) { + throw `Provided temperature must be a multiple of 100 between ${minimumTemperature} and ${maximumTemperature} for this device`; } device.hid.write((0, utils_1.padRight)([0x11, 0xff, 0x04, 0x9c, ...(0, utils_1.integerToBytes)(temperatureInKelvin)], 20, 0x00)); }; @@ -201,7 +200,7 @@ exports.getMaximumBrightnessInLumenForDevice = getMaximumBrightnessInLumenForDev * @returns {number} The minimum temperature in Kelvin supported by the device */ const getMinimumTemperatureInKelvinForDevice = (device) => { - return MINIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE[device.type]; + return ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE[device.type][0]; }; exports.getMinimumTemperatureInKelvinForDevice = getMinimumTemperatureInKelvinForDevice; /** @@ -211,9 +210,20 @@ exports.getMinimumTemperatureInKelvinForDevice = getMinimumTemperatureInKelvinFo * @returns {number} The maximum temperature in Kelvin supported by the device */ const getMaximumTemperatureInKelvinForDevice = (device) => { - return MAXIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE[device.type]; + const allowedTemperatures = ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE[device.type]; + return allowedTemperatures[allowedTemperatures.length - 1]; }; exports.getMaximumTemperatureInKelvinForDevice = getMaximumTemperatureInKelvinForDevice; +/** + * Gets all temperature values in Kelvin supported by a device + * + * @param {Device} device The device to check the allowed temperatures for + * @returns {number[]} The temperature values in Kelvin supported by the device + */ +const getAllowedTemperaturesInKelvinForDevice = (device) => { + return ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE[device.type]; +}; +exports.getAllowedTemperaturesInKelvinForDevice = getAllowedTemperaturesInKelvinForDevice; /** * Gets the name of a device * diff --git a/dist/commonjs/utils.d.ts b/dist/commonjs/utils.d.ts index 3131c12..271040d 100644 --- a/dist/commonjs/utils.d.ts +++ b/dist/commonjs/utils.d.ts @@ -30,3 +30,20 @@ export declare const integerToBytes: (integer: number) => [number, number]; * @returns {number} The value at the given percentage */ export declare const percentageWithinRange: (percentage: number, startRange: number, endRange: number) => number; +/** + * Finds all multiples of a given integer within a range. The returned + * list of multiples may or may not include the values at the start and + * the end of the range. + * + * For example: + * - the multiples of 3 within the range 0 to 10 are 0, 3, 6, 9 + * - the multiples of 3 within the range 1 to 10 are 3, 6, 9 + * - the multiples of 5 within the range 0 to 20 are 0, 5, 10, 15, 20 + * - the multiples of 3 within the range 10 to 20 are 12, 15, 18 + * + * @param {number} multiplesOf The integer to find multiples of + * @param {number} startRange The integer at the start of the range + * @param {number} endRange The integer at the end of the range + * @returns {number[]} An array of all the multiples + */ +export declare const multiplesWithinRange: (multiplesOf: number, startRange: number, endRange: number) => number[]; diff --git a/dist/commonjs/utils.js b/dist/commonjs/utils.js index e3d43df..9b7b5c3 100644 --- a/dist/commonjs/utils.js +++ b/dist/commonjs/utils.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.percentageWithinRange = exports.integerToBytes = exports.padRight = void 0; +exports.multiplesWithinRange = exports.percentageWithinRange = exports.integerToBytes = exports.padRight = void 0; /** * Pads the provided array to a specified length, adding the required * number of occurences of the padding element to the end of the array. @@ -54,3 +54,35 @@ const percentageWithinRange = (percentage, startRange, endRange) => { return Math.round(Math.ceil(((percentage - 1) / (100 - 1)) * (endRange - startRange) + startRange)); }; exports.percentageWithinRange = percentageWithinRange; +/** + * Finds all multiples of a given integer within a range. The returned + * list of multiples may or may not include the values at the start and + * the end of the range. + * + * For example: + * - the multiples of 3 within the range 0 to 10 are 0, 3, 6, 9 + * - the multiples of 3 within the range 1 to 10 are 3, 6, 9 + * - the multiples of 5 within the range 0 to 20 are 0, 5, 10, 15, 20 + * - the multiples of 3 within the range 10 to 20 are 12, 15, 18 + * + * @param {number} multiplesOf The integer to find multiples of + * @param {number} startRange The integer at the start of the range + * @param {number} endRange The integer at the end of the range + * @returns {number[]} An array of all the multiples + */ +const multiplesWithinRange = (multiplesOf, startRange, endRange) => { + if (!Number.isInteger(multiplesOf)) { + throw 'Provided value for `multiplesOf` must be an integer'; + } + if (!Number.isInteger(startRange)) { + throw 'Provided value for `startRange` must be an integer'; + } + if (!Number.isInteger(endRange)) { + throw 'Provided value for `endRange` must be an integer'; + } + const inclusiveIntegersWithinRange = Array(endRange - startRange + 1) + .fill([]) + .map((_, idx) => startRange + idx); + return inclusiveIntegersWithinRange.filter((integer) => integer % multiplesOf === 0); +}; +exports.multiplesWithinRange = multiplesWithinRange; diff --git a/dist/esm/driver.d.ts b/dist/esm/driver.d.ts index 76d12bb..b846412 100644 --- a/dist/esm/driver.d.ts +++ b/dist/esm/driver.d.ts @@ -45,9 +45,11 @@ export declare const turnOff: (device: Device) => void; * Sets the temperature of your Logitech Litra device * * @param {Device} device The device to set the temperature of - * @param {number} temperatureInKelvin The temperature to set in Kelvin. Use the - * `getMinimumTemperatureInKelvinForDevice` and `getMaximumTemperatureInKelvinForDevice` - * functions to get the minimum and maximum temperature for your device. + * @param {number} temperatureInKelvin The temperature to set in Kelvin. Only + * multiples of 100 between the device's minimum and maximum temperatures + * are allowed. Use the `getMinimumTemperatureInKelvinForDevice` and + * `getMaximumTemperatureInKelvinForDevice` functions to get the minimum + * and maximum temperature for your device. */ export declare const setTemperatureInKelvin: (device: Device, temperatureInKelvin: number) => void; /** @@ -95,6 +97,13 @@ export declare const getMinimumTemperatureInKelvinForDevice: (device: Device) => * @returns {number} The maximum temperature in Kelvin supported by the device */ export declare const getMaximumTemperatureInKelvinForDevice: (device: Device) => number; +/** + * Gets all temperature values in Kelvin supported by a device + * + * @param {Device} device The device to check the allowed temperatures for + * @returns {number[]} The temperature values in Kelvin supported by the device + */ +export declare const getAllowedTemperaturesInKelvinForDevice: (device: Device) => number[]; /** * Gets the name of a device * diff --git a/dist/esm/driver.js b/dist/esm/driver.js index f2cb90e..d9f5e3c 100644 --- a/dist/esm/driver.js +++ b/dist/esm/driver.js @@ -1,5 +1,5 @@ import HID from 'node-hid'; -import { integerToBytes, padRight, percentageWithinRange } from './utils'; +import { integerToBytes, multiplesWithinRange, padRight, percentageWithinRange, } from './utils'; export var DeviceType; (function (DeviceType) { DeviceType["LitraGlow"] = "litra_glow"; @@ -19,13 +19,10 @@ const MAXIMUM_BRIGHTNESS_IN_LUMEN_BY_DEVICE_TYPE = { [DeviceType.LitraGlow]: 250, [DeviceType.LitraBeam]: 400, }; -const MINIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE = { - [DeviceType.LitraGlow]: 2700, - [DeviceType.LitraBeam]: 2700, -}; -const MAXIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE = { - [DeviceType.LitraGlow]: 6500, - [DeviceType.LitraBeam]: 6500, +const MULTIPLES_OF_100_BETWEEN_2700_AND_6500 = multiplesWithinRange(100, 2700, 6500); +const ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE = { + [DeviceType.LitraGlow]: MULTIPLES_OF_100_BETWEEN_2700_AND_6500, + [DeviceType.LitraBeam]: MULTIPLES_OF_100_BETWEEN_2700_AND_6500, }; const NAME_BY_DEVICE_TYPE = { [DeviceType.LitraGlow]: 'Logitech Litra Glow', @@ -93,9 +90,11 @@ export const turnOff = (device) => { * Sets the temperature of your Logitech Litra device * * @param {Device} device The device to set the temperature of - * @param {number} temperatureInKelvin The temperature to set in Kelvin. Use the - * `getMinimumTemperatureInKelvinForDevice` and `getMaximumTemperatureInKelvinForDevice` - * functions to get the minimum and maximum temperature for your device. + * @param {number} temperatureInKelvin The temperature to set in Kelvin. Only + * multiples of 100 between the device's minimum and maximum temperatures + * are allowed. Use the `getMinimumTemperatureInKelvinForDevice` and + * `getMaximumTemperatureInKelvinForDevice` functions to get the minimum + * and maximum temperature for your device. */ export const setTemperatureInKelvin = (device, temperatureInKelvin) => { if (!Number.isInteger(temperatureInKelvin)) { @@ -103,9 +102,9 @@ export const setTemperatureInKelvin = (device, temperatureInKelvin) => { } const minimumTemperature = getMinimumTemperatureInKelvinForDevice(device); const maximumTemperature = getMaximumTemperatureInKelvinForDevice(device); - if (temperatureInKelvin < minimumTemperature || - temperatureInKelvin > maximumTemperature) { - throw `Provided temperature must be between ${minimumTemperature} and ${maximumTemperature} for this device`; + const allowedTemperatures = getAllowedTemperaturesInKelvinForDevice(device); + if (!allowedTemperatures.includes(temperatureInKelvin)) { + throw `Provided temperature must be a multiple of 100 between ${minimumTemperature} and ${maximumTemperature} for this device`; } device.hid.write(padRight([0x11, 0xff, 0x04, 0x9c, ...integerToBytes(temperatureInKelvin)], 20, 0x00)); }; @@ -186,7 +185,7 @@ export const getMaximumBrightnessInLumenForDevice = (device) => { * @returns {number} The minimum temperature in Kelvin supported by the device */ export const getMinimumTemperatureInKelvinForDevice = (device) => { - return MINIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE[device.type]; + return ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE[device.type][0]; }; /** * Gets the maximum temperature in Kelvin supported by a device @@ -195,7 +194,17 @@ export const getMinimumTemperatureInKelvinForDevice = (device) => { * @returns {number} The maximum temperature in Kelvin supported by the device */ export const getMaximumTemperatureInKelvinForDevice = (device) => { - return MAXIMUM_TEMPERATURE_IN_KELVIN_BY_DEVICE_TYPE[device.type]; + const allowedTemperatures = ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE[device.type]; + return allowedTemperatures[allowedTemperatures.length - 1]; +}; +/** + * Gets all temperature values in Kelvin supported by a device + * + * @param {Device} device The device to check the allowed temperatures for + * @returns {number[]} The temperature values in Kelvin supported by the device + */ +export const getAllowedTemperaturesInKelvinForDevice = (device) => { + return ALLOWED_TEMPERATURES_IN_KELVIN_BY_DEVICE_TYPE[device.type]; }; /** * Gets the name of a device diff --git a/dist/esm/utils.d.ts b/dist/esm/utils.d.ts index 3131c12..271040d 100644 --- a/dist/esm/utils.d.ts +++ b/dist/esm/utils.d.ts @@ -30,3 +30,20 @@ export declare const integerToBytes: (integer: number) => [number, number]; * @returns {number} The value at the given percentage */ export declare const percentageWithinRange: (percentage: number, startRange: number, endRange: number) => number; +/** + * Finds all multiples of a given integer within a range. The returned + * list of multiples may or may not include the values at the start and + * the end of the range. + * + * For example: + * - the multiples of 3 within the range 0 to 10 are 0, 3, 6, 9 + * - the multiples of 3 within the range 1 to 10 are 3, 6, 9 + * - the multiples of 5 within the range 0 to 20 are 0, 5, 10, 15, 20 + * - the multiples of 3 within the range 10 to 20 are 12, 15, 18 + * + * @param {number} multiplesOf The integer to find multiples of + * @param {number} startRange The integer at the start of the range + * @param {number} endRange The integer at the end of the range + * @returns {number[]} An array of all the multiples + */ +export declare const multiplesWithinRange: (multiplesOf: number, startRange: number, endRange: number) => number[]; diff --git a/dist/esm/utils.js b/dist/esm/utils.js index 5605fcc..f24f303 100644 --- a/dist/esm/utils.js +++ b/dist/esm/utils.js @@ -48,3 +48,34 @@ export const integerToBytes = (integer) => { export const percentageWithinRange = (percentage, startRange, endRange) => { return Math.round(Math.ceil(((percentage - 1) / (100 - 1)) * (endRange - startRange) + startRange)); }; +/** + * Finds all multiples of a given integer within a range. The returned + * list of multiples may or may not include the values at the start and + * the end of the range. + * + * For example: + * - the multiples of 3 within the range 0 to 10 are 0, 3, 6, 9 + * - the multiples of 3 within the range 1 to 10 are 3, 6, 9 + * - the multiples of 5 within the range 0 to 20 are 0, 5, 10, 15, 20 + * - the multiples of 3 within the range 10 to 20 are 12, 15, 18 + * + * @param {number} multiplesOf The integer to find multiples of + * @param {number} startRange The integer at the start of the range + * @param {number} endRange The integer at the end of the range + * @returns {number[]} An array of all the multiples + */ +export const multiplesWithinRange = (multiplesOf, startRange, endRange) => { + if (!Number.isInteger(multiplesOf)) { + throw 'Provided value for `multiplesOf` must be an integer'; + } + if (!Number.isInteger(startRange)) { + throw 'Provided value for `startRange` must be an integer'; + } + if (!Number.isInteger(endRange)) { + throw 'Provided value for `endRange` must be an integer'; + } + const inclusiveIntegersWithinRange = Array(endRange - startRange + 1) + .fill([]) + .map((_, idx) => startRange + idx); + return inclusiveIntegersWithinRange.filter((integer) => integer % multiplesOf === 0); +};