-
Notifications
You must be signed in to change notification settings - Fork 12
MQTT Inverter
The MQTT Inverter driver enables batcontrol to integrate with any battery/inverter system via MQTT topics. It acts as a generic bridge, allowing external systems to provide battery state information and receive control commands over MQTT.
The MQTT inverter driver uses batcontrol's shared MQTT connection (configured in the main batcontrol MQTT API section). It does NOT create a separate MQTT client. This design ensures:
- Single MQTT connection per batcontrol instance
- Consistent MQTT broker configuration
- Shared connection pool and resources
- Unified logging and error handling
All topics follow the pattern: <batcontrol_base_topic>/inverters/$num/<subtopic>
Where:
-
<batcontrol_base_topic>is the MQTT base topic from your main MQTT configuration -
$numis the inverter number (e.g., 0, 1, 2), not the literal string "$num" -
<subtopic>is the specific status or command topic
Example: If your base_topic is "batcontrol" and inverter number is 0, topics would be:
batcontrol/inverters/0/status/socbatcontrol/inverters/0/command/mode
These topics MUST be published as RETAINED by your external inverter/bridge system:
| Topic | Description | Type | Retention |
|---|---|---|---|
<base>/status/capacity |
Battery capacity in Wh | float | RETAINED (required) |
<base>/status/min_soc |
Minimum SoC limit in % (0-100) | float | RETAINED (optional) |
<base>/status/max_soc |
Maximum SoC limit in % (0-100) | float | RETAINED (optional) |
<base>/status/max_charge_rate |
Maximum charge rate in W | float | RETAINED (optional) |
These topics should be updated at least every 2 minutes to ensure fresh data:
| Topic | Description | Type | Retention |
|---|---|---|---|
<base>/status/soc |
Current State of Charge in % (0-100) | float | Non-retained (updated frequently) |
These topics are published by batcontrol and MUST NOT be retained:
| Topic | Description | Values |
|---|---|---|
<base>/command/mode |
Set operating mode |
force_charge, allow_discharge, avoid_discharge
|
<base>/command/charge_rate |
Set charge rate in W | float |
- Status topics MUST be RETAINED so batcontrol can read the current state immediately on startup
- Command topics MUST NOT be retained to avoid re-executing stale commands on reconnect
- If command topics are retained, the inverter may execute old commands after restart, causing unexpected behavior
Configure the MQTT connection in batcontrol's main MQTT API section (not in the inverter configuration):
mqtt:
broker: 192.168.1.100
port: 1883
user: batcontrol
password: secret
base_topic: batcontrol # Base topic for all MQTT messagesinverter:
type: mqtt
capacity: 10000 # Battery capacity in Wh (required)
min_soc: 5 # Minimum SoC % (default: 5)
max_soc: 100 # Maximum SoC % (default: 100)
max_grid_charge_rate: 5000 # Maximum charge rate in W (required)
cache_ttl: 120 # Cache TTL for SOC values in seconds (default: 120)
base_topic: batcontrol/inverter/0 # Optional: override default topic structure| Parameter | Required | Default | Description |
|---|---|---|---|
type |
Yes | - | Must be mqtt
|
capacity |
Yes | - | Battery capacity in Wh |
max_grid_charge_rate |
Yes | - | Maximum charge rate from grid in W |
min_soc |
No | 5 | Minimum State of Charge in % |
max_soc |
No | 100 | Maximum State of Charge in % |
cache_ttl |
No | 120 | Cache TTL for SOC values in seconds |
base_topic |
No | <mqtt.base_topic>/inverters/<num> |
Custom base topic for inverter MQTT messages |
Your external system (inverter bridge script, inverter firmware, etc.) must:
-
Publish battery status as RETAINED messages:
- Battery capacity in Wh (required)
- Optional: min_soc, max_soc, max_charge_rate
-
Publish current SOC regularly (at least every 2 minutes):
- Current State of Charge as a normal message (can be retained or non-retained)
-
Subscribe to command topics (non-retained):
- Mode changes (
force_charge,allow_discharge,avoid_discharge) - Charge rate adjustments
- Mode changes (
-
Handle reconnection gracefully:
- Re-publish all status topics as RETAINED on reconnect
- Don't retain command topics to avoid stale command execution
Here's a simple Python example using paho-mqtt to bridge your inverter to batcontrol:
import paho.mqtt.client as mqtt
import time
# Configuration
MQTT_BROKER = "192.168.1.100"
MQTT_PORT = 1883
MQTT_USER = "batcontrol"
MQTT_PASSWORD = "secret"
BASE_TOPIC = "batcontrol/inverters/0"
def on_connect(client, userdata, flags, rc):
"""Called when connected to MQTT broker"""
print(f"Connected with result code {rc}")
# Publish initial state (RETAINED)
client.publish(f"{BASE_TOPIC}/status/capacity", "10000", retain=True)
client.publish(f"{BASE_TOPIC}/status/min_soc", "5", retain=True)
client.publish(f"{BASE_TOPIC}/status/max_soc", "100", retain=True)
client.publish(f"{BASE_TOPIC}/status/max_charge_rate", "5000", retain=True)
# Subscribe to commands
client.subscribe(f"{BASE_TOPIC}/command/#")
print(f"Subscribed to {BASE_TOPIC}/command/#")
def on_message(client, userdata, message):
"""Handle incoming commands from batcontrol"""
topic = message.topic
value = message.payload.decode()
print(f"Received: {topic} = {value}")
if topic == f"{BASE_TOPIC}/command/mode":
print(f"Setting mode to: {value}")
# TODO: Implement your inverter control here
# Examples:
# - force_charge: Enable grid charging
# - allow_discharge: Normal operation
# - avoid_discharge: Prevent battery discharge
elif topic == f"{BASE_TOPIC}/command/charge_rate":
print(f"Setting charge rate to: {value}W")
# TODO: Implement your charge rate control here
def publish_soc(client, soc_value):
"""Publish current State of Charge"""
client.publish(f"{BASE_TOPIC}/status/soc", str(soc_value))
# Create MQTT client
client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
client.on_connect = on_connect
client.on_message = on_message
# Connect to broker
client.connect(MQTT_BROKER, MQTT_PORT, 60)
# Start network loop in background
client.loop_start()
# Main loop: Periodically publish SOC
try:
while True:
# TODO: Read actual SOC from your inverter
soc = 65.5 # Example value
publish_soc(client, soc)
time.sleep(60) # Update every 60 seconds
except KeyboardInterrupt:
print("Shutting down...")
client.loop_stop()
client.disconnect()The MQTT inverter supports three operating modes:
Forces the battery to charge from grid at the specified rate. Used during low-price periods.
Topic: <base>/command/mode
Payload: force_charge
Topic: <base>/command/charge_rate
Payload: 5000 # Charge at 5000W
Normal operation mode. Battery can charge from PV and discharge to supply loads.
Topic: <base>/command/mode
Payload: allow_discharge
Prevents battery discharge. Battery can still charge from PV but won't discharge to supply loads. Used to preserve battery for later use.
Topic: <base>/command/mode
Payload: avoid_discharge
The MQTT inverter automatically publishes Home Assistant MQTT Discovery messages for all status and command topics. This allows you to monitor your inverter's status and commands in Home Assistant without manual configuration.
Discovered entities include:
- MQTT Inverter Status SOC
- MQTT Inverter Status Capacity
- MQTT Inverter Status Min SOC
- MQTT Inverter Status Max SOC
- MQTT Inverter Status Max Charge Rate
- MQTT Inverter Command Mode
- MQTT Inverter Command Charge Rate
- No bidirectional acknowledgment: batcontrol assumes commands succeed immediately
- No auto-discovery: All topics must follow the documented structure exactly
- Network dependency: MQTT broker must be reliable and accessible
- Initial state required: Status topics must be available at batcontrol startup
- Clock synchronization: Ensure time is synchronized between batcontrol and your inverter system for accurate scheduling
- QoS 1 for commands: Guarantees delivery but not exactly-once semantics (commands may be delivered multiple times)
By default, the MQTT inverter uses the topic structure <mqtt.base_topic>/inverter/<inverter_num>. You can override this:
inverter:
type: mqtt
base_topic: custom/battery/system # Use custom topic structure
capacity: 10000
max_grid_charge_rate: 5000This would result in topics like:
custom/battery/system/status/soccustom/battery/system/command/mode
Each inverter will have its own set of MQTT topics.
- Inverter Configuration - General inverter configuration options
- MQTT API - Main MQTT API configuration and topics
- How batcontrol works - Understanding batcontrol's operation