Skip to content

lopf/smartfox_exporter

Repository files navigation

SMARTFOX Prometheus Exporter

A Prometheus exporter for SMARTFOX solar power management systems that converts XML data from SMARTFOX devices into Prometheus metrics format.

Features

  • Comprehensive Metrics: Exports ~120 time series covering all aspects of your solar power system
  • Proper Units: All metrics use Prometheus base units (watts, watt-hours, celsius, seconds)
  • Flexible Source: Can read from HTTP URL (production) or local file (testing)
  • Health Monitoring: Includes up metric and scrape duration for monitoring exporter health
  • Docker Support: Ready-to-run Docker container
  • Best Practices: Follows Prometheus exporter guidelines

Supported Metrics

Power Measurements

  • Grid power (production/consumption)
  • Total system power
  • Power per electrical phase (L1, L2, L3)
  • Inverter power output
  • Car charger power consumption
  • Heat pump power

Energy Measurements

  • Total energy produced/consumed
  • Daily energy values
  • Energy fed to grid
  • Inverter energy production
  • Car charger energy consumption

Electrical Data

  • Voltage per phase
  • Current per phase
  • Apparent energy

System Status

  • Inverter status and production
  • Relay states and timers
  • Battery status (if available)
  • Temperature readings
  • SD card status
  • Connection timeouts

Quick Start

Using Docker Compose (Recommended)

  1. Clone or download this project
  2. Start with sample data:
    docker-compose up -d
  3. View metrics: http://localhost:9090/metrics
  4. View landing page: http://localhost:9090/

Production Configuration

Edit docker-compose.yml and set your SmartFox URL:

environment:
  SMARTFOX_URL: "http://192.168.1.61/values.xml"  # Your SmartFox IP
  # SMARTFOX_FILE: "sample/values.xml"  # Comment out for production

Manual Installation

  1. Install dependencies:

    pip3 install -r requirements.txt
  2. Run with sample data:

    python3 smartfox_exporter.py
  3. Run with your SMARTFOX system:

    export SMARTFOX_URL="http://192.168.1.61/values.xml"
    python3 smartfox_exporter.py

Configuration

Configure the exporter using environment variables:

Variable Description Default
SMARTFOX_URL URL to SmartFox values.xml None
SMARTFOX_FILE Local XML file path for testing sample/values.xml
SMARTFOX_EXPORTER_PORT HTTP server port 9090

Note: If both SMARTFOX_URL and SMARTFOX_FILE are set, URL takes precedence.

Prometheus Configuration

Add this job to your prometheus.yml:

scrape_configs:
  - job_name: 'smartfox'
    static_configs:
      - targets: ['localhost:9090']  # Adjust hostname/port as needed
    scrape_interval: 30s
    scrape_timeout: 10s

For Docker deployments:

scrape_configs:
  - job_name: 'smartfox'
    static_configs:
      - targets: ['smartfox-exporter:9090']

Sample Metrics Output

# HELP smartfox_up Indicates if the SmartFox system is reachable
# TYPE smartfox_up gauge
smartfox_up 1

# HELP smartfox_power_to_grid_watts Power being fed to the grid
# TYPE smartfox_power_to_grid_watts gauge
smartfox_power_to_grid_watts -6150

# HELP smartfox_energy_total_watt_hours Total energy produced
# TYPE smartfox_energy_total_watt_hours counter
smartfox_energy_total_watt_hours 6108340

# HELP smartfox_voltage_volts Voltage per phase
# TYPE smartfox_voltage_volts gauge
smartfox_voltage_volts{phase="L1"} 243
smartfox_voltage_volts{phase="L2"} 242
smartfox_voltage_volts{phase="L3"} 242

# HELP smartfox_inverter_power_watts Power output per inverter
# TYPE smartfox_inverter_power_watts gauge
smartfox_inverter_power_watts{inverter="1",name="WR"} 6580

Metric Categories

Core Power & Energy

  • smartfox_power_*_watts - Current power measurements
  • smartfox_energy_*_watt_hours - Energy counters and daily values

Electrical System

  • smartfox_voltage_volts{phase} - Voltage per phase
  • smartfox_current_amperes{phase} - Current per phase

