Skip to content

jtbnz/fronius-modbus-controller

Repository files navigation

Fronius Gen24 Modbus Controller

Python 3.7+ License: MIT Code style: black

A Python library and command-line tool for controlling Fronius Gen24 inverters via Modbus TCP. This project enables programmatic control of battery charging without relying on the web interface, perfect for home automation, energy optimization, and dynamic tariff management.

🌟 Key Features

  • Direct Battery Control: Toggle charging on/off programmatically
  • Flexible Charge Rates: Set custom charge rates from 0-100%
  • Real-time Monitoring: Read battery SOC, power, voltage, and current
  • Schedule Support: Define time-based charging windows
  • Easy Integration: Simple Python API for home automation systems
  • CLI Tools: Command-line interface for quick control and scripting
  • Configuration Files: YAML-based configuration for easy deployment

📋 Table of Contents

🏗 Architecture

System Overview

graph TB
    subgraph "Home Network"
        A[Python Application<br/>Fronius Controller] -->|Modbus TCP<br/>Port 502| B[Fronius Gen24<br/>Inverter]
        B -->|Power Flow| C[Battery System]
        B -->|Solar Input| D[PV Arrays]
        B -->|AC Output| E[Home Grid]
    end
    
    F[User/Automation] -->|CLI/API| A
    G[Config File<br/>YAML] --> A
    
    style A fill:#2196F3,color:#fff
    style B fill:#4CAF50,color:#fff
    style C fill:#FF9800,color:#fff
Loading

Component Architecture

graph LR
    subgraph "Fronius Modbus Controller"
        A[CLI Interface] --> B[Controller Core]
        C[Config Loader] --> B
        B --> D[Modbus Client]
        D --> E[pymodbus]
        B --> F[Battery Manager]
        B --> G[Status Monitor]
    end
    
    E -->|TCP/IP| H[Fronius Inverter]
    
    style B fill:#2196F3,color:#fff
    style D fill:#4CAF50,color:#fff
Loading

Data Flow

sequenceDiagram
    participant User
    participant CLI
    participant Controller
    participant Modbus
    participant Inverter
    
    User->>CLI: Enable charging
    CLI->>Controller: enable_battery_charging(rate=80)
    Controller->>Modbus: Write Register 40359 (rate)
    Modbus->>Inverter: Set charge rate
    Inverter-->>Modbus: ACK
    Controller->>Modbus: Write Register 40358 (mode)
    Modbus->>Inverter: Set FORCED_CHARGE
    Inverter-->>Modbus: ACK
    Modbus-->>Controller: Success
    Controller-->>CLI: Operation complete
    CLI-->>User: Charging enabled at 80%
Loading

📋 Prerequisites

Hardware Requirements

  • Fronius Gen24 inverter (Plus or Primo series)
  • Network connection to inverter (Ethernet or WiFi)
  • Compatible battery system (BYD, LG Chem, etc.)

Software Requirements

  • Python 3.7 or higher
  • pip package manager
  • Network access to inverter on port 502

Inverter Configuration

  1. Access your Fronius Gen24 web interface
  2. Navigate to: Settings → Communication → Modbus
  3. Enable Modbus TCP
  4. Note the Unit ID (default: 1)
  5. Ensure port 502 is accessible

🚀 Installation

From Source

# Clone the repository
git clone https://github.com/jtbnz/fronius-modbus-controller.git
cd fronius-modbus-controller

# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Install package
pip install -e .

Using pip (when published)

pip install fronius-modbus-controller

🎯 Quick Start

1. Basic Usage

Toggle battery charging with one command:

python fronius_controller.py 192.168.1.100

2. Check Status

python fronius_controller.py 192.168.1.100 --action status

Output:

Battery Status:
  State of Charge: 85.3%
  Power: 2500W
  Mode: FORCED_CHARGE

3. Enable Charging

python fronius_controller.py 192.168.1.100 --action enable --charge-rate 50

📖 Usage

Command Line Interface

Basic Commands

# Toggle charging on/off
python fronius_controller.py <INVERTER_IP>

# Enable charging at 100% rate
python fronius_controller.py <INVERTER_IP> --action enable

# Enable charging at 50% rate
python fronius_controller.py <INVERTER_IP> --action enable --charge-rate 50

# Disable charging
python fronius_controller.py <INVERTER_IP> --action disable

# Check battery status
python fronius_controller.py <INVERTER_IP> --action status

# Verbose output for debugging
python fronius_controller.py <INVERTER_IP> --action status --verbose

Configuration-Based Usage

# Using default config.yaml
python fronius_config.py status

# Using custom config file
python fronius_config.py --config my_config.yaml toggle

# Run scheduled charging
python fronius_config.py schedule

Python API

from fronius_controller import FroniusModbusController, BatteryMode

# Initialize controller
controller = FroniusModbusController("192.168.1.100")

