Compare commits

...

16 Commits

Author SHA1 Message Date
2737fca294 2.5.1 2025-03-25 14:47:57 +00:00
896233914f fix(snmp): Fix Eaton UPS support by updating power status OID and adjusting battery runtime conversion. 2025-03-25 14:47:57 +00:00
5bb775b17d 2.5.0 2025-03-25 13:26:28 +00:00
ae8219acf7 feat(cli): Automatically restart running NUPST service after configuration changes in interactive setup 2025-03-25 13:26:27 +00:00
4ad383884c 2.4.8 2025-03-25 13:20:36 +00:00
65a9d1c798 fix(installer): Improve Git dependency handling and repository cloning in install.sh 2025-03-25 13:20:36 +00:00
f583e1466f 2.4.7 2025-03-25 13:17:28 +00:00
9d893a97b6 fix(readme): Update installation instructions to combine download and execution into a single command for clarity 2025-03-25 13:17:28 +00:00
aa52d5e9f6 2.4.6 2025-03-25 13:15:48 +00:00
623b7ee51f fix(installer): Improve installation instructions for interactive and non-interactive setups 2025-03-25 13:15:48 +00:00
897e86ad60 2.4.5 2025-03-25 13:12:38 +00:00
ed78db20e2 fix(install): Improve interactive terminal detection and update installation instructions 2025-03-25 13:12:38 +00:00
bd00dfe02c 2.4.4 2025-03-25 13:08:28 +00:00
55c040df82 fix(install): Improve interactive mode detection and non-interactive installation handling in install.sh 2025-03-25 13:08:28 +00:00
e68654a022 2.4.3 2025-03-25 12:57:12 +00:00
89a5d23d2f fix(readme): Update Quick Install command syntax in readme for auto-yes installation 2025-03-25 12:57:12 +00:00
8 changed files with 215 additions and 28 deletions

View File

@ -1,5 +1,54 @@
# Changelog
## 2025-03-25 - 2.5.1 - fix(snmp)
Fix Eaton UPS support by updating power status OID and adjusting battery runtime conversion.
- Updated Eaton UPS power status OID to '1.3.6.1.4.1.534.1.4.4.0' to correctly detect online/battery status.
- Added conversion for Eaton UPS battery runtime from seconds to minutes in SNMP manager.
## 2025-03-25 - 2.5.0 - feat(cli)
Automatically restart running NUPST service after configuration changes in interactive setup
- Added restartServiceIfRunning() to check and restart the service if it's active.
- Invoked the restart function post-setup to apply configuration changes immediately.
## 2025-03-25 - 2.4.8 - fix(installer)
Improve Git dependency handling and repository cloning in install.sh
- Add explicit check for git installation and prompt the user interactively if git is missing.
- Auto-install git when '-y' flag is provided in non-interactive mode.
- Ensure proper cloning of the repository when running the installer outside the repo.
## 2025-03-25 - 2.4.7 - fix(readme)
Update installation instructions to combine download and execution into a single command for clarity
- Method 1 now uses a unified one-line command to download and run the install script
## 2025-03-25 - 2.4.6 - fix(installer)
Improve installation instructions for interactive and non-interactive setups
- Changed install.sh to require explicit download of the install script and updated error messages for non-interactive modes
- Updated readme.md to include three distinct installation methods with clear command examples
## 2025-03-25 - 2.4.5 - fix(install)
Improve interactive terminal detection and update installation instructions
- Enhanced install.sh to better detect non-interactive environments and provide clearer guidance for both interactive and non-interactive installations
- Updated README.md quick install instructions to recommend process substitution and clarify auto-yes usage
## 2025-03-25 - 2.4.4 - fix(install)
Improve interactive mode detection and non-interactive installation handling in install.sh
- Detect and warn when running without a controlling terminal
- Attempt to use /dev/tty for user input when possible
- Update prompts and error messages for auto-installation of dependencies
- Clarify installation instructions in readme for interactive and non-interactive modes
## 2025-03-25 - 2.4.3 - fix(readme)
Update Quick Install command syntax in readme for auto-yes installation
- Changed installation command to use: curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash -c "bash -s -- -y"
## 2025-03-25 - 2.4.2 - fix(daemon)
Refactor shutdown initiation logic in daemon by moving the initiateShutdown and monitorDuringShutdown methods from the SNMP manager to the daemon, and update calls accordingly

View File

