UNPKG

amaran-light-cli

Version:

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

169 lines 7.56 kB
import chalk from 'chalk'; import { addStandardOptions, runDeviceAction } from '../cmdUtils.js'; export function registerPower(program, deps) { const { asyncCommand } = deps; // on addStandardOptions(program.command('on [device]').description('Turn a light on or get status (or all lights if no device specified)')) .option('-g, --get', 'Get current status instead of turning on') .action(asyncCommand(handleOn(deps))); // off addStandardOptions(program.command('off [device]').description('Turn a light off or get status (or all lights if no device specified)')) .option('-g, --get', 'Get current status instead of turning off') .action(asyncCommand(handleOff(deps))); // toggle addStandardOptions(program.command('toggle [device]').description('Toggle a light on/off (or all lights if no device specified)')).action(asyncCommand(handleToggle(deps))); } async function getPowerStatus(deps, deviceQuery, options, _actionName) { return runDeviceAction({ deps, options, deviceQuery, actionName: 'get power status', }, async (device, controller) => { return new Promise((resolve) => { controller.getLightSleepStatus(device.node_id, (success, message, data) => { if (!success) throw new Error(message); const displayName = device.device_name || device.name || device.id || device.node_id || 'Unknown'; // Handle potential nesting: { data: { data: false } } or { data: { sleep: false } } let state = data; if (state && typeof state === 'object' && 'data' in state) { const innerData = state.data; if (typeof innerData === 'boolean') { state = { sleep: innerData }; } else { state = innerData; } } // biome-ignore lint/suspicious/noExplicitAny: Data from server is dynamic const s = state; // sleep = true means OFF, sleep = false means ON const sleepVal = typeof state === 'boolean' ? state : s?.sleep; const status = sleepVal === undefined ? 'Unknown' : sleepVal ? 'OFF' : 'ON'; console.log(chalk.green(`✓ ${displayName}: ${status}`)); resolve(); }); }); }, async (controller) => { const devices = controller.getDevices(); if (devices.length === 0) { console.log(chalk.yellow('No devices found')); return; } // Filter for light devices only, skipping groups like 'ALL' const lightDevices = devices.filter((d) => d.node_id?.includes('-') && d.node_id !== '00000000000000000000000000000000'); 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.getLightSleepStatus(device.node_id, (success, message, data) => { const displayName = device.device_name || device.name || device.id || device.node_id || 'Unknown'; if (success) { let state = data; if (state && typeof state === 'object' && 'data' in state) { const innerData = state.data; if (typeof innerData === 'boolean') { state = { sleep: innerData }; } else { state = innerData; } } // biome-ignore lint/suspicious/noExplicitAny: Data from server is dynamic const s = state; const sleepVal = typeof state === 'boolean' ? state : s?.sleep; const status = sleepVal === undefined ? 'Unknown' : sleepVal ? 'OFF' : 'ON'; console.log(chalk.green(`✓ ${displayName}: ${status}`)); } else { console.error(chalk.red(`✗ ${displayName}: Failed to get status: ${message}`)); } resolve(); }); }); } } }); } function handleOn(deps) { return async (deviceQuery, options) => { if (options.get) { return getPowerStatus(deps, deviceQuery, options, 'get status'); } return runDeviceAction({ deps, options, deviceQuery, actionName: 'turn on light', onSuccess: (device) => `✓ ${device.device_name || device.name || device.id || device.node_id || 'Unknown'} turned on`, }, (device, controller) => { return new Promise((resolve) => { controller.turnLightOn(device.node_id, (success, message) => { if (!success) throw new Error(message); resolve(); }); }); }, async (controller) => { await controller.turnOnAllLights((success, message) => { if (!success) console.error(`✗ Failed to turn on light: ${message}`); }); }); }; } function handleOff(deps) { return async (deviceQuery, options) => { if (options.get) { return getPowerStatus(deps, deviceQuery, options, 'get status'); } return runDeviceAction({ deps, options, deviceQuery, actionName: 'turn off light', onSuccess: (device) => `✓ ${device.device_name || device.name || device.id || device.node_id || 'Unknown'} turned off`, }, (device, controller) => { return new Promise((resolve) => { controller.turnLightOff(device.node_id, (success, message) => { if (!success) throw new Error(message); resolve(); }); }); }, async (controller) => { await controller.turnOffAllLights((success, message) => { if (!success) console.error(`✗ Failed to turn off light: ${message}`); }); }); }; } function handleToggle(deps) { return (deviceQuery, options) => runDeviceAction({ deps, options, deviceQuery, actionName: 'toggle light', onSuccess: (device) => `✓ ${device.device_name || device.name || device.id || device.node_id || 'Unknown'} toggled`, }, (device, controller) => { return new Promise((resolve) => { controller.toggleLight(device.node_id, (success, message) => { if (!success) throw new Error(message); resolve(); }); }); }, async (controller) => { await controller.toggleAllLights((success, message) => { if (!success) console.error(`✗ Failed to toggle light: ${message}`); }); }); } export default registerPower; //# sourceMappingURL=power.js.map