# Connect to inverter
if controller.connect():
    try:
        # Enable charging at 80% rate
        controller.enable_battery_charging(charge_rate=80)
        
        # Read battery status
        soc = controller.get_battery_soc()
        power = controller.get_battery_power()
        
        print(f"Battery SOC: {soc:.1f}%")
        print(f"Battery Power: {power}W")
        
        # Toggle charging
        controller.toggle_battery_charging()
        
        # Check current mode
        mode = controller.read_register(FroniusRegisters.BATTERY_CONTROL_MODE)
        print(f"Current Mode: {BatteryMode(mode).name}")
        
    finally:
        controller.disconnect()

Home Assistant Integration

# configuration.yaml
shell_command:
  fronius_charge_on:
    command: "python /path/to/fronius_controller.py 192.168.1.100 --action enable"
  fronius_charge_off:
    command: "python /path/to/fronius_controller.py 192.168.1.100 --action disable"

sensor:
  - platform: command_line
    name: Fronius Battery SOC
    command: "python /path/to/fronius_controller.py 192.168.1.100 --action status | grep 'State of Charge' | awk '{print $4}'"
    unit_of_measurement: "%"
    scan_interval: 300

⚙️ Configuration

Basic Configuration

Create a config.yaml file:

inverter:
  host: 192.168.1.100
  port: 502
  unit_id: 1

charging:
  default_rate: 100

logging:
  level: INFO

Advanced Configuration with Scheduling

inverter:
  host: 192.168.1.100
  port: 502
  unit_id: 1
  timeout: 10
  retries: 3

charging:
  default_rate: 100
  
  # Charge during off-peak hours
  schedule:
    - start: "23:00"
      end: "07:00"
      rate: 100
      days: ["mon", "tue", "wed", "thu", "fri"]
    
    # Weekend solar charging window
    - start: "10:00"
      end: "14:00"
      rate: 50
      days: ["sat", "sun"]

monitoring:
  poll_interval: 60
  metrics_file: /var/log/fronius_metrics.json

logging:
  level: INFO
  file: /var/log/fronius_controller.log
  max_size: 10485760  # 10MB
  backup_count: 5

Environment Variables

You can override configuration with environment variables:

export FRONIUS_HOST=192.168.1.100
export FRONIUS_PORT=502
export FRONIUS_UNIT_ID=1

📚 API Reference

FroniusModbusController

Constructor

FroniusModbusController(host: str, port: int = 502, unit_id: int = 1)

Methods

Method Description Returns
connect() Connect to the inverter bool
disconnect() Disconnect from the inverter None
enable_battery_charging(charge_rate: int) Enable charging at specified rate bool
disable_battery_charging() Disable charging (normal mode) bool
toggle_battery_charging() Toggle charging on/off bool
get_battery_soc() Get battery state of charge Optional[float]
get_battery_power() Get battery power (W) Optional[int]
read_register(address: int) Read a Modbus register Optional[int]
write_register(address: int, value: int) Write to a Modbus register bool

Modbus Registers

Register Name Description Access
40358 WChaCtl_Mod Battery control mode R/W
40359 WChaGra Charge rate (% × 100) R/W
40360 WDisChaGra Discharge rate (% × 100) R/W
30845 Battery SOC State of charge (% × 100) R
30775 Battery Power Power in watts R
30851 Battery Voltage Voltage in volts R
30843 Battery Current Current in amps R

Battery Modes

class BatteryMode(Enum):
    DISABLED = 0          # Battery disabled
    NORMAL = 1           # Normal operation
    FORCED_CHARGE = 2    # Force charging
    FORCED_DISCHARGE = 3 # Force discharging

💡 Examples

See the examples directory for more detailed examples:

🔧 Troubleshooting

Common Issues

Connection Refused

Error: Connection refused to 192.168.1.100:502

Solution: Enable Modbus TCP in inverter settings

Invalid Response

Error: Modbus Error: [Invalid Message] No response received

Solution: Check Unit ID matches inverter configuration

Permission Denied

Error: Modbus Error: [Illegal Function] 

Solution: Some registers may be read-only or require specific inverter states

Debug Mode

Enable verbose logging for troubleshooting:

python fronius_controller.py 192.168.1.100 --verbose --action status

Network Testing

Test connectivity:

# Ping test
ping 192.168.1.100

# Port test
nc -zv 192.168.1.100 502

# Modbus test
python -c "from pymodbus.client import ModbusTcpClient; c=ModbusTcpClient('192.168.1.100'); print(c.connect())"

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone and install in development mode
git clone https://github.com/jtbnz/fronius-modbus-controller.git
cd fronius-modbus-controller
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black .

# Lint
flake8

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

⚠️ Disclaimer

This is an unofficial tool and is not affiliated with Fronius International GmbH. Use at your own risk. Always ensure proper safety measures when controlling battery systems.

🙏 Acknowledgments

  • Fronius for their excellent inverter technology
  • The pymodbus community for the robust Modbus implementation
  • Contributors and testers from the home automation community

📞 Support

About

Control Fronius Gen24 inverters via Modbus TCP for battery management and home automation

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages