GitHunt
SC

scttfrdmn/cyberpower-monitor

Go library and CLI for monitoring CyberPower UPS devices with RMCARD 205/305 network cards via SNMP. Features 80%+ test coverage, Prometheus metrics export, device discovery, and production-ready error handling. Library-first design with comprehensive examples.

cyberpower-monitor

Go Version
Go Report Card
Coverage
License
GoDoc

Go library and CLI for monitoring CyberPower UPS devices with RMCARD 205/305 network monitoring cards.

Table of Contents

Features

  • ๐Ÿ“š Library-first design - Clean, well-documented Go API
  • ๐Ÿ”Œ SNMP protocol - SNMPv1 and SNMPv3 support (REST API planned)
  • ๐ŸŽฏ Selective queries - Get only the metrics you need
  • โšก High performance - Efficient SNMP communication
  • ๐Ÿงช Excellent test coverage - 80.4% coverage with integration tests
  • ๐Ÿ› ๏ธ Production-ready - Proper error handling, timeouts, retries
  • ๐Ÿ”„ Context-aware - Full context.Context support for cancellation
  • ๐Ÿ“Š Prometheus ready - Built-in metrics export support
  • ๐Ÿ” Device discovery - Automatic network scanning for RMCARD devices

Library Installation

go get github.com/scttfrdmn/cyberpower-monitor/pkg/cyberpower

Library Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/scttfrdmn/cyberpower-monitor/pkg/cyberpower"
)

func main() {
    ctx := context.Background()

    // Create a client using SNMP
    client, err := cyberpower.NewClient(ctx,
        cyberpower.WithSNMP("192.168.1.100", "public"))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // Get UPS status
    status, err := client.GetStatus(ctx)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Battery: %d%%\n", status.Battery.Capacity)
    fmt.Printf("Load: %d%% (%dW)\n", status.Load.Percentage, status.Load.Watts)
    fmt.Printf("Status: %s\n", status.Status)
}

More Examples

See the examples/ directory for complete, runnable examples:

  • Simple Usage - Basic status monitoring

    cd examples/simple && go run main.go
  • Prometheus Integration - Custom Prometheus exporter with HTTP server

    cd examples/prometheus && go run main.go
    # Visit http://localhost:9100/metrics
  • Continuous Monitoring - Poll UPS every 5 seconds with alerts

    cd examples/continuous && go run main.go
  • Testing with Mocks - How to test code using the library

    cd examples/testing && go test -v

Each example demonstrates different library usage patterns and can be used as a starting point for your own applications.

Library API

Creating a Client

// SNMP (recommended)
client, err := cyberpower.NewClient(ctx,
    cyberpower.WithSNMP("192.168.1.100", "public"))

// SNMPv3 with authentication
client, err := cyberpower.NewClient(ctx,
    cyberpower.WithSNMPv3("192.168.1.100", "username", "password"))

// REST API (planned - not yet implemented)
// client, err := cyberpower.NewClient(ctx,
//     cyberpower.WithREST("192.168.1.100", "admin", "password"))

// Custom timeout and port
client, err := cyberpower.NewClient(ctx,
    cyberpower.WithSNMP("192.168.1.100", "public"),
    cyberpower.WithTimeout(10*time.Second),
    cyberpower.WithPort(161))

Querying Metrics

// Get complete status (all metrics)
status, err := client.GetStatus(ctx)

// Get specific metrics (more efficient)
battery, err := client.GetBattery(ctx)
load, err := client.GetLoad(ctx)
input, err := client.GetInput(ctx)
output, err := client.GetOutput(ctx)

Continuous Monitoring

ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()

for {
    select {
    case <-ticker.C:
        status, err := client.GetStatus(ctx)
        if err != nil {
            log.Printf("Error: %v", err)
            continue
        }
        fmt.Printf("Battery: %d%%, Load: %d%%\n",
            status.Battery.Capacity, status.Load.Percentage)

    case <-ctx.Done():
        return
    }
}

CLI Installation

go install github.com/scttfrdmn/cyberpower-monitor/cmd/cyberpower-monitor@latest

Or build from source:

git clone https://github.com/scttfrdmn/cyberpower-monitor
cd cyberpower-monitor
make build

CLI Usage

The CLI demonstrates various library usage patterns and provides a useful standalone monitoring tool.

Discovery

# Discover RMCARD devices on your network
cyberpower-monitor discover

# Discover on specific subnet
cyberpower-monitor discover --subnet 192.168.1.0/24

# Quick scan (faster, less detailed)
cyberpower-monitor discover --quick

# Increase scan speed
cyberpower-monitor discover --concurrent 50

# JSON output
cyberpower-monitor discover --json

How it works: The discover command scans your network for SNMP-enabled devices and filters for CyberPower enterprise OID (1.3.6.1.4.1.3808). It automatically detects your local subnet or you can specify one manually.

Basic Commands

# Show complete UPS status
cyberpower-monitor status --host 192.168.1.100

