Skip to main content

uart-based ups power management for raspberry pi

Project description

UPS-Pi

UART-based UPS power management for Raspberry Pi4+ using UPSPack v3 devices.

Features

  • UART Communication: Direct serial via /dev/ttyAMA0 (GPIO 14/15)
  • Automated Shutdown: Configurable battery thresholds and delays
  • Real-time Monitoring: Continuous UPS status monitoring
  • Systemd Integration: Optional service installation for production
  • GPIO Support: Optional status LEDs and hardware signals
  • Comprehensive Logging: Event logging with rotation

Installation

Basic Installation

pip install ups-pi

With GPIO Support

pip install ups-pi[gpio]

Quick Start

Basic Usage

from ups_pi import UPSDevice, PowerManager, PowerManagerConfig

# Monitor UPS status
with UPSDevice() as ups:
    status = ups.read_status()
    print(f"Power: {status.power_status}")
    print(f"Battery: {status.battery_percentage}%")
    print(f"Voltage: {status.voltage_mv}mV")

# Full power management
config = PowerManagerConfig(
    shutdown_delay=60,
    critical_battery_threshold=10
)

with PowerManager(config) as pm:
    pm.start_monitoring()

Command Line

# Start monitoring (foreground)
ups-pi

# Test UPS communication
ups-pi --test-communication

# Verbose logging
ups-pi --verbose

# Custom config file
ups-pi --config /path/to/config.ini

Hardware Setup

Connections

Connect UPSPack v3 to Raspberry Pi:

  • UPS TXPi GPIO 15 (RX)
  • UPS RXPi GPIO 14 (TX)
  • UPS GNDPi GND
  • UPS SHUTDOWNPi GPIO 18 (optional, for GPIO support)

Enable UART

Add to /boot/firmware/config.txt:

enable_uart=1
dtoverlay=disable-bt

Shutdown Permissions (Important!)

For automatic shutdown to work, configure passwordless sudo:

# Add to /etc/sudoers.d/ups-pi (run: sudo visudo -f /etc/sudoers.d/ups-pi)
your-username ALL=(ALL) NOPASSWD: /sbin/shutdown, /sbin/halt, /bin/systemctl poweroff

# Or run as systemd service (recommended)
sudo ups-pi-service install

Reboot after changes.

Service Installation (Optional)

Install Service

# Install service files (requires root)
sudo ups-pi-service install

# Create config and log directories
sudo ups-pi-service setup-dirs

# Enable and start service
sudo ups-pi-service enable

Service Management

# Check status
sudo systemctl status ups-pi

# View logs
sudo journalctl -u ups-pi -f

# Stop service
sudo systemctl stop ups-pi

# Uninstall service
sudo ups-pi-service uninstall

Configuration

Default Locations

  • /etc/ups-pi/config.ini (system-wide)
  • ~/.config/ups-pi/config.ini (user-specific)
  • config.ini (current directory)

Example Configuration

[uart]
port = /dev/ttyAMA0
baudrate = 9600
timeout = 2.0

[monitoring]
interval = 5.0
retries = 3

[shutdown]
delay = 30
critical_threshold = 5
enable = true

[gpio]
enable = false
status_led_pin = 18

[logging]
level = INFO
file = /var/log/ups-pi/power_events.log

API Reference

UPSDevice

from ups_pi import UPSDevice

with UPSDevice(port="/dev/ttyAMA0") as ups:
    status = ups.read_status()
    # status.firmware_version
    # status.power_status ("External", "Battery", "Charging")
    # status.battery_percentage (0-100)
    # status.voltage_mv (millivolts)

PowerManager

from ups_pi import PowerManager, PowerManagerConfig

config = PowerManagerConfig(
    shutdown_delay=60,           # seconds before shutdown
    critical_battery_threshold=5, # immediate shutdown %
    enable_shutdown=True         # allow actual shutdown
)

with PowerManager(config) as pm:
    pm.start_monitoring()
    # Monitoring runs in background thread

Troubleshooting

UART Issues

# Check UART status
ls -la /dev/ttyAMA*

# Test UART loopback (connect GPIO 14 to 15)
ups-pi --test-communication

Permissions

# Add user to dialout group
sudo usermod -a -G dialout $USER

# Logout and login again

Service Issues

# Check service logs
sudo journalctl -u ups-pi --no-pager