Equipment Status

  • smartfox_inverter_*{inverter,name} - Solar inverter metrics
  • smartfox_car_charger_*{charger,name} - EV charger metrics
  • smartfox_relay_*{relay,name} - Relay control status
  • smartfox_battery_*{battery} - Battery system metrics

Environmental

  • smartfox_temperature_celsius{location} - Temperature sensors
  • smartfox_heat_pump_* - Heat pump metrics

System Health

  • smartfox_up - System reachability (1=up, 0=down)
  • smartfox_scrape_duration_seconds - Metric collection time

Grafana Dashboard

Key queries for dashboards:

Power Flow:

smartfox_power_to_grid_watts  # Grid power (negative = consuming)
smartfox_power_production_watts  # Solar production

Daily Energy:

smartfox_energy_day_watt_hours / 1000  # Daily production in kWh
smartfox_energy_to_grid_day_watt_hours / 1000  # Daily grid feed-in

System Health:

smartfox_up  # System availability
rate(smartfox_energy_total_watt_hours[1h]) * 3600 / 1000  # Hourly production rate

Troubleshooting

Connection Issues

  1. Check SmartFox accessibility:

    curl http://192.168.1.61/values.xml
  2. Verify exporter logs:

    docker-compose logs smartfox-exporter
  3. Check metrics endpoint:

    curl http://localhost:9090/metrics

Common Problems

  • smartfox_up 0: SmartFox system unreachable or returning invalid XML
  • Missing metrics: Check XML structure matches expected format
  • Connection timeout: Increase network timeout or check firewall rules

Debug Mode

For detailed logging, modify the logging level in smartfox_exporter.py:

logging.basicConfig(level=logging.DEBUG)

Development

Testing with Sample Data

The included sample/values.xml contains real SmartFox data for testing:

# Run with sample data
SMARTFOX_FILE=sample/values.xml python smartfox_exporter.py

# Or use Docker
docker-compose up

Adding New Metrics

  1. Add metric definition in __init__ method
  2. Add parsing logic in update_metrics method
  3. Test with sample data
  4. Update documentation

Code Structure

  • SmartFoxExporter: Main exporter class
  • fetch_xml_data(): Handles data source (URL/file)
  • parse_xml_to_dict(): Converts XML to Python dict
  • update_metrics(): Maps XML values to Prometheus metrics
  • clean_value(): Handles HTML entities and units

Dependency Management

The SMARTFOX exporter follows a minimal dependency approach:

  • Uses Python's built-in xml.etree.ElementTree instead of external XML libraries like lxml
  • Only includes dependencies that are actively used in the codebase
  • Regular dependency audits to remove unused imports and packages

Dependencies

The SMARTFOX exporter has minimal dependencies for optimal performance:

  • prometheus_client (0.21.0): Core Prometheus metrics functionality
  • requests (2.32.3): HTTP client for fetching XML data from SMARTFOX systems

Recent Optimization: Removed unnecessary dependencies (lxml) that were not being used, reducing installation size and potential security surface area.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test with both sample and real data
  5. Submit a pull request

License

This project is open source. See the LICENSE file for details.

Support

For issues and questions:

  1. Check the troubleshooting section
  2. Review the logs for error messages
  3. Verify your SmartFox XML format matches the expected structure
  4. Open an issue with detailed information about your setup

Testing

The SMARTFOX exporter includes a comprehensive pytest test suite covering:

  • Unit Tests: Core functionality like XML parsing, value conversion, and metric registration
  • Integration Tests: Complete workflow testing with sample data
  • Error Handling: Network failures, malformed XML, and edge cases
  • Prometheus Metrics: Metric output format, labels, and types

Running Tests

  1. Install test dependencies:

    pip3 install pytest pytest-mock
  2. Run all tests:

    python3 -m pytest tests/
    # or use Makefile
    make test-pytest
  3. Run with verbose output:

    python3 -m pytest tests/ -v
    # or use Makefile
    make test-verbose
  4. Run specific test files:

    python3 -m pytest tests/test_smartfox_exporter.py -v
    python3 -m pytest tests/test_prometheus_metrics.py -v
    # or use Makefile
    make test-unit
    make test-integration
  5. Run tests with coverage (optional):

    pip3 install pytest-cov
    python3 -m pytest tests/ --cov=smartfox_exporter --cov-report=html
    # or use Makefile
    make test-coverage

