2025-10-19 12:57:17 +00:00
|
|
|
import process from 'node:process';
|
2025-10-18 11:59:55 +00:00
|
|
|
import { Nupst } from '../nupst.ts';
|
2025-10-20 01:30:57 +00:00
|
|
|
import { logger, type ITableColumn } from '../logger.ts';
|
|
|
|
import { theme } from '../colors.ts';
|
2025-10-18 11:59:55 +00:00
|
|
|
import * as helpers from '../helpers/index.ts';
|
|
|
|
import { type IGroupConfig } from '../daemon.ts';
|
2025-03-28 22:12:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class for handling group-related CLI commands
|
|
|
|
* Provides interface for managing UPS groups
|
|
|
|
*/
|
|
|
|
export class GroupHandler {
|
|
|
|
private readonly nupst: Nupst;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new Group handler
|
|
|
|
* @param nupst Reference to the main Nupst instance
|
|
|
|
*/
|
|
|
|
constructor(nupst: Nupst) {
|
|
|
|
this.nupst = nupst;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List all UPS groups
|
|
|
|
*/
|
|
|
|
public async list(): Promise<void> {
|
|
|
|
try {
|
|
|
|
// Try to load configuration
|
|
|
|
try {
|
|
|
|
await this.nupst.getDaemon().loadConfig();
|
|
|
|
} catch (error) {
|
2025-10-20 01:30:57 +00:00
|
|
|
logger.logBox('Configuration Error', [
|
|
|
|
'No configuration found.',
|
|
|
|
"Please run 'nupst ups add' first to create a configuration.",
|
|
|
|
], 50, 'error');
|
2025-03-28 22:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get current configuration
|
|
|
|
const config = this.nupst.getDaemon().getConfig();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if multi-UPS config
|
|
|
|
if (!config.groups || !Array.isArray(config.groups)) {
|
2025-10-20 01:30:57 +00:00
|
|
|
logger.logBox('UPS Groups', [
|
|
|
|
'No groups configured.',
|
|
|
|
'',
|
|
|
|
`${theme.dim('Run')} ${theme.command('nupst group add')} ${theme.dim('to add a group')}`,
|
|
|
|
], 50, 'info');
|
2025-03-28 22:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-10-20 01:30:57 +00:00
|
|
|
// Display group list with modern table
|
2025-03-28 22:12:01 +00:00
|
|
|
if (config.groups.length === 0) {
|
2025-10-20 01:30:57 +00:00
|
|
|
logger.logBox('UPS Groups', [
|
|
|
|
'No UPS groups configured.',
|
|
|
|
'',
|
|
|
|
`${theme.dim('Run')} ${theme.command('nupst group add')} ${theme.dim('to add a group')}`,
|
|
|
|
], 60, 'info');
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-10-20 01:30:57 +00:00
|
|
|
// Prepare table data
|
|
|
|
const rows = config.groups.map((group) => {
|
|
|
|
// Count UPS devices in this group
|
|
|
|
const upsInGroup = config.upsDevices.filter((ups) => ups.groups.includes(group.id));
|
|
|
|
const upsCount = upsInGroup.length;
|
|
|
|
const upsNames = upsInGroup.map((ups) => ups.name).join(', ');
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-10-20 01:30:57 +00:00
|
|
|
return {
|
|
|
|
id: group.id,
|
|
|
|
name: group.name || '',
|
|
|
|
mode: group.mode || 'unknown',
|
|
|
|
count: String(upsCount),
|
|
|
|
devices: upsCount > 0 ? upsNames : theme.dim('None'),
|
|
|
|
};
|
|
|
|
});
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-10-20 01:30:57 +00:00
|
|
|
const columns: ITableColumn[] = [
|
|
|
|
{ header: 'ID', key: 'id', align: 'left', color: theme.highlight },
|
|
|
|
{ header: 'Name', key: 'name', align: 'left' },
|
|
|
|
{ header: 'Mode', key: 'mode', align: 'left', color: theme.info },
|
|
|
|
{ header: 'UPS Count', key: 'count', align: 'right' },
|
|
|
|
{ header: 'UPS Devices', key: 'devices', align: 'left' },
|
|
|
|
];
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-10-20 01:30:57 +00:00
|
|
|
logger.log('');
|
|
|
|
logger.info(`UPS Groups (${config.groups.length}):`);
|
|
|
|
logger.log('');
|
|
|
|
logger.logTable(columns, rows);
|
|
|
|
logger.log('');
|
2025-03-28 22:12:01 +00:00
|
|
|
} catch (error) {
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.error(
|
|
|
|
`Failed to list UPS groups: ${error instanceof Error ? error.message : String(error)}`,
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
/**
|
|
|
|
* Add a new UPS group
|
|
|
|
*/
|
|
|
|
public async add(): Promise<void> {
|
|
|
|
try {
|
|
|
|
// Import readline module for user input
|
2025-10-18 12:36:35 +00:00
|
|
|
const readline = await import('node:readline');
|
2025-03-28 22:12:01 +00:00
|
|
|
|
|
|
|
const rl = readline.createInterface({
|
|
|
|
input: process.stdin,
|
|
|
|
output: process.stdout,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Helper function to prompt for input
|
|
|
|
const prompt = (question: string): Promise<string> => {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
rl.question(question, (answer: string) => {
|
|
|
|
resolve(answer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Try to load configuration
|
|
|
|
try {
|
|
|
|
await this.nupst.getDaemon().loadConfig();
|
|
|
|
} catch (error) {
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.error(
|
|
|
|
'No configuration found. Please run "nupst setup" first to create a configuration.',
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get current configuration
|
|
|
|
const config = this.nupst.getDaemon().getConfig();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Initialize groups array if not exists
|
|
|
|
if (!config.groups) {
|
|
|
|
config.groups = [];
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if upsDevices is initialized
|
|
|
|
if (!config.upsDevices) {
|
|
|
|
config.upsDevices = [];
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
logger.log('\nNUPST Add Group');
|
|
|
|
logger.log('==============\n');
|
|
|
|
logger.log('This will guide you through creating a new UPS group.\n');
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Generate a new unique group ID
|
|
|
|
const groupId = helpers.shortId();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get group name
|
|
|
|
const name = await prompt('Group Name: ');
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get group mode
|
|
|
|
const modeInput = await prompt('Group Mode (redundant/nonRedundant) [redundant]: ');
|
|
|
|
const mode = modeInput.toLowerCase() === 'nonredundant' ? 'nonRedundant' : 'redundant';
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get optional description
|
|
|
|
const description = await prompt('Group Description (optional): ');
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Create the new group
|
|
|
|
const newGroup: IGroupConfig = {
|
|
|
|
id: groupId,
|
|
|
|
name: name || `Group-${groupId}`,
|
|
|
|
mode,
|
2025-10-19 13:14:18 +00:00
|
|
|
description: description || undefined,
|
2025-03-28 22:12:01 +00:00
|
|
|
};
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Add the group to the configuration
|
|
|
|
config.groups.push(newGroup);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Save the configuration
|
|
|
|
await this.nupst.getDaemon().saveConfig(config);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Display summary
|
|
|
|
const boxWidth = 45;
|
|
|
|
logger.logBoxTitle('Group Created', boxWidth);
|
|
|
|
logger.logBoxLine(`ID: ${newGroup.id}`);
|
|
|
|
logger.logBoxLine(`Name: ${newGroup.name}`);
|
|
|
|
logger.logBoxLine(`Mode: ${newGroup.mode}`);
|
|
|
|
if (newGroup.description) {
|
|
|
|
logger.logBoxLine(`Description: ${newGroup.description}`);
|
|
|
|
}
|
|
|
|
logger.logBoxEnd();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if there are UPS devices to assign to this group
|
|
|
|
if (config.upsDevices.length > 0) {
|
2025-10-19 13:14:18 +00:00
|
|
|
const assignUps = await prompt(
|
|
|
|
'Would you like to assign UPS devices to this group now? (y/N): ',
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (assignUps.toLowerCase() === 'y') {
|
|
|
|
await this.assignUpsToGroup(newGroup.id, config, prompt);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Save again after assigning UPS devices
|
|
|
|
await this.nupst.getDaemon().saveConfig(config);
|
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if service is running and restart it if needed
|
|
|
|
this.nupst.getUpsHandler().restartServiceIfRunning();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
logger.log('\nGroup setup complete!');
|
|
|
|
} finally {
|
|
|
|
rl.close();
|
2025-10-20 00:32:06 +00:00
|
|
|
process.stdin.destroy();
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
|
|
|
} catch (error) {
|
2025-10-18 21:07:57 +00:00
|
|
|
logger.error(`Add group error: ${error instanceof Error ? error.message : String(error)}`);
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
/**
|
|
|
|
* Edit an existing UPS group
|
|
|
|
* @param groupId ID of the group to edit
|
|
|
|
*/
|
|
|
|
public async edit(groupId: string): Promise<void> {
|
|
|
|
try {
|
|
|
|
// Import readline module for user input
|
2025-10-18 12:36:35 +00:00
|
|
|
const readline = await import('node:readline');
|
2025-03-28 22:12:01 +00:00
|
|
|
|
|
|
|
const rl = readline.createInterface({
|
|
|
|
input: process.stdin,
|
|
|
|
output: process.stdout,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Helper function to prompt for input
|
|
|
|
const prompt = (question: string): Promise<string> => {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
rl.question(question, (answer: string) => {
|
|
|
|
resolve(answer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Try to load configuration
|
|
|
|
try {
|
|
|
|
await this.nupst.getDaemon().loadConfig();
|
|
|
|
} catch (error) {
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.error(
|
|
|
|
'No configuration found. Please run "nupst setup" first to create a configuration.',
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get current configuration
|
|
|
|
const config = this.nupst.getDaemon().getConfig();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if groups are initialized
|
|
|
|
if (!config.groups || !Array.isArray(config.groups)) {
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.error(
|
|
|
|
'No groups configured. Please run "nupst group add" first to create a group.',
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Find the group to edit
|
2025-10-19 13:14:18 +00:00
|
|
|
const groupIndex = config.groups.findIndex((group) => group.id === groupId);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (groupIndex === -1) {
|
|
|
|
logger.error(`Group with ID "${groupId}" not found.`);
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
const group = config.groups[groupIndex];
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
logger.log(`\nNUPST Edit Group: ${group.name} (${group.id})`);
|
|
|
|
logger.log('==============================================\n');
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Edit group name
|
|
|
|
const newName = await prompt(`Group Name [${group.name}]: `);
|
|
|
|
if (newName.trim()) {
|
|
|
|
group.name = newName;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Edit group mode
|
|
|
|
const currentMode = group.mode || 'redundant';
|
|
|
|
const modeInput = await prompt(`Group Mode (redundant/nonRedundant) [${currentMode}]: `);
|
|
|
|
if (modeInput.trim()) {
|
|
|
|
group.mode = modeInput.toLowerCase() === 'nonredundant' ? 'nonRedundant' : 'redundant';
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Edit description
|
|
|
|
const currentDesc = group.description || '';
|
|
|
|
const newDesc = await prompt(`Group Description [${currentDesc}]: `);
|
|
|
|
if (newDesc.trim() || newDesc === '') {
|
|
|
|
group.description = newDesc.trim() || undefined;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Update the group in the configuration
|
|
|
|
config.groups[groupIndex] = group;
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Save the configuration
|
|
|
|
await this.nupst.getDaemon().saveConfig(config);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Display summary
|
|
|
|
const boxWidth = 45;
|
|
|
|
logger.logBoxTitle('Group Updated', boxWidth);
|
|
|
|
logger.logBoxLine(`ID: ${group.id}`);
|
|
|
|
logger.logBoxLine(`Name: ${group.name}`);
|
|
|
|
logger.logBoxLine(`Mode: ${group.mode}`);
|
|
|
|
if (group.description) {
|
|
|
|
logger.logBoxLine(`Description: ${group.description}`);
|
|
|
|
}
|
|
|
|
logger.logBoxEnd();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Edit UPS assignments if requested
|
2025-10-19 13:14:18 +00:00
|
|
|
const editAssignments = await prompt(
|
|
|
|
'Would you like to edit UPS assignments for this group? (y/N): ',
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (editAssignments.toLowerCase() === 'y') {
|
|
|
|
await this.assignUpsToGroup(group.id, config, prompt);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Save again after editing assignments
|
|
|
|
await this.nupst.getDaemon().saveConfig(config);
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if service is running and restart it if needed
|
|
|
|
this.nupst.getUpsHandler().restartServiceIfRunning();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
logger.log('\nGroup edit complete!');
|
|
|
|
} finally {
|
|
|
|
rl.close();
|
2025-10-20 00:32:06 +00:00
|
|
|
process.stdin.destroy();
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
|
|
|
} catch (error) {
|
2025-10-18 21:07:57 +00:00
|
|
|
logger.error(`Edit group error: ${error instanceof Error ? error.message : String(error)}`);
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
/**
|
|
|
|
* Delete an existing UPS group
|
|
|
|
* @param groupId ID of the group to delete
|
|
|
|
*/
|
2025-10-18 12:36:35 +00:00
|
|
|
public async remove(groupId: string): Promise<void> {
|
2025-03-28 22:12:01 +00:00
|
|
|
try {
|
|
|
|
// Try to load configuration
|
|
|
|
try {
|
|
|
|
await this.nupst.getDaemon().loadConfig();
|
|
|
|
} catch (error) {
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.error(
|
|
|
|
'No configuration found. Please run "nupst setup" first to create a configuration.',
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get current configuration
|
|
|
|
const config = this.nupst.getDaemon().getConfig();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if groups are initialized
|
|
|
|
if (!config.groups || !Array.isArray(config.groups)) {
|
|
|
|
logger.error('No groups configured.');
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Find the group to delete
|
2025-10-19 13:14:18 +00:00
|
|
|
const groupIndex = config.groups.findIndex((group) => group.id === groupId);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (groupIndex === -1) {
|
|
|
|
logger.error(`Group with ID "${groupId}" not found.`);
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
const groupToDelete = config.groups[groupIndex];
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Get confirmation before deleting
|
2025-10-18 12:36:35 +00:00
|
|
|
const readline = await import('node:readline');
|
2025-03-28 22:12:01 +00:00
|
|
|
const rl = readline.createInterface({
|
|
|
|
input: process.stdin,
|
|
|
|
output: process.stdout,
|
|
|
|
});
|
2025-10-19 13:14:18 +00:00
|
|
|
|
|
|
|
const confirm = await new Promise<string>((resolve) => {
|
|
|
|
rl.question(
|
|
|
|
`Are you sure you want to delete group "${groupToDelete.name}" (${groupId})? [y/N]: `,
|
|
|
|
(answer) => {
|
|
|
|
resolve(answer.toLowerCase());
|
|
|
|
},
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
});
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
rl.close();
|
2025-10-20 00:32:06 +00:00
|
|
|
process.stdin.destroy();
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
if (confirm !== 'y' && confirm !== 'yes') {
|
|
|
|
logger.log('Deletion cancelled.');
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Remove this group from all UPS device group assignments
|
|
|
|
if (config.upsDevices && Array.isArray(config.upsDevices)) {
|
|
|
|
for (const ups of config.upsDevices) {
|
|
|
|
const groupIndex = ups.groups.indexOf(groupId);
|
|
|
|
if (groupIndex !== -1) {
|
|
|
|
ups.groups.splice(groupIndex, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Remove the group from the array
|
|
|
|
config.groups.splice(groupIndex, 1);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Save the configuration
|
|
|
|
await this.nupst.getDaemon().saveConfig(config);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
logger.log(`Group "${groupToDelete.name}" (${groupId}) has been deleted.`);
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Check if service is running and restart it if needed
|
|
|
|
this.nupst.getUpsHandler().restartServiceIfRunning();
|
|
|
|
} catch (error) {
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.error(
|
|
|
|
`Failed to delete group: ${error instanceof Error ? error.message : String(error)}`,
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Assign UPS devices to groups
|
|
|
|
* @param ups UPS configuration to update
|
|
|
|
* @param groups Available groups
|
|
|
|
* @param prompt Function to prompt for user input
|
|
|
|
*/
|
|
|
|
public async assignUpsToGroups(
|
|
|
|
ups: any,
|
|
|
|
groups: any[],
|
2025-10-19 13:14:18 +00:00
|
|
|
prompt: (question: string) => Promise<string>,
|
2025-03-28 22:12:01 +00:00
|
|
|
): Promise<void> {
|
|
|
|
// Initialize groups array if it doesn't exist
|
|
|
|
if (!ups.groups) {
|
|
|
|
ups.groups = [];
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Show current group assignments
|
|
|
|
logger.log('\nCurrent Group Assignments:');
|
|
|
|
if (ups.groups && ups.groups.length > 0) {
|
|
|
|
for (const groupId of ups.groups) {
|
2025-10-19 13:14:18 +00:00
|
|
|
const group = groups.find((g) => g.id === groupId);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (group) {
|
|
|
|
logger.log(`- ${group.name} (${group.id})`);
|
|
|
|
} else {
|
|
|
|
logger.log(`- Unknown group (${groupId})`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
logger.log('- None');
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Show available groups
|
|
|
|
logger.log('\nAvailable Groups:');
|
|
|
|
if (groups.length === 0) {
|
|
|
|
logger.log('- No groups available. Use "nupst group add" to create groups.');
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
for (let i = 0; i < groups.length; i++) {
|
|
|
|
const group = groups[i];
|
|
|
|
const assigned = ups.groups && ups.groups.includes(group.id);
|
2025-10-19 13:14:18 +00:00
|
|
|
logger.log(
|
|
|
|
`${i + 1}) ${group.name} (${group.id}) [${assigned ? 'Assigned' : 'Not Assigned'}]`,
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Prompt for group selection
|
2025-10-19 13:14:18 +00:00
|
|
|
const selection = await prompt(
|
|
|
|
'\nSelect groups to assign/unassign (comma-separated numbers, or "clear" to remove all): ',
|
|
|
|
);
|
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
if (selection.toLowerCase() === 'clear') {
|
|
|
|
// Clear all group assignments
|
|
|
|
ups.groups = [];
|
|
|
|
logger.log('All group assignments cleared.');
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
if (!selection.trim()) {
|
|
|
|
// No change if empty input
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Process selections
|
2025-10-19 13:14:18 +00:00
|
|
|
const selections = selection.split(',').map((s) => s.trim());
|
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
for (const sel of selections) {
|
|
|
|
const index = parseInt(sel, 10) - 1;
|
|
|
|
if (isNaN(index) || index < 0 || index >= groups.length) {
|
|
|
|
logger.error(`Invalid selection: ${sel}`);
|
|
|
|
continue;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
const group = groups[index];
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Initialize groups array if needed (should already be done above)
|
|
|
|
if (!ups.groups) {
|
|
|
|
ups.groups = [];
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Toggle assignment
|
|
|
|
const groupIndex = ups.groups.indexOf(group.id);
|
|
|
|
if (groupIndex === -1) {
|
|
|
|
// Add to group
|
|
|
|
ups.groups.push(group.id);
|
|
|
|
logger.log(`Added to group: ${group.name} (${group.id})`);
|
|
|
|
} else {
|
|
|
|
// Remove from group
|
|
|
|
ups.groups.splice(groupIndex, 1);
|
|
|
|
logger.log(`Removed from group: ${group.name} (${group.id})`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
/**
|
|
|
|
* Assign UPS devices to a specific group
|
|
|
|
* @param groupId Group ID to assign UPS devices to
|
|
|
|
* @param config Full configuration
|
|
|
|
* @param prompt Function to prompt for user input
|
|
|
|
*/
|
|
|
|
public async assignUpsToGroup(
|
|
|
|
groupId: string,
|
|
|
|
config: any,
|
2025-10-19 13:14:18 +00:00
|
|
|
prompt: (question: string) => Promise<string>,
|
2025-03-28 22:12:01 +00:00
|
|
|
): Promise<void> {
|
|
|
|
if (!config.upsDevices || config.upsDevices.length === 0) {
|
|
|
|
logger.log('No UPS devices available. Use "nupst add" to add UPS devices.');
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-10-18 21:07:57 +00:00
|
|
|
const group = config.groups.find((g: { id: string }) => g.id === groupId);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (!group) {
|
|
|
|
logger.error(`Group with ID "${groupId}" not found.`);
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Show current assignments
|
|
|
|
logger.log(`\nUPS devices in group "${group.name}" (${group.id}):`);
|
2025-10-19 13:14:18 +00:00
|
|
|
const upsInGroup = config.upsDevices.filter((ups: { groups?: string[] }) =>
|
|
|
|
ups.groups && ups.groups.includes(groupId)
|
|
|
|
);
|
2025-03-28 22:12:01 +00:00
|
|
|
if (upsInGroup.length === 0) {
|
|
|
|
logger.log('- None');
|
|
|
|
} else {
|
|
|
|
for (const ups of upsInGroup) {
|
|
|
|
logger.log(`- ${ups.name} (${ups.id})`);
|
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Show all UPS devices
|
|
|
|
logger.log('\nAvailable UPS devices:');
|
|
|
|
for (let i = 0; i < config.upsDevices.length; i++) {
|
|
|
|
const ups = config.upsDevices[i];
|
|
|
|
const assigned = ups.groups && ups.groups.includes(groupId);
|
|
|
|
logger.log(`${i + 1}) ${ups.name} (${ups.id}) [${assigned ? 'Assigned' : 'Not Assigned'}]`);
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Prompt for UPS selection
|
2025-10-19 13:14:18 +00:00
|
|
|
const selection = await prompt(
|
|
|
|
'\nSelect UPS devices to assign/unassign (comma-separated numbers, or "clear" to remove all): ',
|
|
|
|
);
|
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
if (selection.toLowerCase() === 'clear') {
|
|
|
|
// Clear all UPS from this group
|
|
|
|
for (const ups of config.upsDevices) {
|
|
|
|
if (ups.groups) {
|
|
|
|
const groupIndex = ups.groups.indexOf(groupId);
|
|
|
|
if (groupIndex !== -1) {
|
|
|
|
ups.groups.splice(groupIndex, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
logger.log(`All UPS devices removed from group "${group.name}".`);
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
if (!selection.trim()) {
|
|
|
|
// No change if empty input
|
|
|
|
return;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Process selections
|
2025-10-19 13:14:18 +00:00
|
|
|
const selections = selection.split(',').map((s) => s.trim());
|
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
for (const sel of selections) {
|
|
|
|
const index = parseInt(sel, 10) - 1;
|
|
|
|
if (isNaN(index) || index < 0 || index >= config.upsDevices.length) {
|
|
|
|
logger.error(`Invalid selection: ${sel}`);
|
|
|
|
continue;
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
const ups = config.upsDevices[index];
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Initialize groups array if needed
|
|
|
|
if (!ups.groups) {
|
|
|
|
ups.groups = [];
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
|
2025-03-28 22:12:01 +00:00
|
|
|
// Toggle assignment
|
|
|
|
const groupIndex = ups.groups.indexOf(groupId);
|
|
|
|
if (groupIndex === -1) {
|
|
|
|
// Add to group
|
|
|
|
ups.groups.push(groupId);
|
|
|
|
logger.log(`Added "${ups.name}" to group "${group.name}"`);
|
|
|
|
} else {
|
|
|
|
// Remove from group
|
|
|
|
ups.groups.splice(groupIndex, 1);
|
|
|
|
logger.log(`Removed "${ups.name}" from group "${group.name}"`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-10-19 13:14:18 +00:00
|
|
|
}
|