@ -50,11 +50,42 @@ fi
# Detect if script is being piped or run directly
PIPED=0
INTERACTIVE=1
if [ ! -t 0 ]; then
# Being piped, need to clone the repo
PIPED=1
fi
# Check if stdin is a terminal
if [ ! -t 0 ] || [ ! -t 1 ]; then
# Either stdin or stdout is not a terminal, check if -y was provided
if [ $AUTO_YES -ne 1 ]; then
echo "Script detected it's running in a non-interactive environment without -y flag."
echo "Attempting to find a controlling terminal for interactive prompts..."
# Try to use a controlling terminal for user input
if [ -t 1 ]; then
# Stdout is a terminal, use it
exec < /dev/tty 2>/dev/null || INTERACTIVE=0
else
# Try to find controlling terminal
exec < /dev/tty 2>/dev/null || INTERACTIVE=0
fi
if [ $INTERACTIVE -eq 0 ]; then
echo "ERROR: No controlling terminal available for interactive prompts."
echo "For interactive installation (RECOMMENDED):"
echo " curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh -o nupst-install.sh"
echo " sudo bash nupst-install.sh"
echo ""
echo "For non-interactive installation with automatic dependency installation:"
echo " curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash -s -- -y"
exit 1
else
echo "Interactive terminal found, continuing with prompts..."
fi
fi
fi
# Helper function to detect OS type
detect_os() {
if [ -f /etc/os-release ]; then
@ -131,29 +162,37 @@ install_git() {
INSTALL_DIR="/opt/nupst"
REPO_URL="https://code.foss.global/serve.zone/nupst.git"
if [ $PIPED -eq 1 ]; then
echo "Installing NUPST from remote repository..."
# Check if git is installed - needed for both piped and direct execution
if ! command -v git &> /dev/null; then
echo "Git is required but not installed."
# Check if git is installed
if ! command -v git &> /dev/null; then
echo "Git is required but not installed."
if [ $AUTO_YES -eq 1 ]; then
echo "Auto-installing git (-y flag provided)..."
install_git
elif [ $INTERACTIVE -eq 1 ]; then
# If interactive and no -y flag, ask the user
echo "Would you like to install git now? (y/N): "
read -r install_git_prompt
if [ $AUTO_YES -eq 1 ]; then
echo "Auto-installing git (-y flag provided)..."
if [[ "$install_git_prompt" =~ ^[Yy]$ ]]; then
install_git
else
read -p "Would you like to install git now? (y/N): " install_git_prompt
if [[ "$install_git_prompt" =~ ^[Yy]$ ]]; then
install_git
else
echo "Git installation skipped. Please install git manually and run the installer again."
echo "Alternatively, you can run the installer with -y flag to automatically install git:"
echo " sudo bash install.sh -y"
exit 1
fi
echo "Git installation skipped. Please install git manually and run the installer again."
echo "Alternatively, you can run the installer with -y flag to automatically install git:"
echo " sudo bash install.sh -y"
exit 1
fi
else
# Non-interactive mode without -y flag
echo "Error: Git is required but not installed."
echo "In non-interactive mode, use -y flag to auto-install dependencies:"
echo " curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash -s -- -y"
exit 1
fi
fi
if [ $PIPED -eq 1 ]; then
echo "Installing NUPST from remote repository..."
# Check if installation directory exists
if [ -d "$INSTALL_DIR" ] && [ -d "$INSTALL_DIR/.git" ]; then
@ -196,12 +235,47 @@ if [ $PIPED -eq 1 ]; then
# Set script directory to the cloned repo
SCRIPT_DIR="$INSTALL_DIR"
else
# Running directly from within the repo
# Running directly from within the repo or downloaded script
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# When running from a downloaded script in a different location
# we need to clone the repository first
if [ ! -f "$SCRIPT_DIR/setup.sh" ]; then
echo "Running installer from downloaded script outside repository."
echo "Will clone the repository to $INSTALL_DIR..."
# Create installation directory if needed
if [ -d "$INSTALL_DIR" ]; then
echo "Removing previous installation at $INSTALL_DIR..."
rm -rf "$INSTALL_DIR"
fi
mkdir -p "$INSTALL_DIR"
# Clone the repository
echo "Cloning NUPST repository to $INSTALL_DIR..."
git clone --depth 1 $REPO_URL "$INSTALL_DIR"
if [ $? -ne 0 ]; then
echo "Failed to clone repository. Please check your internet connection."
exit 1
fi
# Update script directory to use the cloned repo
SCRIPT_DIR="$INSTALL_DIR"
fi
fi
# Run setup script
echo "Running setup script..."
if [ ! -f "$SCRIPT_DIR/setup.sh" ]; then
echo "ERROR: Setup script not found at $SCRIPT_DIR/setup.sh"
echo "Current directory: $(pwd)"
echo "Script directory: $SCRIPT_DIR"
ls -la "$SCRIPT_DIR"
exit 1
fi
bash "$SCRIPT_DIR/setup.sh"
# Install globally

View File

@ -1,6 +1,6 @@
{
"name": "@serve.zone/nupst",
"version": "2.4.2",
"version": "2.5.1",
"description": "Node.js UPS Shutdown Tool for SNMP-enabled UPS devices",
"main": "dist/index.js",
"bin": {

View File

@ -19,13 +19,21 @@ NUPST is a command-line tool that monitors SNMP-enabled UPS devices and initiate
### Quick Install (One-line command)
```bash
# Install directly without cloning the repository (requires root privileges)
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
# Method 1: Download and run (most reliable across all environments)
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh -o nupst-install.sh && sudo bash nupst-install.sh && rm nupst-install.sh
```
# Install with auto-yes for dependencies (will install git automatically if needed)
```bash
# Method 2: Pipe with automatic yes for dependencies (non-interactive)
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash -s -- -y
```
```bash
# Method 3: Process substitution (only on systems that support /dev/fd/)
# Note: This may fail on some systems with "No such file or directory" errors
sudo bash <(curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh)
```
### Direct from Git
```bash

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@serve.zone/nupst',
version: '2.4.2',
version: '2.5.1',
description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices'
}

View File

@ -533,6 +533,9 @@ Options:
// Test the connection if requested
await this.optionallyTestConnection(config, prompt);
// Check if service is running and restart it if needed
await this.restartServiceIfRunning();
console.log('\nSetup complete!');
await this.optionallyEnableService(prompt);
}
@ -833,6 +836,44 @@ Options:
}
}
/**
* Check if the systemd service is running and restart it if it is
* This is useful after configuration changes
*/
private async restartServiceIfRunning(): Promise<void> {
try {
// Check if the service is active
const isActive = execSync('systemctl is-active nupst.service || true').toString().trim() === 'active';
if (isActive) {
// Service is running, restart it
console.log('┌─ Service Update ─────────────────────────┐');
console.log('│ Configuration has changed.');
console.log('│ Restarting NUPST service to apply changes...');
try {
if (process.getuid && process.getuid() === 0) {
// We have root access, restart directly
execSync('systemctl restart nupst.service');
console.log('│ Service restarted successfully.');
} else {
// No root access, show instructions
console.log('│ Please restart the service with:');
console.log('│ sudo systemctl restart nupst.service');
}
} catch (error) {
console.log(`│ Error restarting service: ${error.message}`);
console.log('│ You may need to restart the service manually:');
console.log('│ sudo systemctl restart nupst.service');
}
console.log('└──────────────────────────────────────────┘');
}
} catch (error) {
// Ignore errors checking service status
}
}
/**
* Optionally enable and start systemd service
* @param prompt Function to prompt for user input

View File

@ -348,6 +348,14 @@ export class NupstSnmp {
} else if (powerStatusValue === 3) {
powerStatus = 'onBattery';
}
} else if (config.upsModel === 'eaton') {
// Eaton UPS: xupsOutputSource values
// 3=normal/mains, 5=battery, etc.
if (powerStatusValue === 3) {
powerStatus = 'online';
} else if (powerStatusValue === 5) {
powerStatus = 'onBattery';
}
} else {
// Default interpretation for other UPS models
if (powerStatusValue === 1) {
@ -357,14 +365,21 @@ export class NupstSnmp {
}
}
// Convert TimeTicks to minutes for CyberPower runtime (value is in 1/100 seconds)
// Convert to minutes for UPS models with different time units
let processedRuntime = batteryRuntime;
if (config.upsModel === 'cyberpower' && batteryRuntime > 0) {
// TimeTicks is in 1/100 seconds, convert to minutes
// CyberPower: TimeTicks is in 1/100 seconds, convert to minutes
processedRuntime = Math.floor(batteryRuntime / 6000); // 6000 ticks = 1 minute
if (this.debug) {
console.log(`Converting CyberPower runtime from ${batteryRuntime} ticks to ${processedRuntime} minutes`);
}
} else if (config.upsModel === 'eaton' && batteryRuntime > 0) {
// Eaton: Runtime is in seconds, convert to minutes
processedRuntime = Math.floor(batteryRuntime / 60);
if (this.debug) {
console.log(`Converting Eaton runtime from ${batteryRuntime} seconds to ${processedRuntime} minutes`);
}
}
const result = {

View File

@ -25,9 +25,9 @@ export class UpsOidSets {
// Eaton OIDs
eaton: {
POWER_STATUS: '1.3.6.1.4.1.534.1.1.2.0', // Power status
BATTERY_CAPACITY: '1.3.6.1.4.1.534.1.2.4.0', // Battery capacity in percentage
BATTERY_RUNTIME: '1.3.6.1.4.1.534.1.2.1.0', // Remaining runtime in minutes
POWER_STATUS: '1.3.6.1.4.1.534.1.4.4.0', // xupsOutputSource (3=normal/mains, 5=battery)
BATTERY_CAPACITY: '1.3.6.1.4.1.534.1.2.4.0', // xupsBatCapacity (percentage)
BATTERY_RUNTIME: '1.3.6.1.4.1.534.1.2.1.0', // xupsBatTimeRemaining (seconds)
},
// TrippLite OIDs