# Show only battery information
cyberpower-monitor battery --host 192.168.1.100

# Show only load information
cyberpower-monitor load --host 192.168.1.100

# JSON output (for scripting)
cyberpower-monitor status --host 192.168.1.100 --json

Continuous Monitoring

# Watch mode - live updates every 5 seconds
cyberpower-monitor watch --host 192.168.1.100 --interval 5s

Prometheus Integration

# Export Prometheus metrics (one-shot)
cyberpower-monitor export --host 192.168.1.100 --format prometheus

# Run Prometheus HTTP exporter (continuous)
cyberpower-monitor export --host 192.168.1.100 --listen :9100
# Metrics available at http://localhost:9100/metrics

Using REST API

cyberpower-monitor status --host 192.168.1.100 --protocol rest \
  --username admin --password secret

Configuration via Environment

export CYBERPOWER_HOST=192.168.1.100
export CYBERPOWER_COMMUNITY=public
cyberpower-monitor status

Supported Metrics

  • Battery: Capacity (%), voltage, status, remaining time, temperature
  • Load: Percentage (%), watts, amperage
  • Input: Voltage, frequency, status
  • Output: Voltage, frequency, current, power
  • Status: Overall UPS status (online, on battery, low battery, etc.)

Requirements

  • Go 1.23 or later
  • CyberPower UPS with RMCARD 205 or RMCARD 305
  • Network access to the RMCARD (SNMP port 161 or HTTP/HTTPS)

RMCARD Firmware

  • SNMP: Works with all firmware versions
  • REST API: Requires firmware v1.4.4 or later (released April 2025)

Testing

The library has comprehensive test coverage with both unit and integration tests.

Test Coverage: 80.4% โœ…

The project exceeds Go best practices for library code (70-80% coverage):

Unit Tests (no hardware required):

  • Coverage: 37.4%
  • Tests: 42 test functions
  • Tests configuration, types, error handling, SNMP mappers
  • Run with: go test ./pkg/cyberpower/...

Integration Tests (requires RMCARD205):

  • Coverage: 80.4%
  • Tests: 16 test functions
  • Tests all operations against real hardware
  • Run with: go test -tags=integration ./pkg/cyberpower/...

Running Tests

# Unit tests only (fast, no hardware needed)
go test ./pkg/cyberpower/...

# Integration tests (requires RMCARD at 192.168.1.172)
go test -tags=integration ./pkg/cyberpower/...

# Custom UPS for integration tests
UPS_HOST=192.168.1.100 UPS_COMMUNITY=private go test -tags=integration ./pkg/cyberpower/...

# Generate coverage report
go test -tags=integration -coverprofile=coverage.out ./pkg/cyberpower/...
go tool cover -html=coverage.out

What's Tested

โœ… All client configuration options
โœ… Client factory and error cases
โœ… All SNMP operations (GetStatus, GetBattery, GetLoad, GetInput, GetOutput)
โœ… Connection management and Close()
โœ… Error handling (timeouts, invalid credentials, connection failures)
โœ… Type system and String() methods
โœ… Data validation and range checking
โœ… Context cancellation
โœ… Multiple concurrent clients

Development

Setup

# Clone repository
git clone https://github.com/scttfrdmn/cyberpower-monitor
cd cyberpower-monitor

# Install dependencies
go mod download

# Install development tools (optional)
make install-tools

Quality Checks

# Run all quality checks (gofmt, go vet, staticcheck, golint, gocyclo)
make check

# Run tests with coverage
make test

# Run integration tests (requires RMCARD)
make integration

Building

# Build binary
make build

# Build with version
make build VERSION=v1.0.0

# Clean build artifacts
make clean

Architecture

cyberpower-monitor/
โ”œโ”€โ”€ pkg/cyberpower/          # Public library API
โ”‚   โ”œโ”€โ”€ client.go           # Client factory
โ”‚   โ”œโ”€โ”€ types.go            # Public types
โ”‚   โ”œโ”€โ”€ options.go          # Configuration options
โ”‚   โ”œโ”€โ”€ snmp_client.go      # SNMP implementation
โ”‚   โ””โ”€โ”€ doc.go              # Package documentation
โ”œโ”€โ”€ cmd/cyberpower-monitor/ # CLI tool (demonstrates library)
โ”‚   โ””โ”€โ”€ commands/           # CLI commands
โ”œโ”€โ”€ examples/               # Library usage examples
โ”‚   โ”œโ”€โ”€ simple/            # Basic usage
โ”‚   โ””โ”€โ”€ prometheus/        # Advanced integration
โ””โ”€โ”€ internal/              # Internal utilities

Documentation

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/improvement)
  3. Run tests (make check)
  4. Commit changes (git commit -m 'feat: add improvement')
  5. Push branch (git push origin feat/improvement)
  6. Open a Pull Request

License

Apache 2.0 - See LICENSE file for details.

Acknowledgments


Questions? Open an issue or discussion on GitHub.