nupst

9 min read Original article ↗

NUPST — Network UPS Shutdown Tool

Keep your systems safe when the power goes out. NUPST is a lightweight, battle-tested CLI tool that monitors UPS devices via SNMP or NUT (UPSD) and orchestrates graceful shutdowns during power emergencies — including Proxmox VMs, LXC containers, and the host itself.

Distributed as self-contained binaries with zero runtime dependencies. No Node.js, no Python, no package managers. Just download and run.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

Features

  • 🔌 Multi-UPS Support — Monitor multiple UPS devices from a single daemon
  • 📡 Dual Protocol Support — SNMP (v1/v2c/v3) for network UPS + UPSD/NIS for USB-connected UPS via NUT
  • 🖥️ Proxmox Integration — Gracefully shut down QEMU VMs and LXC containers before host shutdown
  • 👥 Group Management — Organize UPS devices into groups with flexible operating modes
    • Redundant Mode — Only trigger actions when ALL UPS devices in a group are critical
    • Non-Redundant Mode — Trigger actions when ANY UPS device is critical
  • ⚙️ Action System — Define custom responses with flexible trigger conditions
    • Battery & runtime threshold triggers
    • Power status change triggers
    • Webhook notifications (POST/GET)
    • Custom shell scripts
    • Proxmox VM/LXC shutdown
    • Configurable shutdown delays
  • 🏭 Multiple UPS Brands — CyberPower, APC, Eaton, TrippLite, Liebert/Vertiv, and custom OID configurations
  • 🌐 HTTP API — Optional JSON status endpoint with token authentication
  • ⏸️ Pause/Resume — Temporarily suppress actions during maintenance windows
  • 🛡️ Network Loss Detection — Detects unreachable UPS devices and prevents false shutdowns
  • 📊 Power Metrics — Monitor output load, power (watts), voltage, and current
  • 📦 Single Binary — Zero runtime dependencies. Download, chmod +x, run.
  • 🖥️ Cross-Platform — Linux (x64, ARM64), macOS (Intel, Apple Silicon), Windows

🚀 Quick Start

One-Line Installation

Initial Setup

That's it! Your system is now protected. 🛡️

📥 Installation

What it does:

  1. Detects your platform (OS + architecture)
  2. Downloads the latest pre-compiled binary
  3. Installs to /opt/nupst/nupst
  4. Creates symlink at /usr/local/bin/nupst
  5. Preserves existing configuration

Options:

Manual Installation

Download the binary for your platform from releases:

Platform Binary
Linux x64 nupst-linux-x64
Linux ARM64 nupst-linux-arm64
macOS Intel nupst-macos-x64
macOS Apple Silicon nupst-macos-arm64
Windows x64 nupst-windows-x64.exe

Via npm

This downloads the appropriate pre-compiled binary for your platform during installation.

Verify Installation

📖 CLI Reference

Command Structure

Global Options

Flag Description
--version, -v Show version
--help, -h Show help
--debug, -d Enable debug mode (verbose SNMP/UPSD logging)

Service Management

UPS Device Management

During nupst ups add, you'll choose a communication protocol:

  • SNMP — For network-attached UPS with an SNMP agent (default)
  • UPSD/NIS — For USB-connected UPS managed by a local NUT server

Group Management

Action Management

Pause/Resume

Temporarily suppress actions during maintenance (UPS polling continues):

When paused:

  • UPS polling continues (status is still visible)
  • All actions are suppressed (no shutdowns, webhooks, scripts)
  • The HTTP API response includes "paused": true
  • Status display shows a [PAUSED] indicator

Feature Management

Other Commands

⚙️ Configuration

NUPST stores configuration at /etc/nupst/config.json. The easiest way to configure is through the interactive CLI commands, but you can also edit the JSON directly.

Example Configuration

UPS Device Configuration

Protocol Selection

Each UPS device has a protocol field:

Protocol Use Case Default Port
snmp Network-attached UPS with SNMP agent 161
upsd USB-connected UPS via local NUT server 3493

SNMP Settings (snmp object)

Field Description Values / Default
host IP address or hostname e.g., "192.168.1.100"
port SNMP port Default: 161
version SNMP version 1, 2, or 3
timeout Timeout in milliseconds Default: 5000
upsModel UPS brand/model cyberpower, apc, eaton, tripplite, liebert, custom
community Community string (v1/v2c) Default: "public"

SNMPv3 fields (when version: 3):

Field Description Values
securityLevel Security level noAuthNoPriv, authNoPriv, authPriv
username Authentication username
authProtocol Auth protocol MD5 or SHA
authKey Auth password
privProtocol Encryption protocol DES or AES
privKey Encryption password

UPSD/NIS Settings (upsd object)

For USB-connected UPS via NUT (Network UPS Tools):

Field Description Default
host NUT server address 127.0.0.1
port NUT UPSD port 3493
upsName NUT device name ups
timeout Connection timeout (ms) 5000
username Optional auth username
password Optional auth password

NUT variables mapped: ups.status, battery.charge, battery.runtime, ups.load, ups.realpower, output.voltage, output.current

Action Configuration

Actions define automated responses to UPS conditions. They run sequentially in array order, so place Proxmox actions before shutdown actions.

Action Types

Type Description
shutdown Graceful system shutdown with configurable delay
webhook HTTP POST/GET notification to external services
script Execute custom shell scripts from /etc/nupst/
proxmox Shut down Proxmox QEMU VMs and LXC containers via REST API

Common Fields

Field Description Values / Default
type Action type shutdown, webhook, script, proxmox
thresholds Battery and runtime limits { "battery": 0-100, "runtime": minutes }
triggerMode When to trigger See Trigger Modes below

Trigger Modes

Mode Description
onlyPowerChanges Only when power status changes (online ↔ onBattery)
onlyThresholds Only when battery or runtime thresholds are violated
powerChangesAndThresholds On power changes OR threshold violations (default)
anyChange On every polling cycle

Shutdown Action

Field Description Default
shutdownDelay Seconds to wait before shutdown 5

Webhook Action

Field Description Default
webhookUrl URL to call Required
webhookMethod HTTP method POST
webhookTimeout Timeout in ms 10000

Script Action

Field Description Default
scriptPath Script filename in /etc/nupst/ Required
scriptTimeout Execution timeout in ms 60000

🖥️ Proxmox Action

Gracefully shuts down QEMU VMs and LXC containers on a Proxmox node before the host is shut down.

Field Description Default
proxmoxHost Proxmox API host localhost
proxmoxPort Proxmox API port 8006
proxmoxNode Proxmox node name Auto-detect via hostname
proxmoxTokenId API token ID (e.g. root@pam!nupst) Required
proxmoxTokenSecret API token secret (UUID) Required
proxmoxExcludeIds VM/CT IDs to skip []
proxmoxStopTimeout Seconds to wait for graceful shutdown 120
proxmoxForceStop Force-stop VMs/CTs that don't shut down true
proxmoxInsecure Skip TLS verification (self-signed certs) true

Setting up the API token on Proxmox:

⚠️ Important: Place the Proxmox action before the shutdown action in the actions array so VMs are stopped before the host shuts down.

Group Configuration

Groups coordinate actions across multiple UPS devices:

Field Description Values
id Unique group identifier
name Human-readable name
mode Group operating mode redundant, nonRedundant
description Optional description
actions Array of action configurations

Group Modes:

  • redundant — Actions trigger only when ALL UPS devices in the group are critical. Use for setups with backup power units.
  • nonRedundant — Actions trigger when ANY UPS device is critical. Use when all UPS units must be operational.

HTTP Server Configuration

Query the API:

Response format:

When monitoring is paused:

🛡️ Network Loss Detection

NUPST tracks communication failures per UPS device:

  • After 3 consecutive failures, the UPS status transitions to unreachable
  • Shutdown actions will NOT fire on unreachable — this prevents false shutdowns from network glitches
  • Webhook and script actions still fire, allowing you to send alerts
  • When connectivity is restored, NUPST logs a recovery event with downtime duration
  • The failure counter is capped at 100 to prevent overflow

Power status values: online | onBattery | unknown | unreachable

🖥️ Monitoring

Status Display

Live Logs

🔒 Security

Architecture

  • Single Binary — Self-contained executable with zero runtime dependencies
  • Minimal Attack Surface — Compiled Deno binary with only essential functionality
  • Reduced Supply Chain Risk — Pre-compiled binaries with SHA256 checksums
  • No Telemetry — No data sent to external servers

SNMP Security

Full SNMPv3 support with authentication and encryption:

Security Level Description
noAuthNoPriv No authentication, no encryption
authNoPriv MD5/SHA authentication without encryption
authPriv Authentication + DES/AES encryption

Network Security

  • Connects only to UPS devices and optionally Proxmox on local network
  • HTTP API disabled by default; token-required when enabled
  • No external internet connections

Verifying Downloads

🔒 Supported UPS Models

SNMP-based

Brand Config Value Notes
CyberPower cyberpower Full support including power metrics
APC apc Smart-UPS, Back-UPS series
Eaton eaton Eaton/Powerware UPS
TrippLite tripplite SmartPro and similar
Liebert/Vertiv liebert GXT, PSI series
Custom custom Provide your own OID mappings

Custom OIDs example:

UPSD/NIS-based

Any UPS supported by NUT (Network UPS Tools) — this covers hundreds of models from virtually every manufacturer, including USB-connected devices. Check the NUT hardware compatibility list.

🔄 Updating

Built-in Update

Re-run Installer

The installer preserves your configuration and restarts the service if it was running.

🗑️ Uninstallation

🔧 Troubleshooting

Binary Won't Execute

Service Won't Start

Can't Connect to UPS

Proxmox VMs Not Shutting Down

Actions Not Triggering

📊 System Changes

File System

Path Description
/opt/nupst/nupst Pre-compiled binary
/usr/local/bin/nupst Symlink to binary
/etc/nupst/config.json Configuration file
/etc/nupst/pause Pause state file (when paused)
/etc/systemd/system/nupst.service Systemd service unit

Services

  • Creates nupst.service systemd unit (when enabled)
  • Runs with root permissions (required for system shutdown)

Network

  • Outbound SNMP to UPS devices (port 161)
  • Outbound TCP to NUT servers (port 3493)
  • Outbound HTTPS to Proxmox API (port 8006, if configured)
  • Optional inbound HTTP server (disabled by default)
  • No external internet connections

🚀 Migration from v3.x

The installer auto-detects v3.x installations, migrates the configuration, and swaps the binary. Your settings are preserved.

Aspect v3.x v4.x+
Runtime Node.js + npm Deno (self-contained)
Distribution Git repo + npm install Pre-compiled binaries
Runtime Dependencies node_modules Zero
Size ~150MB ~80MB
Commands Flat (nupst add) Subcommands (nupst ups add)

💻 Development

Requirements: Deno v1.x or later

Project Structure

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the LICENSE file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.