2026-02-20 11:51:59 +00:00
# ⚡ NUPST — Network UPS Shutdown Tool
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
**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.
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
Distributed as **self-contained binaries ** with zero runtime dependencies. No Node.js, no Python, no package managers. Just download and run.
2025-03-25 09:06:23 +00:00
2026-01-29 17:04:12 +00:00
## Issue Reporting and Security
2026-02-20 11:51:59 +00:00
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/ ](https://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/ ](https://code.foss.global/ ) account to submit Pull Requests directly.
2026-01-29 17:04:12 +00:00
2025-10-20 12:52:26 +00:00
## ✨ Features
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
- **🔌 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
2025-10-20 12:52:26 +00:00
- Power status change triggers
2026-02-20 11:51:59 +00:00
- Webhook notifications (POST/GET)
2026-01-29 17:04:12 +00:00
- Custom shell scripts
2026-02-20 11:51:59 +00:00
- Proxmox VM/LXC shutdown
2025-10-20 12:52:26 +00:00
- Configurable shutdown delays
2026-02-20 11:51:59 +00:00
- **🏭 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
2025-03-25 09:06:23 +00:00
2025-10-20 12:52:26 +00:00
## 🚀 Quick Start
2025-03-25 09:06:23 +00:00
2025-10-20 12:52:26 +00:00
### One-Line Installation
2025-03-25 09:06:23 +00:00
```bash
2025-10-19 21:37:41 +00:00
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
2025-03-25 09:06:23 +00:00
```
2025-10-20 12:52:26 +00:00
### Initial Setup
2025-03-25 13:15:48 +00:00
2025-10-20 12:52:26 +00:00
```bash
2026-02-20 11:51:59 +00:00
# 1. Add your first UPS device (interactive wizard)
2025-10-20 12:52:26 +00:00
sudo nupst ups add
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
# 2. Test the connection
nupst ups test
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
# 3. Enable and start monitoring
sudo nupst service enable
sudo nupst service start
2025-03-25 09:06:23 +00:00
2025-10-20 12:52:26 +00:00
# 4. Check status
nupst service status
```
2025-03-25 09:06:23 +00:00
2025-10-20 12:52:26 +00:00
**That's it!** Your system is now protected. 🛡️
2025-03-25 11:31:24 +00:00
2025-10-20 12:52:26 +00:00
## 📥 Installation
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
### Automated Installer (Recommended)
2025-03-25 11:31:24 +00:00
2025-10-20 12:52:26 +00:00
```bash
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
2025-03-25 11:31:24 +00:00
```
2025-10-20 12:52:26 +00:00
**What it does:**
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
1. Detects your platform (OS + architecture)
2025-10-20 12:52:26 +00:00
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
2026-02-20 11:51:59 +00:00
**Options:**
2025-03-25 09:06:23 +00:00
```bash
2025-10-18 13:33:46 +00:00
# Install specific version
2025-10-20 12:52:26 +00:00
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | \
2025-10-20 13:00:42 +00:00
sudo bash -s -- --version v5.0.0
2025-10-18 13:33:46 +00:00
# Custom installation directory
2025-10-20 12:52:26 +00:00
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | \
sudo bash -s -- --install-dir /usr/local/nupst
2025-03-25 09:06:23 +00:00
2025-10-20 12:52:26 +00:00
# Show help
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | bash -s -- --help
```
2025-03-25 11:31:24 +00:00
2025-10-20 12:52:26 +00:00
### Manual Installation
2025-03-25 11:31:24 +00:00
2026-02-20 11:51:59 +00:00
Download the binary for your platform from [releases ](https://code.foss.global/serve.zone/nupst/releases ):
2025-03-25 11:31:24 +00:00
2025-10-23 12:57:58 +00:00
| 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` |
2025-03-25 11:31:24 +00:00
2025-10-20 12:52:26 +00:00
```bash
2026-02-20 11:51:59 +00:00
# Download (replace with your platform)
2025-10-20 13:00:42 +00:00
curl -sSL https://code.foss.global/serve.zone/nupst/releases/download/v5.0.0/nupst-linux-x64 -o nupst
2025-10-20 12:52:26 +00:00
chmod +x nupst
sudo mv nupst /usr/local/bin/nupst
```
2025-03-25 11:31:24 +00:00
2026-02-20 11:51:59 +00:00
### Via npm
2025-11-09 11:30:39 +00:00
```bash
npm install -g @serve .zone/nupst
```
2026-02-20 11:51:59 +00:00
> This downloads the appropriate pre-compiled binary for your platform during installation.
2025-11-09 11:30:39 +00:00
2025-10-20 12:52:26 +00:00
### Verify Installation
2025-03-25 09:06:23 +00:00
```bash
2025-10-20 12:52:26 +00:00
nupst --version
nupst help
2025-03-25 09:06:23 +00:00
```
2026-02-20 11:51:59 +00:00
## 📖 CLI Reference
2025-03-25 09:06:23 +00:00
2025-10-20 12:52:26 +00:00
### Command Structure
2025-10-18 13:33:46 +00:00
2025-03-25 09:06:23 +00:00
```
2026-02-20 11:51:59 +00:00
nupst <command> [subcommand] [options]
2025-10-20 12:52:26 +00:00
```
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
### Global Options
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
| Flag | Description |
| ---------------- | -------------------------------------- |
| `--version` , `-v` | Show version |
| `--help` , `-h` | Show help |
| `--debug` , `-d` | Enable debug mode (verbose SNMP/UPSD logging) |
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
### Service Management
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst service enable # Install and enable systemd service
nupst service disable # Stop and disable systemd service
nupst service start # Start the service
nupst service stop # Stop the service
nupst service restart # Restart the service
nupst service status # Show service and UPS status
nupst service logs # Tail live service logs (Ctrl+C to exit)
2025-03-25 09:06:23 +00:00
```
2026-02-20 11:51:59 +00:00
### UPS Device Management
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst ups add # Add a new UPS device (interactive wizard)
nupst ups edit [id] # Edit a UPS device
nupst ups remove <id> # Remove a UPS device
nupst ups list # List all UPS devices
nupst ups test # Test all UPS connections
2025-10-20 12:52:26 +00:00
```
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
During `nupst ups add` , you'll choose a communication protocol:
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
- **SNMP** — For network-attached UPS with an SNMP agent (default)
- **UPSD/NIS** — For USB-connected UPS managed by a local NUT server
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
### Group Management
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst group add # Create a new UPS group
nupst group edit <id> # Edit a group
nupst group remove <id> # Remove a group
nupst group list # List all groups
2025-10-20 12:52:26 +00:00
```
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
### Action Management
2025-10-23 12:57:58 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst action add <target-id> # Add action to a UPS or group
nupst action remove <target-id> <idx> # Remove an action by index
nupst action list [target-id] # List actions (optionally for a target)
2025-10-23 12:57:58 +00:00
```
2026-02-20 11:51:59 +00:00
### Pause/Resume
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
Temporarily suppress actions during maintenance (UPS polling continues):
2025-10-23 12:57:58 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst pause # Pause indefinitely
nupst pause --duration 30m # Pause for 30 minutes (auto-resume)
nupst pause --duration 2h # Pause for 2 hours
nupst pause --duration 1d # Pause for 1 day (max: 24h)
nupst resume # Resume immediately
2025-10-23 12:57:58 +00:00
```
2026-02-20 11:51:59 +00:00
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
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
### Feature Management
2025-03-25 09:06:23 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst feature httpServer # Configure HTTP JSON status API
2025-10-20 12:52:26 +00:00
```
2025-03-28 16:19:43 +00:00
2026-02-20 11:51:59 +00:00
### Other Commands
2025-03-28 16:19:43 +00:00
2025-10-20 12:52:26 +00:00
```bash
2026-02-20 11:51:59 +00:00
nupst config show # Display current configuration
nupst update # Update to latest version (requires root)
nupst uninstall # Completely remove NUPST (requires root)
2025-03-25 09:06:23 +00:00
```
2025-10-20 12:52:26 +00:00
## ⚙️ Configuration
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
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.
2025-10-20 12:52:26 +00:00
2026-01-29 17:04:12 +00:00
### Example Configuration
2025-03-25 09:06:23 +00:00
```json
{
2025-10-23 12:57:58 +00:00
"version": "4.2",
2025-03-28 16:19:43 +00:00
"checkInterval": 30000,
2025-10-23 12:57:58 +00:00
"httpServer": {
"enabled": true,
"port": 8080,
"path": "/ups-status",
2026-02-20 11:51:59 +00:00
"authToken": "your-secret-token"
2025-10-23 12:57:58 +00:00
},
2025-03-28 16:19:43 +00:00
"upsDevices": [
{
2025-10-20 12:52:26 +00:00
"id": "ups-main",
"name": "Main Server UPS",
2026-02-20 11:51:59 +00:00
"protocol": "snmp",
2025-03-28 16:19:43 +00:00
"snmp": {
"host": "192.168.1.100",
"port": 161,
"community": "public",
"version": 1,
"timeout": 5000,
"upsModel": "cyberpower"
},
2025-10-20 12:52:26 +00:00
"actions": [
2026-02-20 11:51:59 +00:00
{
"type": "proxmox",
"triggerMode": "onlyThresholds",
"thresholds": { "battery": 30, "runtime": 15 },
"proxmoxHost": "localhost",
"proxmoxPort": 8006,
"proxmoxTokenId": "root@pam !nupst",
"proxmoxTokenSecret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
},
2025-10-20 12:52:26 +00:00
{
"type": "shutdown",
"triggerMode": "onlyThresholds",
2026-02-20 11:51:59 +00:00
"thresholds": { "battery": 20, "runtime": 10 },
2025-10-20 12:52:26 +00:00
"shutdownDelay": 10
}
],
2025-03-28 16:19:43 +00:00
"groups": ["datacenter"]
},
{
2026-02-20 11:51:59 +00:00
"id": "ups-usb",
"name": "Local USB UPS",
"protocol": "upsd",
"upsd": {
"host": "127.0.0.1",
"port": 3493,
"upsName": "ups",
"timeout": 5000
2025-03-28 16:19:43 +00:00
},
2025-10-20 12:52:26 +00:00
"actions": [
{
"type": "shutdown",
"triggerMode": "onlyThresholds",
2026-02-20 11:51:59 +00:00
"thresholds": { "battery": 15, "runtime": 5 },
2025-10-20 12:52:26 +00:00
"shutdownDelay": 5
}
],
2026-02-20 11:51:59 +00:00
"groups": []
2025-03-28 16:19:43 +00:00
}
],
"groups": [
{
"id": "datacenter",
"name": "Data Center",
"mode": "redundant",
2026-02-20 11:51:59 +00:00
"description": "Redundant UPS setup",
2025-10-20 12:52:26 +00:00
"actions": [
{
"type": "shutdown",
"triggerMode": "onlyThresholds",
2026-02-20 11:51:59 +00:00
"thresholds": { "battery": 10, "runtime": 5 },
2025-10-20 12:52:26 +00:00
"shutdownDelay": 15
}
]
2025-03-28 16:19:43 +00:00
}
]
2025-03-25 09:06:23 +00:00
}
```
2026-02-20 11:51:59 +00:00
### 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` ):
2025-03-28 16:19:43 +00:00
2026-02-20 11:51:59 +00:00
| 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 | — |
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
#### UPSD/NIS Settings (`upsd` object)
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
For USB-connected UPS via [NUT (Network UPS Tools) ](https://networkupstools.org/ ):
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
| 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 | — |
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
**NUT variables mapped:** `ups.status` , `battery.charge` , `battery.runtime` , `ups.load` , `ups.realpower` , `output.voltage` , `output.current`
2025-10-19 13:14:18 +00:00
2026-02-20 11:51:59 +00:00
### Action Configuration
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
Actions define automated responses to UPS conditions. They run **sequentially in array order ** , so place Proxmox actions before shutdown actions.
2025-10-19 13:14:18 +00:00
2026-02-20 11:51:59 +00:00
#### Action Types
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
| 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 |
2025-10-19 13:14:18 +00:00
2026-02-20 11:51:59 +00:00
#### 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
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```json
{
"type": "shutdown",
2026-02-20 11:51:59 +00:00
"thresholds": { "battery": 20, "runtime": 10 },
2025-10-20 12:52:26 +00:00
"triggerMode": "onlyThresholds",
"shutdownDelay": 10
}
```
2026-02-20 11:51:59 +00:00
| Field | Description | Default |
| --------------- | ---------------------------------- | ------- |
| `shutdownDelay` | Seconds to wait before shutdown | `5` |
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
#### Webhook Action
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
```json
{
"type": "webhook",
"thresholds": { "battery": 30, "runtime": 15 },
"triggerMode": "powerChangesAndThresholds",
"webhookUrl": "https://hooks.slack.com/services/...",
"webhookMethod": "POST",
"webhookTimeout": 10000
}
```
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
| Field | Description | Default |
| ---------------- | -------------------- | -------- |
| `webhookUrl` | URL to call | Required |
| `webhookMethod` | HTTP method | `POST` |
| `webhookTimeout` | Timeout in ms | `10000` |
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
#### Script Action
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
```json
{
"type": "script",
"thresholds": { "battery": 25, "runtime": 10 },
"triggerMode": "onlyThresholds",
"scriptPath": "pre-shutdown.sh",
"scriptTimeout": 60000
}
```
2025-10-19 13:14:18 +00:00
2026-02-20 11:51:59 +00:00
| Field | Description | Default |
| --------------- | -------------------------------------- | ------- |
| `scriptPath` | Script filename in `/etc/nupst/` | Required |
| `scriptTimeout` | Execution timeout in ms | `60000` |
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
#### 🖥️ Proxmox Action
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
Gracefully shuts down QEMU VMs and LXC containers on a Proxmox node before the host is shut down.
2025-03-28 16:19:43 +00:00
2025-10-20 12:52:26 +00:00
```json
{
2026-02-20 11:51:59 +00:00
"type": "proxmox",
"thresholds": { "battery": 30, "runtime": 15 },
"triggerMode": "onlyThresholds",
"proxmoxHost": "localhost",
"proxmoxPort": 8006,
"proxmoxTokenId": "root@pam !nupst",
"proxmoxTokenSecret": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"proxmoxExcludeIds": [100, 101],
"proxmoxStopTimeout": 120,
"proxmoxForceStop": true,
"proxmoxInsecure": true
2025-10-20 12:52:26 +00:00
}
```
2025-03-28 16:19:43 +00:00
2026-02-20 11:51:59 +00:00
| 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` |
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
**Setting up the API token on Proxmox:**
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
```bash
# Create token with full privileges (no privilege separation)
pveum user token add root@pam nupst --privsep=0
```
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
> ⚠️ **Important:** Place the Proxmox action **before** the shutdown action in the actions array so VMs are stopped before the host shuts down.
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
### Group Configuration
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
Groups coordinate actions across multiple UPS devices:
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
| 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 | — |
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
**Group Modes:**
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
- **`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.
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
### HTTP Server Configuration
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
```bash
# Interactive setup
sudo nupst feature httpServer
```
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
```json
{
"httpServer": {
"enabled": true,
"port": 8080,
"path": "/ups-status",
"authToken": "your-secret-token"
}
}
```
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
**Query the API:**
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
```bash
# Bearer token
curl -H "Authorization: Bearer your-secret-token" http://localhost:8080/ups-status
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
# Query parameter
curl "http://localhost:8080/ups-status?token=your-secret-token"
```
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
**Response format:**
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
```json
{
"upsDevices": [
{
"id": "ups-main",
"name": "Main Server UPS",
"powerStatus": "online",
"batteryCapacity": 100,
"batteryRuntime": 45,
"outputLoad": 23,
"outputPower": 115,
"outputVoltage": 230.5,
"outputCurrent": 0.5,
"consecutiveFailures": 0,
"unreachableSince": 0,
"lastStatusChange": 1729685123456,
"lastCheckTime": 1729685153456
}
],
"paused": false
}
```
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
When monitoring is paused:
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```json
2026-02-20 11:51:59 +00:00
{
"upsDevices": [...],
"paused": true,
"pauseState": {
"pausedAt": 1729685123456,
"pausedBy": "cli",
"resumeAt": 1729686923456
}
2025-10-20 12:52:26 +00:00
}
2025-03-25 09:06:23 +00:00
```
2026-02-20 11:51:59 +00:00
## 🛡️ 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`
2025-10-20 12:52:26 +00:00
## 🖥️ Monitoring
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
### Status Display
2025-10-18 13:33:46 +00:00
2025-03-25 09:06:23 +00:00
```bash
2025-10-20 12:52:26 +00:00
$ nupst service status
UPS Devices (2):
✓ Main Server UPS (online - 100%, 3840min)
2026-02-20 11:51:59 +00:00
Host: 192.168.1.100:161 (SNMP)
2025-10-20 12:52:26 +00:00
Groups: Data Center
2026-02-20 11:51:59 +00:00
Action: proxmox (onlyThresholds: battery<30%, runtime<15min)
2025-10-20 12:52:26 +00:00
Action: shutdown (onlyThresholds: battery<20%, runtime<10min, delay=10s)
2026-02-20 11:51:59 +00:00
✓ Local USB UPS (online - 95%, 2400min)
Host: 127.0.0.1:3493 (UPSD)
2025-10-20 12:52:26 +00:00
Action: shutdown (onlyThresholds: battery<15%, runtime<5min, delay=5s)
Groups (1):
ℹ Data Center (redundant)
2026-02-20 11:51:59 +00:00
UPS Devices (1): Main Server UPS
2025-10-20 12:52:26 +00:00
Action: shutdown (onlyThresholds: battery<10%, runtime<5min, delay=15s)
2025-03-25 09:06:23 +00:00
```
2025-10-20 12:52:26 +00:00
### Live Logs
2025-10-18 13:33:46 +00:00
2025-03-25 09:49:30 +00:00
```bash
2025-10-20 12:52:26 +00:00
nupst service logs
```
```
2026-02-20 11:51:59 +00:00
[2026-02-20 10:30:15] ℹ NUPST daemon started
[2026-02-20 10:30:15] ✓ Connected to Main Server UPS (192.168.1.100)
[2026-02-20 10:30:45] ℹ Status check: All systems normal
[2026-02-20 10:31:15] ⚠ Main Server UPS on battery (85%, 45min remaining)
[2026-02-20 10:35:00] ⚠ UPS Unreachable: Backup UPS (3 consecutive failures)
[2026-02-20 10:37:30] ✓ UPS Recovered: Backup UPS (downtime: 2m 30s)
2025-03-25 09:49:30 +00:00
```
2025-10-20 12:52:26 +00:00
## 🔒 Security
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
### Architecture
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
- **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
2025-10-18 13:33:46 +00:00
### SNMP Security
2025-10-20 12:52:26 +00:00
Full SNMPv3 support with authentication and encryption:
2026-02-20 11:51:59 +00:00
| Security Level | Description |
| -------------- | ------------------------------------------ |
| `noAuthNoPriv` | No authentication, no encryption |
| `authNoPriv` | MD5/SHA authentication without encryption |
| `authPriv` | Authentication + DES/AES encryption ✅ |
2025-03-25 09:49:30 +00:00
2025-10-18 13:33:46 +00:00
### Network Security
2026-02-20 11:51:59 +00:00
- Connects only to UPS devices and optionally Proxmox on local network
- HTTP API disabled by default; token-required when enabled
- No external internet connections
2025-10-18 13:33:46 +00:00
### Verifying Downloads
2025-03-25 09:49:30 +00:00
```bash
2025-10-20 13:00:42 +00:00
curl -sSL https://code.foss.global/serve.zone/nupst/releases/download/v5.0.0/nupst-linux-x64 -o nupst
curl -sSL https://code.foss.global/serve.zone/nupst/releases/download/v5.0.0/SHA256SUMS.txt -o SHA256SUMS.txt
2025-10-18 13:33:46 +00:00
sha256sum -c SHA256SUMS.txt --ignore-missing
2025-03-25 09:49:30 +00:00
```
2026-02-20 11:51:59 +00:00
## 🔒 Supported UPS Models
2025-10-19 13:05:51 +00:00
2026-02-20 11:51:59 +00:00
### SNMP-based
2025-10-19 13:05:51 +00:00
2026-02-20 11:51:59 +00:00
| 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 |
2025-10-19 13:05:51 +00:00
2026-02-20 11:51:59 +00:00
**Custom OIDs example:**
2025-10-19 13:05:51 +00:00
2026-02-20 11:51:59 +00:00
```json
{
"upsModel": "custom",
"customOIDs": {
"POWER_STATUS": "1.3.6.1.4.1.1234.1.1.0",
"BATTERY_CAPACITY": "1.3.6.1.4.1.1234.1.2.0",
"BATTERY_RUNTIME": "1.3.6.1.4.1.1234.1.3.0"
}
}
```
2025-10-23 12:57:58 +00:00
2026-02-20 11:51:59 +00:00
### UPSD/NIS-based
2025-10-19 13:14:18 +00:00
2026-02-20 11:51:59 +00:00
Any UPS supported by [NUT (Network UPS Tools) ](https://networkupstools.org/ ) — this covers **hundreds of models ** from virtually every manufacturer, including USB-connected devices. Check the [NUT hardware compatibility list ](https://networkupstools.org/stable-hcl.html ).
2025-10-19 13:05:51 +00:00
2026-02-20 11:51:59 +00:00
## 🔄 Updating
2025-10-19 13:05:51 +00:00
2026-02-20 11:51:59 +00:00
### Built-in Update
2025-10-19 13:14:18 +00:00
2026-02-20 11:51:59 +00:00
```bash
sudo nupst update
2025-10-19 13:05:51 +00:00
```
2026-02-20 11:51:59 +00:00
### Re-run Installer
2025-10-19 13:14:18 +00:00
2025-10-19 13:05:51 +00:00
```bash
2026-02-20 11:51:59 +00:00
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
2025-10-19 13:05:51 +00:00
```
2026-02-20 11:51:59 +00:00
The installer preserves your configuration and restarts the service if it was running.
2025-10-20 12:52:26 +00:00
## 🗑️ Uninstallation
2025-10-19 13:14:18 +00:00
2025-10-19 13:05:51 +00:00
```bash
2026-02-20 11:51:59 +00:00
# Interactive uninstall
sudo nupst uninstall
2025-10-20 12:52:26 +00:00
2026-02-20 11:51:59 +00:00
# Or manual removal
sudo nupst service disable
2025-10-20 12:52:26 +00:00
sudo rm /usr/local/bin/nupst
sudo rm -rf /opt/nupst
sudo rm -rf /etc/nupst
sudo rm /etc/systemd/system/nupst.service
sudo systemctl daemon-reload
2025-10-19 13:05:51 +00:00
```
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
## 🔧 Troubleshooting
2025-10-18 13:33:46 +00:00
### Binary Won't Execute
2025-03-26 13:49:47 +00:00
```bash
2025-10-18 13:33:46 +00:00
chmod +x /opt/nupst/nupst
2026-02-20 11:51:59 +00:00
uname -m # x86_64 = x64, aarch64 = arm64
2025-03-26 13:49:47 +00:00
```
2025-03-25 09:49:30 +00:00
2025-10-18 13:33:46 +00:00
### Service Won't Start
2025-03-25 09:49:30 +00:00
2025-10-18 13:33:46 +00:00
```bash
sudo systemctl status nupst
sudo journalctl -u nupst -n 50
nupst config show
2025-10-20 12:52:26 +00:00
nupst ups test --debug
2025-10-18 13:33:46 +00:00
```
2025-03-25 09:49:30 +00:00
2025-10-18 13:33:46 +00:00
### Can't Connect to UPS
2025-03-25 09:49:30 +00:00
2025-10-18 13:33:46 +00:00
```bash
2026-02-20 11:51:59 +00:00
# SNMP
2025-10-18 13:33:46 +00:00
nupst ups test --debug
2026-02-20 11:51:59 +00:00
ping <ups-ip>
nc -zv <ups-ip> 161
2025-03-25 09:49:30 +00:00
2026-02-20 11:51:59 +00:00
# UPSD/NUT
nc -zv 127.0.0.1 3493
upsc ups@localhost # if NUT CLI is installed
2025-10-18 13:33:46 +00:00
```
2025-03-26 13:27:47 +00:00
2026-02-20 11:51:59 +00:00
### Proxmox VMs Not Shutting Down
2025-10-18 13:33:46 +00:00
```bash
2026-02-20 11:51:59 +00:00
# Verify API token works
curl -k -H "Authorization: PVEAPIToken=root@pam !nupst=YOUR-SECRET" \
https://localhost:8006/api2/json/nodes/$(hostname)/qemu
2025-10-18 13:33:46 +00:00
2026-02-20 11:51:59 +00:00
# Check token permissions
pveum user token list root@pam
2025-10-18 13:33:46 +00:00
```
2026-02-20 11:51:59 +00:00
### Actions Not Triggering
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```bash
nupst action list
nupst service logs
2026-02-20 11:51:59 +00:00
# Check if monitoring is paused
nupst service status
2025-10-20 12:52:26 +00:00
```
## 📊 System Changes
### File System
2025-10-23 12:57:58 +00:00
| Path | Description |
| ----------------------------------- | -------------------- |
| `/opt/nupst/nupst` | Pre-compiled binary |
| `/usr/local/bin/nupst` | Symlink to binary |
| `/etc/nupst/config.json` | Configuration file |
2026-02-20 11:51:59 +00:00
| `/etc/nupst/pause` | Pause state file (when paused) |
2025-10-20 12:52:26 +00:00
| `/etc/systemd/system/nupst.service` | Systemd service unit |
### Services
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
- Creates `nupst.service` systemd unit (when enabled)
- Runs with root permissions (required for system shutdown)
2025-10-19 13:14:18 +00:00
2025-10-20 12:52:26 +00:00
### Network
2026-02-20 11:51:59 +00:00
- 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)
2025-10-20 12:52:26 +00:00
- No external internet connections
## 🚀 Migration from v3.x
```bash
curl -sSL https://code.foss.global/serve.zone/nupst/raw/branch/main/install.sh | sudo bash
```
2026-02-20 11:51:59 +00:00
The installer auto-detects v3.x installations, migrates the configuration, and swaps the binary. Your settings are preserved.
2025-10-20 12:52:26 +00:00
2026-01-29 17:04:12 +00:00
| Aspect | v3.x | v4.x+ |
2025-10-23 12:57:58 +00:00
| ------------------------ | -------------------------- | ----------------------------- |
2026-02-20 11:51:59 +00:00
| **Runtime ** | Node.js + npm | Deno (self-contained) |
2025-10-23 12:57:58 +00:00
| **Distribution ** | Git repo + npm install | Pre-compiled binaries |
2026-02-20 11:51:59 +00:00
| **Runtime Dependencies ** | node_modules | Zero |
| **Size ** | ~150MB | ~80MB |
2025-10-23 12:57:58 +00:00
| **Commands ** | Flat (`nupst add` ) | Subcommands (`nupst ups add` ) |
2025-10-20 12:52:26 +00:00
## 💻 Development
**Requirements:** [Deno ](https://deno.land/ ) v1.x or later
2025-10-18 13:33:46 +00:00
```bash
git clone https://code.foss.global/serve.zone/nupst.git
cd nupst
2025-10-20 12:52:26 +00:00
# Run directly
2025-10-18 13:33:46 +00:00
deno run --allow-all mod.ts help
2026-02-20 11:51:59 +00:00
# Type check
deno task check
# Lint
deno task lint
2025-10-20 12:52:26 +00:00
# Run tests
deno test --allow-all test/
2025-10-18 13:33:46 +00:00
# Compile for current platform
deno compile --allow-all --output nupst mod.ts
# Compile for all platforms
2025-10-20 12:52:26 +00:00
deno task compile
2025-10-18 13:33:46 +00:00
```
2025-10-20 12:52:26 +00:00
### Project Structure
2025-10-18 13:33:46 +00:00
2025-10-20 12:52:26 +00:00
```
nupst/
2026-02-20 11:51:59 +00:00
├── mod.ts # Entry point
├── deno.json # Deno configuration
2025-10-20 12:52:26 +00:00
├── ts/
2026-02-20 11:51:59 +00:00
│ ├── cli.ts # CLI command routing
│ ├── nupst.ts # Main coordinator class
│ ├── daemon.ts # Background monitoring daemon
│ ├── systemd.ts # Systemd service management
│ ├── http-server.ts # Optional HTTP JSON API
│ ├── constants.ts # Centralized constants
│ ├── snmp/ # SNMP protocol implementation
│ ├── upsd/ # UPSD/NIS protocol implementation (NUT)
│ ├── protocol/ # Protocol abstraction layer
│ ├── actions/ # Action system (shutdown, webhook, script, proxmox)
│ ├── migrations/ # Config version migrations
│ ├── helpers/ # Utility functions
│ ├── interfaces/ # Shared TypeScript interfaces
│ └── cli/ # CLI command handlers
├── scripts/ # Build and install scripts
└── test/ # Test files
2025-10-18 13:33:46 +00:00
```
2025-03-25 11:36:11 +00:00
## License and Legal Information
2025-03-25 09:06:23 +00:00
2026-02-20 11:51:59 +00:00
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE ](./LICENSE ) file.
2025-03-25 11:36:11 +00:00
2026-02-20 11:51:59 +00:00
**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.
2025-03-25 11:36:11 +00:00
### Trademarks
2026-02-20 11:51:59 +00:00
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.
2026-01-29 17:04:12 +00:00
2026-02-20 11:51:59 +00:00
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.
2025-03-25 11:36:11 +00:00
### Company Information
2026-02-20 11:51:59 +00:00
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
2025-03-25 11:36:11 +00:00
2026-01-29 17:04:12 +00:00
For any legal inquiries or further information, please contact us via email at hello@task .vc.
2025-03-25 11:36:11 +00:00
2026-02-20 11:51:59 +00:00
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.