Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
2737fca294 | |||
896233914f | |||
5bb775b17d | |||
ae8219acf7 | |||
4ad383884c | |||
65a9d1c798 | |||
f583e1466f | |||
9d893a97b6 |
24
changelog.md
24
changelog.md
@ -1,5 +1,29 @@
|
||||
# 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
|
||||
|
||||
|
85
install.sh
85
install.sh
@ -162,37 +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
|
||||
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 [[ "$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
|
||||
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"
|
||||
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
|
||||
@ -235,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
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@serve.zone/nupst",
|
||||
"version": "2.4.6",
|
||||
"version": "2.5.1",
|
||||
"description": "Node.js UPS Shutdown Tool for SNMP-enabled UPS devices",
|
||||
"main": "dist/index.js",
|
||||
"bin": {
|
||||
|
@ -20,8 +20,7 @@ NUPST is a command-line tool that monitors SNMP-enabled UPS devices and initiate
|
||||
|
||||
```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
|
||||
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
|
||||
```
|
||||
|
||||
```bash
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/nupst',
|
||||
version: '2.4.6',
|
||||
version: '2.5.1',
|
||||
description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices'
|
||||
}
|
||||
|
41
ts/cli.ts
41
ts/cli.ts
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user