# Test manual run
sudo ups-pi --verbose

Shutdown Issues

# Test shutdown permissions
sudo shutdown -c  # Cancel any pending shutdown
sudo systemctl poweroff --dry-run

# Configure passwordless shutdown
sudo visudo -f /etc/sudoers.d/ups-pi
# Add: your-username ALL=(ALL) NOPASSWD: /sbin/shutdown, /sbin/halt, /bin/systemctl

# Use systemd service (recommended)
sudo ups-pi-service install
sudo systemctl start ups-pi

License

MIT License - see LICENSE file for details.

Hardware Compatibility

  • Tested: UPSPack v3

  • Compatible: Any UART-based UPS with CSV output format

  • Requirements: Raspberry Pi with GPIO UART support sudo systemctl start ups-pi

    Check status

    sudo systemctl status ups-pi

    
    

Manual Installation

1. Enable UART

Add to /boot/firmware/config.txt:

enable_uart=1

2. Install Dependencies

sudo apt update
sudo apt install python3-pip python3-serial
pip3 install -r requirements.txt

3. Install UPS-Pi

# Copy files
sudo mkdir -p /usr/local/bin/ups-pi
sudo cp src/* /usr/local/bin/ups-pi/
sudo chmod +x /usr/local/bin/ups-pi/ups_manager.py

# Install configuration
sudo mkdir -p /etc/ups-pi
sudo cp config/config.ini /etc/ups-pi/

# Install service
sudo cp config/ups-pi.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable ups-pi

4. Create Log Directory

sudo mkdir -p /var/log/ups-pi
sudo chmod 755 /var/log/ups-pi

Configuration

Configuration File: /etc/ups-pi/config.ini

[uart]
port = /dev/ttyAMA0
baudrate = 9600
timeout = 2.0

[monitoring]
interval = 5.0          # seconds between status checks
retries = 3             # communication retry attempts
max_failures = 5        # max consecutive failures before stopping

[shutdown]
delay = 30              # seconds to wait on battery before shutdown
critical_threshold = 5  # battery % for immediate shutdown
low_threshold = 20      # battery % for low battery warnings
enable = true           # allow automatic shutdown
require_confirmation = false

[gpio]
enable = false          # enable GPIO features
shutdown_pin = 18       # GPIO pin for shutdown signal
status_led_pin =        # GPIO pin for status LED (empty = disabled)

[logging]
level = INFO                               # DEBUG, INFO, WARNING, ERROR, CRITICAL
file = /var/log/ups-pi/power_events.log    # log file path
max_size = 10485760                        # 10MB max log file size
backup_count = 5                           # number of backup log files

Environment Variables

Override configuration with environment variables:

export UPS_UART_PORT=/dev/ttyAMA0
export UPS_SHUTDOWN_DELAY=60
export UPS_CRITICAL_BATTERY=10
export UPS_ENABLE_GPIO=false
export UPS_LOG_LEVEL=DEBUG

Usage

Service Management

# Start/stop service
sudo systemctl start ups-pi
sudo systemctl stop ups-pi

# Enable/disable automatic startup
sudo systemctl enable ups-pi
sudo systemctl disable ups-pi

# Check status and logs
sudo systemctl status ups-pi
sudo journalctl -u ups-pi -f

Interactive Mode

# Test mode (no actual shutdown)
/usr/local/bin/ups-pi/ups_manager.py --test-mode

# Verbose logging
/usr/local/bin/ups-pi/ups_manager.py --verbose

# Custom configuration
/usr/local/bin/ups-pi/ups_manager.py --config /path/to/config.ini

Testing

# Test UPS communication
python3 tests/test_device.py

# Test with different device
python3 tests/test_device.py --port /dev/ttyS0

# Performance testing
python3 tests/test_device.py --performance 60

# Multiple test cycles
python3 tests/test_device.py --loop 10

Monitoring and Logs

Log Files

  • Service logs: sudo journalctl -u ups-pi
  • Application logs: /var/log/ups-pi/power_events.log
  • System logs: /var/log/syslog

Status Monitoring

# View real-time logs
sudo tail -f /var/log/ups-pi/power_events.log

# Check current UPS status
/usr/local/bin/ups-pi/ups_manager.py --test-communication

# Monitor systemd service
sudo systemctl status ups-pi

Troubleshooting

Common Issues

  1. UART device not found:

    # Check if UART is enabled
    grep uart /boot/firmware/config.txt
    
    # Check device exists
    ls -la /dev/ttyAMA*
    
    # May need reboot after enabling UART
    sudo reboot
    
  2. Permission errors:

    # Check user groups
    groups
    
    # Add user to dialout group
    sudo usermod -a -G dialout $USER
    
  3. Communication errors:

    # Test different baud rates
    python3 tests/test_device.py --baudrate 2400
    python3 tests/test_device.py --baudrate 4800
    
    # Check physical connections
    # Verify UPS is powered and operational
    
  4. Service won't start:

    # Check service status
    sudo systemctl status ups-pi
    
    # Check configuration
    /usr/local/bin/ups-pi/ups_manager.py --test-communication
    
    # Reload systemd
    sudo systemctl daemon-reload
    

Hardware Verification

# Check GPIO status
python3 -c "
import subprocess
result = subprocess.run(['gpio', 'readall'], capture_output=True, text=True)
print(result.stdout)
"

# Manual UART test
sudo minicom -D /dev/ttyAMA0 -b 9600

# Loopback test (connect GPIO 14 to GPIO 15)
echo "Testing UART loopback..."

Architecture

Components

  • ups_communication.py: UART communication and data parsing
  • power_manager.py: Main power management logic and monitoring
  • config.py: Configuration loading and validation
  • ups_manager.py: Main application entry point

Data Flow

  1. UART Communication: Read status from UPS device
  2. Data Parsing: Parse and validate UPS data
  3. State Management: Track power state changes
  4. Action Execution: Execute shutdown procedures when needed
  5. Logging: Record all events and status changes

Power States

  • EXTERNAL_POWER: Normal operation on external power
  • BATTERY_POWER: Running on battery (power outage)
  • CRITICAL_BATTERY: Critical battery level (immediate shutdown)
  • UNKNOWN: Initial state or communication error

Development

Project Structure

ups-pi-clean/
├── src/                    # Source code
│   ├── ups_manager.py      # Main application
│   ├── power_manager.py    # Power management logic
│   ├── ups_communication.py # UART communication
│   ├── config.py           # Configuration management
│   └── __init__.py         # Package initialization
├── config/                 # Configuration files
│   ├── config.ini          # Default configuration
│   └── ups-pi.service      # Systemd service file
├── scripts/                # Installation and utility scripts
│   └── install.py          # Automated installer
├── tests/                  # Test scripts
│   └── test_device.py      # Device communication tests
├── docs/                   # Documentation
├── requirements.txt        # Python dependencies
└── README.md              # This file

Testing

# Install development dependencies
pip3 install -r requirements.txt

# Run device tests
python3 tests/test_device.py --verbose

# Test installation (dry run)
python3 scripts/install.py --help

License

MIT License - see LICENSE file for details.

Support

For support and bug reports, please open an issue on GitHub.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make changes with tests
  4. Submit a pull request

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ups_pi-1.0.9.tar.gz (32.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ups_pi-1.0.9-py3-none-any.whl (23.7 kB view details)

Uploaded Python 3

File details

Details for the file ups_pi-1.0.9.tar.gz.

File metadata

  • Download URL: ups_pi-1.0.9.tar.gz
  • Upload date:
  • Size: 32.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ups_pi-1.0.9.tar.gz
Algorithm Hash digest
SHA256 872861f527fa0da32453526a75d10c3812f81cf61b5041e0c9b0d6494eda5f94
MD5 6ad2daf7fce3ca92b2474ecddb994976
BLAKE2b-256 89cd9645f494ce623ab557c103b6fb67e9050a4f1920f1a141ead607d34c9828

See more details on using hashes here.

File details

Details for the file ups_pi-1.0.9-py3-none-any.whl.

File metadata

  • Download URL: ups_pi-1.0.9-py3-none-any.whl
  • Upload date:
  • Size: 23.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ups_pi-1.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 317956a1d68498507ef9f27689cf5b6e7191c4c7e77cbeeb3839f09013c2baf1
MD5 d0a7439b260905e2f56f783b0cdaf49d
BLAKE2b-256 477d90bb27af1ba0f69c15609a851608fb1fdfd3e8fbfe14e6fe8f6e288b659f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page