UNPKG

amaran-light-cli

Version:

Command line tool for controlling Aputure Amaran lights via WebSocket to a local Amaran desktop app.

214 lines 11.2 kB
import chalk from 'chalk'; import { addStandardOptions, commandCallbackPromise, getLightDevices, runDeviceAction } from '../cmdUtils.js'; export function registerColor(program, deps) { const { asyncCommand } = deps; addStandardOptions(program .command('color [color] [device]') .description('Set or get color by name or hex code (e.g., "red", "#ff0000"). Omit device or use "all" for all lights.')) .option('-i, --intensity <value>', 'Set intensity (0-100)') .option('-g, --get', 'Get current color status') .action(asyncCommand(handleColor(deps))); } function handleColor(deps) { return async (colorStr, deviceQuery, options) => { // Handle get mode if (options.get) { // Argument shifting: if only one arg provided and it might be a device (or if colorStr is undefined) // For color command, if user types `color -g mydevice`, colorStr will be "mydevice". // If user types `color -g`, colorStr is undefined. let targetDevice = deviceQuery; if (!targetDevice && colorStr) { // If colorStr does not look like a color (hex/name) but might be a device? // Actually, if fetching, we don't care about color arg. So whatever is passed is likely the device or ignored. // It's safer to treat the first arg as device if getting. targetDevice = colorStr; } return runDeviceAction({ deps, options, deviceQuery: targetDevice, actionName: 'get color', }, async (device, controller) => { // We use getNodeConfig initially return new Promise((resolve) => { controller.getNodeConfig(device.node_id, async (_success, _messagee, data) => { const displayName = device.device_name || device.name || device.id || device.node_id || 'Unknown'; const config = data?.data || data || {}; const h = config.hue ?? config.h; const s = config.saturation ?? config.sat ?? config.s; let i = config.intensity ?? config.int ?? config.i; let cct = config.cct; // If state is missing, try explicit getters for reliable props (CCT, Intensity) // We skip getHSI as it is invalid on server if (h === undefined && s === undefined && cct === undefined) { // Try getting CCT await new Promise((r) => { controller.getCCT(device.node_id, (ok, _msg, d) => { if (ok) { const inner = d?.data ?? d; const val = typeof inner === 'number' ? inner : inner?.cct; if (val !== undefined) cct = val; } r(); }); }); // Try getting Intensity await new Promise((r) => { controller.getIntensity(device.node_id, (ok, _msg, d) => { if (ok) { const inner = d?.data ?? d; const val = typeof inner === 'number' ? inner : inner?.intensity; if (val !== undefined) i = val; } r(); }); }); } let output = `✓ ${displayName}: `; const parts = []; if (h !== undefined && s !== undefined) { parts.push(`HSI(${h}, ${s}, ${i !== undefined ? i / 10 : '?'})`); } else if (cct !== undefined) { parts.push(`CCT: ${cct}K`); } if (i !== undefined && (parts.length === 0 || !parts[0].includes('HSI'))) { parts.push(`Intensity: ${i / 10}%`); } if (parts.length === 0) { parts.push('Unknown state'); } output += parts.join(', '); console.log(chalk.green(output)); resolve(); }); }); }, async (controller) => { // Apply to all devices loop const devices = controller.getDevices(); if (devices.length === 0) { console.log(chalk.yellow('No devices found')); return; } // Filter for light devices only const lightDevices = getLightDevices(devices); if (lightDevices.length === 0) { console.log(chalk.yellow('No light devices found')); return; } for (const device of lightDevices) { if (device.node_id) { await new Promise((resolve) => { controller.getNodeConfig(device.node_id, async (_success, _messagee, data) => { const displayName = device.device_name || device.name || device.id || device.node_id || 'Unknown'; const config = data?.data || data || {}; const h = config.hue ?? config.h; const s = config.saturation ?? config.sat ?? config.s; let i = config.intensity ?? config.int ?? config.i; let cct = config.cct; if (h === undefined && s === undefined && cct === undefined) { await new Promise((r) => { controller.getCCT(device.node_id, (ok, _msg, d) => { if (ok) { const inner = d?.data ?? d; const val = typeof inner === 'number' ? inner : inner?.cct; if (val !== undefined) cct = val; } r(); }); }); await new Promise((r) => { controller.getIntensity(device.node_id, (ok, _msg, d) => { if (ok) { const inner = d?.data ?? d; const val = typeof inner === 'number' ? inner : inner?.intensity; if (val !== undefined) i = val; } r(); }); }); } const parts = []; if (h !== undefined && s !== undefined) { parts.push(`HSI(${h}, ${s}, ${i !== undefined ? i / 10 : '?'})`); } else if (cct !== undefined) { parts.push(`CCT: ${cct}K`); } if (i !== undefined && (parts.length === 0 || !parts[0].includes('HSI'))) { parts.push(`Intensity: ${i / 10}%`); } if (parts.length === 0) parts.push('Unknown state'); console.log(chalk.green(`✓ ${displayName}: ${parts.join(', ')}`)); resolve(); }); }); } } }); } // Set mode (original logic) if (!colorStr) { console.error(chalk.red("error: missing required argument 'color'")); process.exit(1); } const color = colorStr; let intensity; if (options.intensity) { intensity = parseInt(options.intensity, 10); if (Number.isNaN(intensity) || intensity < 0 || intensity > 100) { console.error(chalk.red('Intensity must be a number between 0 and 100')); process.exit(1); } intensity = intensity * 10; } return runDeviceAction({ deps, options, deviceQuery, actionName: 'set color', onSuccess: (device) => { const displayName = device.device_name || device.name || device.id || device.node_id || 'Unknown'; let msg = `✓ ${displayName} color set to ${color}`; if (intensity !== undefined) { msg += ` at ${intensity / 10}% intensity`; } return msg; }, }, (device, controller) => { return commandCallbackPromise((callback) => controller.setColor(device.node_id, color, intensity, callback)); }, async (controller) => { await controller.setColorForAllLights(color, intensity, (success, message) => { if (!success) console.error(`✗ Failed to set color: ${message}`); }); }); }; } export default registerColor; //# sourceMappingURL=color.js.map