Version: 0.0.2-alpha - Alpha release with VRM identification paths for Venus OS GUI visibility.
This service implements a complete Venus OS D-Bus integration for MPP Solar inverters (PI30 series) using the mpp-solar Python package. It features a proper Multi/Solar Charger service architecture that correctly represents hybrid inverter/charger functionality and provides comprehensive data mapping for all MPP Solar values.
- Multi/Solar Charger Architecture: Implements proper Victron D-Bus service types for hybrid inverters
- Device Capability Detection: Automatically assesses device capabilities and creates appropriate services
- Comprehensive Data Mapping: Maps all MPP Solar PI30 protocol values to appropriate D-Bus paths
- Conditional Path Publishing: Only publishes paths that are supported by the connected device
- Enhanced Logging: Extensive debug logging with configurable log levels and file rotation
- Venus OS Integration: Full compatibility with GX devices and Venus OS ecosystem
- Private Bus Connections: Uses private D-Bus connections to avoid conflicts with core services
The service creates two D-Bus services based on device capabilities:
- Multi Service (
com.victronenergy.multi.mppsolar): Handles inverter/charger functionality - Solar Charger Service (
com.victronenergy.solarcharger.mppsolar): Handles PV input data
This architecture correctly represents MPP Solar hybrid inverters that combine AC charging, DC solar input, and battery management in a single device.
This service integrates the following repositories:
- dbus-serialbattery - D-Bus patterns and Venus OS integration
- mpp-solar - MPP Solar protocol implementation
AI-generated code with human validation and testing by: Grok XAI and HHaufe (spacecabbie)
- D-Bus integration with Venus OS
- Support for PI30 protocol inverters via USB/HIDRAW connections
- Comprehensive logging and error handling
Run standalone tests with the new architecture:
cd /data/apps/dbus-mppsolarv2
python3 standalone_mppsolar_test.pyExpected output includes capability assessment and comprehensive data mapping:
Starting MPP Solar standalone test with Multi/Solar Charger architecture...
Testing MPP Solar inverter connection...
Using port: /dev/hidraw0, baud: 2400
β Connection successful
Testing device capability assessment...
β Capability assessment completed
Device Capabilities:
has_ac_output: True
has_ac_input: True
has_battery_data: True
has_pv_data: True
has_temperature: True
minimum_requirements_met: True
Testing data refresh and D-Bus mapping...
β Data refresh completed
MPP Solar Data Values:
ac_voltage: 230.1
ac_current: 2.3
...
D-Bus Path Mapping:
/Ac/Out/L1/V: 230.1
/Ac/In/L1/V: 240.5
...
β All tests passed!
For direct communication with your MPP Solar inverter (useful for testing and debugging), use the provided wrapper script:
# Get device protocol info
./run-mpp-solar.sh -p /dev/hidraw0 -c QPI
# Get full inverter status
./run-mpp-solar.sh -p /dev/hidraw0 -c QPIGS
# Get device mode
./run-mpp-solar.sh -p /dev/hidraw0 -c QMOD
# With debug output
./run-mpp-solar.sh -p /dev/hidraw0 -c QPIGS -D
# List available commands for PI30 protocol
./run-mpp-solar.sh -P PI30 -cNote: The run-mpp-solar.sh script is specifically designed for Venus OS to avoid Python package installation conflicts. It provides direct access to all mpp-solar functionality without requiring package installation.
The service creates two D-Bus services based on device capabilities:
Handles inverter/charger functionality with the following paths:
/Ac/In/L1/V- AC input voltage (V)/Ac/In/L1/I- AC input current (A)/Ac/In/L1/F- AC input frequency (Hz)/Ac/Out/L1/V- AC output voltage (V)/Ac/Out/L1/I- AC output current (A)/Ac/Out/L1/P- AC output active power (W)/Ac/Out/L1/S- AC output apparent power (VA)/Ac/Out/L1/F- AC output frequency (Hz)
/Dc/Battery/Voltage- Battery voltage (V)/Dc/Battery/Current- Battery current (A, negative for discharge)/Dc/Battery/Power- Battery power (W)/Dc/Battery/Soc- Battery state of charge (%)/Dc/Battery/Temperature- Battery temperature (Β°C)
/Mode- Operating mode (1=Charger, 2=Inverter, 3=Off, 4=System fault)/State- System state (0=Off, 1=Low Power, 2=Fault, 9=Inverting)/ErrorCode- Error code (0=None, 1=Device fault, 2=AC input fault, etc.)/Relay/0/State- Relay state (0=Open, 1=Closed)
/DeviceInstance- Device instance ID/ProductId- Product ID (0xB004)/ProductName- Product name ("MPP Solar Multi")/FirmwareVersion- Firmware version/Serial- Device serial number
/Mgmt/ProcessName- Process name ("dbus-mppsolar")/Mgmt/ProcessVersion- Process version ("1.0.0")/Mgmt/Connection- Connection type ("USB HID", "Serial USB", etc.)/Connected- Connection status (0/1)
Handles PV input data with the following paths:
/Dc/0/Voltage- PV input voltage (V)/Dc/0/Current- PV input current (A)/Dc/0/Power- PV input power (W)
/Dc/0/Temperature- PV controller temperature (Β°C)/Load/State- Load state (0=Off, 1=On)/Yield/Power- Daily yield power (W)/Yield/User- Total user yield (kWh)/Yield/System- Total system yield (kWh)
/State- Charger state (0=Off, 1=Low Power, 2=Fault, 3=Bulk, 4=Absorption, 5=Float, 6=Storage, 7=Equalize, 8=Passthru, 9=Inverting, 11=Power supply, 252=External control)/ErrorCode- Error code (0=None, 1=Battery voltage too high, 2=Battery voltage too low, etc.)/OffReason- Off reason bitmask
/ProductId- Product ID (0xA06C)/ProductName- Product name ("MPP Solar Solar Charger")/FirmwareVersion- Firmware version/Serial- Device serial number
/Mgmt/ProcessName- Process name ("dbus-mppsolar")/Mgmt/ProcessVersion- Process version ("1.0.0")/Mgmt/Connection- Connection type/Connected- Connection status (0/1)
Additional device-specific data is published under custom paths:
/Custom/MppSolar/AcLoadPercentage- AC load percentage (%)/Custom/MppSolar/BusVoltage- Bus voltage (V)/Custom/MppSolar/HeatSinkTemp- Heat sink temperature (Β°C)/Custom/MppSolar/IsChargingOn- Charging enabled status/Custom/MppSolar/IsSccChargingOn- SCC charging enabled status/Custom/MppSolar/IsChargingToFloat- Float charging status
/Custom/MppSolar/PvInputCurrentBattery- PV input current for battery (A)/Custom/MppSolar/PvInputPower- PV input power (W)
Paths are only published if the device supports the corresponding functionality:
- AC input paths only if AC input voltage > 1.0V is detected
- Battery paths only if battery voltage is available
- PV paths only if PV voltage or power is available
- Temperature paths only if temperature data is valid (0-100Β°C)
This ensures clean D-Bus interfaces without placeholder values.
1. Device Not Found
# Check available serial devices
ls /dev/ttyUSB* /dev/ttyACM* /dev/ttyS* /dev/hidraw*
# Check device permissions
ls -la /dev/hidraw0
# Check recent device connections
dmesg | grep -E "(tty|hidraw|usb)" | tail -10
# Fix permissions if needed
sudo chmod 666 /dev/hidraw02. Connection Timeout
- Verify correct port in
config.ini - Check baud rate (typically 2400 for MPP Solar)
- Ensure device is powered on and connected
- Try different USB port or cable
3. D-Bus Service Conflicts
- Service uses private bus connections to avoid conflicts
- Check for existing MPP Solar services:
systemctl list-units | grep mppsolar - Stop conflicting services before starting this one
4. No Data in Venus OS GUI
- Verify D-Bus paths are published:
dbus -y com.victronenergy.multi.mppsolar /Connected GetValue - Check service logs for data publishing errors
- Ensure device capabilities match expected data
Enable detailed logging for troubleshooting:
# In config.ini
[DBUS]
DEBUG_ENABLED = True
[LOGGING]
LOG_LEVEL = DEBUG# View recent logs
journalctl -u com.victronenergy.mppsolar.service -n 50
# Follow logs in real-time
journalctl -u com.victronenergy.mppsolar.service -f
# View logs with timestamps
journalctl -u com.victronenergy.mppsolar.service --since "1 hour ago"# Test device connection only
python3 standalone_mppsolar_test.py
# Run service in foreground for debugging
python3 dbus-mppsolar.py
# Test direct MPP Solar communication
./run-mpp-solar.sh -p /dev/hidraw0 -c QPIGS- High CPU usage: Increase poll interval in config (default 1000ms)
- Serial communication errors: Check USB cable quality and power supply
- Log file growing too large: Adjust log rotation settings in config
- Stop the service:
systemctl stop com.victronenergy.mppsolar.service - Check device connection:
ls -la /dev/hidraw* - Test standalone:
python3 standalone_mppsolar_test.py - Check configuration: Verify
config.inisettings - Restart service:
systemctl restart com.victronenergy.mppsolar.service - Monitor logs:
journalctl -u com.victronenergy.mppsolar.service -f
dbus-mppsolarv2/
βββ README.md # π Project documentation and installation guide
βββ pyproject.toml # βοΈ Python project configuration with dependencies
βββ dbus-mppsolar.py # π Main D-Bus service entry point and main loop
βββ standalone_mppsolar_test.py # π§ͺ Standalone testing script for device connection
βββ mpp-solar/ # π¦ MPP Solar communication library (git submodule)
βββ dbus_mppsolar/ # π Core service modules directory
β βββ __init__.py # π Python package initialization
β βββ inverter.py # οΏ½ MPP Solar inverter device implementation
β βββ dbushelper.py # π D-Bus communication helper for Venus OS
β βββ utils.py # π οΈ Configuration management and utility functions
β βββ config.default.ini # βοΈ Default configuration template
β βββ config.ini # βοΈ User configuration file (created from default)
β βββ dbus-mppsolar.py # π Alternative service entry point
βββ service/ # π§ Systemd service configuration
β βββ com.victronenergy.mppsolar.service # π Systemd service definition file
βββ test/ # π§ͺ Testing directory
β βββ README.md # π Test documentation and usage instructions
βββ .github/ # π§ GitHub repository configuration
β βββ copilot-instructions.md # π€ AI assistant instructions for development
βββ *.sh # π Shell scripts for service management
β βββ install.sh # π¦ Automated installation script
β βββ uninstall.sh # ποΈ Service removal script
β βββ enable.sh # β
Enable systemd service
β βββ disable.sh # β Disable systemd service
β βββ restart.sh # π Restart service script
β βββ start-mppsolar.sh # βΆοΈ Manual service start script
β βββ run-mpp-solar.sh # π§ Direct MPP Solar communication wrapper
βββ bms/ # π Empty directory (reserved for future BMS drivers)
βββ ext/ # π¦ Empty directory (reserved for external dependencies)
βββ qml/ # π¨ Empty directory (reserved for QML UI components)
βββ rc/ # π§ Empty directory (reserved for runtime configuration)
README.md- Comprehensive project documentation including installation, configuration, usage, and troubleshootingpyproject.toml- Python project configuration defining dependencies (mpp-solar, pyserial, dbus-python, gobject)dbus-mppsolar.py- Main service entry point that initializes D-Bus, sets up the MPPService, and runs the main event loopstandalone_mppsolar_test.py- Independent testing script to verify MPP Solar device connection and data retrieval
mpp-solar/- Git submodule containing the MPP Solar communication library for inverter protocol handling
__init__.py- Python package initialization fileinverter.py- Implements the Inverter class that handles MPP Solar inverter communication using the mpp-solar packagedbushelper.py- D-Bus helper class that publishes inverter data to Venus OS D-Bus paths for system integrationutils.py- Utility functions for configuration loading, logging setup, and Venus OS constantsconfig.default.ini- Template configuration file with default settings for port, baud rate, protocol, and timeoutsconfig.ini- User configuration file (created from config.default.ini during installation)dbus-mppsolar.py- Alternative service entry point (may be redundant with root level file)
com.victronenergy.mppsolar.service- Systemd service definition for automatic startup and management
README.md- Documentation for testing procedures and expected results
copilot-instructions.md- Instructions for AI assistants on project development guidelines and workflow
install.sh- Automated installation script that sets up dependencies, copies files, and configures systemduninstall.sh- Removes the service, cleans up files, and disables systemd serviceenable.sh- Enables the systemd service for automatic startupdisable.sh- Disables the systemd servicerestart.sh- Restarts the running servicestart-mppsolar.sh- Manual service startup scriptrun-mpp-solar.sh- Direct MPP Solar communication wrapper (Venus OS compatible)
bms/- Empty directory reserved for future BMS (Battery Management System) driver implementationsext/- Empty directory for external dependencies and librariesqml/- Empty directory for QML user interface components (if GUI development is added)rc/- Empty directory for runtime configuration scripts and hooks## License
MIT License - see LICENSE file for details
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
classDiagram
class MPPService {
+inverter: Inverter
+dbus_helper: DbusHelper
+mainloop: MainLoop
+running: bool
+__init__()
+setup() bool
+run() void
-_update_data() bool
-_signal_handler(signum, frame) void
}
class Inverter {
+port: str
+baud_rate: int
+protocol: str
+mpp_device: MPP
+online: bool
+voltage: float
+current: float
+power: float
+ac_voltage: float
+ac_current: float
+frequency: float
+__init__(port, baud, address)
+test_connection() bool
+refresh_data() bool
-_init_device() void
-_parse_status_data(data) void
+get_settings() bool
+unique_identifier() str
+connection_name() str
+custom_name() str
+product_name() str
+use_callback(callback) bool
+get_allow_to_charge() bool
+get_allow_to_discharge() bool
+validate_data() bool
}
class DbusHelper {
+inverter: Inverter
+dbus_service: VeDbusService
+_paths: Dict
+_dbus_paths: Dict
+__init__(inverter)
+setup_vedbus() bool
+publish_inverter() bool
+publish_dbus() bool
+update_process_name(name) bool
+update_process_version(version) bool
+update_connection_type(connection) bool
}
class Utils {
+logger: Logger
+config: ConfigParser
+get_config_value(key, section, default) Any
+get_bool_from_config(key, section, default) bool
+safe_number_format(value, format) str
}
MPPService --> Inverter : creates
MPPService --> DbusHelper : creates
Inverter --> Utils : uses
DbusHelper --> Utils : uses
DbusHelper --> Inverter : monitors
note for MPPService "Main service orchestrator\nManages service lifecycle"
note for Inverter "MPP Solar device handler\nCommunicates with inverter hardware"
note for DbusHelper "D-Bus interface manager\nPublishes data to Venus OS"
note for Utils "Configuration & utilities\nLogging, config loading"
flowchart TD
A["dbus-mppsolar.py"] --> B["main()"]
B --> C["DBusGMainLoop set_as_default=True"]
C --> D["Create MPPService instance"]
D --> E["service.setup()"]
E --> F{"Setup successful?"}
F -->|"No"| G["Log error & exit"]
F -->|"Yes"| H["service.run()"]
H --> I["Setup signal handlers"]
I --> J["Publish initial data"]
J --> K["Create GLib MainLoop"]
K --> L["Add periodic timer every 1000ms"]
L --> M["Start main loop blocking call"]
M --> N["_update_data timer fires"]
N --> O["inverter.refresh_data()"]
O --> P{"Data refresh successful?"}
P -->|"Yes"| Q["dbus_helper.publish_inverter()"]
P -->|"No"| R["Log error"]
Q --> S["Return True continue timer"]
R --> S
M --> T["Signal received SIGTERM/SIGINT"]
T --> U["_signal_handler called"]
U --> V["mainloop.quit()"]
V --> W["Set running = False"]
W --> X["Exit main loop"]
X --> Y["Service shutdown complete"]
classDef entry fill:#e1f5fe
classDef setup fill:#f3e5f5
classDef runtime fill:#e8f5e8
classDef update fill:#fff3e0
classDef shutdown fill:#ffebee
class A entry
class B,C,D,E setup
class H,I,J,K,L,M runtime
class N,O,P,Q,R,S update
class T,U,V,W,X,Y shutdown
sequenceDiagram
participant M as main()
participant S as MPPService
participant I as Inverter
participant D as DbusHelper
participant DB as D-Bus
M->>S: MPPService()
S->>I: Inverter()
I->>I: _init_device()
I->>I: test_connection()
S->>D: DbusHelper(inverter)
D->>D: setup_vedbus()
D->>DB: Create VeDbusService
D->>DB: Add D-Bus paths
M->>S: setup()
S->>I: test_connection()
I-->>S: connection result
S->>D: setup_vedbus()
D-->>S: setup result
S-->>M: setup result
M->>S: run()
S->>D: publish_inverter()
D->>DB: Publish initial data
S->>S: Setup signal handlers
S->>S: Create MainLoop
S->>S: Add timer 1000ms
loop Periodic updates
S->>S: _update_data()
S->>I: refresh_data()
I->>I: get_general_status()
I->>I: _parse_status_data()
I-->>S: data
S->>D: publish_inverter()
D->>DB: Update D-Bus paths
end
Note over M,DB: Service runs until signal received
M->>S: Signal handler
S->>S: mainloop.quit()
graph LR
subgraph "Configuration Layer"
CFG["config.default.ini"] --> U["utils.py"]
CFG --> I["inverter.py"]
end
subgraph "Communication Layer"
MPP["mpp-solar/ (submodule)"] --> I
SERIAL["Serial Port /dev/ttyUSB0"] --> I
end
subgraph "Service Layer"
I --> S["dbus-mppsolar.py MPPService"]
U --> S
D["dbushelper.py DbusHelper"] --> S
end
subgraph "Integration Layer"
S --> DBUS["D-Bus System Bus"]
D --> DBUS
DBUS --> VRM["Venus OS VRM Portal"]
DBUS --> GUI["Venus OS GUI Apps"]
end
subgraph "Management Layer"
INST["install.sh"] --> SYS["systemd service"]
EN["enable.sh"] --> SYS
START["start-mppsolar.sh"] --> S
TEST["standalone_mppsolar_test.py"] --> I
end
classDef config fill:#e3f2fd
classDef comm fill:#f3e5f5
classDef service fill:#e8f5e8
classDef integration fill:#fff3e0
classDef management fill:#fce4ec
class CFG config
class MPP,SERIAL comm
class I,U,S,D service
class DBUS,VRM,GUI integration
class INST,EN,START,TEST,SYS management
- MPPService β Inverter: Creates and manages the inverter instance
- MPPService β DbusHelper: Creates and manages the D-Bus interface
- Inverter β Utils: Uses logging and configuration utilities
- DbusHelper β Utils: Uses logging and D-Bus constants
- DbusHelper β Inverter: Monitors inverter data for publishing
- Entry Point:
dbus-mppsolar.py:main()initializes D-Bus and creates service - Setup Phase: Service initializes inverter connection and D-Bus interface
- Runtime Phase: Main loop runs with periodic data updates every 1 second
- Data Flow: Inverter β MPPService β DbusHelper β D-Bus β Venus OS
- Shutdown: Signal handlers gracefully stop the service
- AC Data:
ac_voltage,ac_current,ac_power,frequency - DC Data: Not published (to avoid double-counting with AC power in Venus OS)
- Battery Service: Separate
com.victronenergy.battery.mppsolar_{instance}service with voltage, current, power, SOC - Status:
online,connection_info - D-Bus Paths:
/Ac/Out/L1/*,/Dc/0/*,/Connected,/Status,/State
This architecture provides a clean separation between device communication, data processing, and system integration, making it maintainable and extensible for Venus OS compatibility.