Test Structure

  • tests/test_smartfox_exporter.py - Core exporter functionality tests
  • tests/test_prometheus_metrics.py - Prometheus integration tests
  • tests/conftest.py - Test fixtures and sample data
  • pytest.ini - Test configuration

All tests use realistic XML data structures that match the actual SMARTFOX system output.

CI/CD and Releases

Automated Release Process

The SMARTFOX exporter uses a simplified automated CI/CD pipeline with semantic versioning based on branch naming conventions:

  • πŸ”„ Continuous Integration: Every PR runs tests, code quality checks, and security scans
  • πŸš€ Branch-Based Auto Releases: PRs merged to main automatically trigger releases based on branch naming
  • πŸ“¦ Docker Images: Multi-architecture images automatically built and published to Docker Hub during releases
  • 🏷️ Semantic Versioning: Following MAJOR.MINOR.PATCH (SemVer) standards

Release Types

Feature Releases (x.MINOR.x) - Automatic:

  • Branch naming: feature/* (e.g., feature/new-metrics, feature/add-ssl-support)
  • Trigger: PR merge to main from feature branch
  • Version bump: Minor version increment (resets patch to 0)
  • Process: Automated testing, tagging, Docker image build/push, and GitHub release creation

Bug Fix Releases (x.x.PATCH) - Automatic:

  • Branch naming: bugfix/* or fix/* (e.g., bugfix/metric-parsing, fix/connection-timeout)
  • Trigger: PR merge to main from bugfix/fix branch
  • Version bump: Patch version increment
  • Process: Automated testing, tagging, Docker image build/push, and GitHub release creation

Security Updates (x.x.PATCH) - Automatic:

  • Branch naming: dependabot/* (created automatically by Dependabot)
  • Trigger: PR merge to main from dependabot security update
  • Version bump: Patch version increment
  • Process: Automated testing, tagging, Docker image build/push, and GitHub release creation

Manual Releases (any version):

  • Available via GitHub Actions for edge cases or major releases
  • Manually triggered with custom version number

Branch Naming Convention

To trigger automated releases, use these branch prefixes:

# For new features (minor version bump)
git checkout -b feature/add-new-metrics
git checkout -b feature/improve-performance

# For bug fixes (patch version bump)  
git checkout -b bugfix/fix-parsing-error
git checkout -b fix/memory-leak

πŸ“‹ Detailed Documentation: For comprehensive information about the release process, see RELEASE_WORKFLOW.md

Docker Images

After each release, multi-architecture Docker images are available on Docker Hub supporting:

  • linux/amd64 - Intel/AMD 64-bit systems
  • linux/arm64 - ARM 64-bit systems (Raspberry Pi 4+, Apple Silicon)
  • linux/arm/v7 - ARM 32-bit systems (Raspberry Pi 2/3, Pi Zero 2 W)
# Latest stable release
docker pull lopf/smartfox_exporter:latest

# Specific version
docker pull lopf/smartfox_exporter:v0.1.0

# Major version tracking
docker pull lopf/smartfox_exporter:0

Raspberry Pi Usage:

# Works on all Raspberry Pi models (2, 3, 4, Zero 2 W)
docker run -d --name smartfox-exporter \
  -p 9090:9090 \
  -e SMARTFOX_URL="http://192.168.1.61/values.xml" \
  lopf/smartfox_exporter:latest

Development Workflow

  1. Fork & Branch: Create feature branches from main
  2. Quality Gates: All PRs require passing tests and code quality checks
  3. Auto-merge: Security-only Dependabot PRs auto-merge after successful CI
  4. Protected Main: Main branch is protected and requires PR approval

For detailed setup instructions, see CI/CD Setup Guide.


Note: This exporter is designed for SmartFox solar power management systems. The XML format and available metrics may vary between different SmartFox models and firmware versions.

About

SMARTFOX Solar Energy Management Prometheus Exporter

Resources

License

Stars

Watchers

Forks

Packages

No packages published