Developer Guide
Architecture, contributing guidelines, and development setup
Architecture Overview
System Components
eos_connect.py
Main application entry point and orchestration
config.py
Configuration loading and validation
interfaces/
Data source and control interfaces
web/
Web dashboard (HTML/CSS/JS)
Core Interfaces
| Interface | Purpose | File |
|---|---|---|
| Base Control | Core control state management | base_control.py |
| Battery Interface | Battery data retrieval and management | battery_interface.py |
| PV Interface | Solar forecast retrieval | pv_interface.py |
| Price Interface | Electricity price forecasts | price_interface.py |
| Load Interface | Household load data | load_interface.py |
| Inverter (Fronius) | Inverter control and monitoring | inverter_fronius_v2.py |
| EVCC Interface | EV charging control | evcc_interface.py |
| MQTT Interface | MQTT publishing and subscription | mqtt_interface.py |
| Optimization Interface | EOS/EVopt communication | optimization_interface.py |
Data Flow
1. Main Loop (every refresh_time minutes)
├─ Fetch battery SOC (battery_interface)
├─ Fetch PV forecast (pv_interface)
├─ Fetch price forecast (price_interface)
├─ Fetch load data (load_interface)
├─ Build optimization request
├─ Send to EOS/EVopt (optimization_interface)
├─ Process optimization response
├─ Update controls (base_control)
├─ Execute inverter commands (inverter_interface)
├─ Update EVCC (evcc_interface)
├─ Publish to MQTT (mqtt_interface)
└─ Serve via web API
Contributing
Branch Strategy
| Branch Type | Purpose | Naming |
|---|---|---|
| main | Stable, tagged releases only | - |
| develop | Integration branch (PR target) | - |
| feature | New functionality | feature/<desc> or feature/<issue>-<desc> |
| bugfix | Fix for develop | bugfix/<issue>-<desc> |
| hotfix | Urgent production fix | hotfix/<issue>-<desc> |
| issue | GitHub auto-created | issue-<number>-<desc> |
Contribution Workflow
# 1. Update local
git fetch origin
git switch develop
git pull --ff-only
# 2. Create feature branch
git switch -c feature/better-forecast
# 3. Code + test + document
# - Write code
# - Add/update tests
# - Update docs (README / CONFIG_README / MQTT if behavior changes)
# 4. Format and lint
black .
pylint src/
# 5. Run tests
pytest tests/
# 6. Rebase before PR
git fetch origin
git rebase origin/develop
# 7. Push
git push -u origin feature/better-forecast
# 8. Create PR targeting develop
# - Link relevant issues (Closes #123)
# - Provide clear description
Code Quality Requirements
- Formatting: Use Black for all Python files
- Linting: Pylint score ≥9.0
- Testing: Add/update tests for logic changes
- Documentation: Update relevant docs
Commit Message Format (Conventional Commits)
feat: add battery forecast smoothing
fix: correct negative PV handling
docs: update MQTT topic table
test: add tests for price calculation
refactor: simplify config loading
chore: update dependencies
VS Code Tip: Install the Black Formatter extension for automatic formatting on save.
Testing
Test Structure
Tests are organized to mirror the source structure:
tests/
├── test_control_states.py
└── interfaces/
├── test_base_control.py
├── test_battery_interface.py
├── test_inverter_fronius_v2.py
├── test_load_interface.py
├── test_optimization_interface.py
├── test_price_interface.py
├── test_pv_interface.py
└── optimization_backends/
└── test_optimization_backend_eos.py
Running Tests
# Run all tests
pytest tests/
# Run specific test file
pytest tests/interfaces/test_battery_interface.py
# Run with coverage
pytest --cov=src tests/
# Run with verbose output
pytest -v tests/
Writing Tests
Test File Naming
- Place in
tests/directory - Mirror source structure
- Name as
test_<module>.py
Example Test
import pytest
from src.interfaces.battery_interface import BatteryInterface
def test_battery_soc_calculation():
"""Test SOC calculation with known values"""
battery = BatteryInterface(capacity_wh=10000)
battery.set_soc(0.75)
assert battery.get_remaining_wh() == 7500
assert battery.get_soc() == 0.75
def test_battery_temperature_protection():
"""Test temperature-based power reduction"""
battery = BatteryInterface(
capacity_wh=10000,
max_charge_power_w=5000,
temperature_sensor="sensor.temp"
)
# Cold temperature should reduce power
power = battery.calculate_max_charge_power(
soc=0.50,
temperature=-5
)
assert power < 500 # Should be ~5-7.5% of max
Test Configuration
Configure pytest in pytest.ini:
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
Development Setup
Prerequisites
- Python 3.11 or higher
- Git
- pip
- (Optional) VS Code with Python extension
Setup Steps
# 1. Clone repository
git clone https://github.com/ohAnd/EOS_connect.git
cd EOS_connect
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Install development dependencies
pip install black pylint pytest pytest-cov
# 5. Copy and edit config
cp src/config.yaml.example src/config.yaml
# Edit src/config.yaml with your settings
# 6. Run EOS Connect
python src/eos_connect.py
VS Code Configuration
Recommended .vscode/settings.json:
{
"python.defaultInterpreterPath": "./venv/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.linting.pylintArgs": ["--rcfile=.pylintrc"],
"python.formatting.provider": "black",
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": ["tests"]
}
Environment Variables
For development, you can override config with environment variables:
# Linux/Mac
export EOS_CONNECT_LOG_LEVEL=debug
export EOS_CONNECT_PORT=8081
# Windows
set EOS_CONNECT_LOG_LEVEL=debug
set EOS_CONNECT_PORT=8081
Project Structure
EOS_connect/
├── src/
│ ├── eos_connect.py # Main application
│ ├── config.py # Configuration management
│ ├── config.yaml # User configuration
│ ├── constants.py # Constants and enums
│ ├── log_handler.py # Logging setup
│ ├── version.py # Version information
│ ├── interfaces/ # Data interfaces
│ │ ├── base_control.py
│ │ ├── battery_interface.py
│ │ ├── evcc_interface.py
│ │ ├── inverter_fronius_v2.py
│ │ ├── load_interface.py
│ │ ├── mqtt_interface.py
│ │ ├── optimization_interface.py
│ │ ├── price_interface.py
│ │ └── pv_interface.py
│ ├── web/ # Web dashboard
│ │ ├── index.html
│ │ ├── css/
│ │ └── js/
│ └── json/ # JSON schemas and examples
├── tests/ # Test suite
├── docs/ # Documentation (GitHub Pages)
├── docker-compose.yml # Docker deployment
├── Dockerfile # Docker image
├── requirements.txt # Python dependencies
├── pytest.ini # Pytest configuration
├── README.md # Project overview
├── CONTRIBUTING.md # Contribution guidelines
└── LICENSE # MIT License
Resources
Documentation
Related Projects
- Akkudoktor EOS - Main optimization backend
- EVCC - EV charging controller
- Home Assistant - Smart home platform
Tools
Get Involved!
We welcome contributions of all kinds:
Report Bugs
Open an issue with detailed reproduction steps
Suggest Features
Share your ideas in GitHub Discussions
Improve Docs
Documentation PRs are always welcome!
Submit PRs
Follow the contribution workflow and submit your changes