A custom Home Assistant integration for monitoring and controlling Marstek energy storage devices (Venus A/D/E 3.0, etc.) using local UDP communication via the Marstek Open API.
Note: This is an independent community project and is not affiliated with or endorsed by Marstek. This integration was originally inspired by Marstek's reference implementation but has been completely rewritten with a custom architecture, UDP client, and feature set.
- Battery State of Charge (SoC) - Current battery level percentage
- Battery Power - Real-time charge/discharge power (W)
- Battery Temperature - Battery pack temperature
- Battery Status - Current operational status
- Operating Mode - Current device mode (Auto, AI, Manual, Passive)
- PV Metrics - Solar panel power, voltage, current, and state (up to 4 channels; Venus A/D)
- On-grid Power - Total grid power from energy meter (3-phase support)
- WiFi Signal Strength - RSSI for connectivity diagnostics
- CT Connection Status - Current transformer connection state
- Device Information - IP address, firmware version, MAC addresses
- Operating Mode Selection - Switch between Auto, AI, Manual, and Passive modes
- Passive Mode Control - Set charge/discharge power with duration (service)
- Manual Scheduling - Configure up to 10 time-based charge/discharge schedules
- Bulk Schedule Management - Set multiple schedules via YAML or clear all schedules
- Data Sync - Trigger immediate device refresh on demand
- Local UDP Communication - No cloud dependency, fast and reliable
- Automatic IP Discovery - Finds devices via UDP broadcast
- Dynamic IP Handling - Background scanner detects and updates IP changes
- Centralized Polling - Single coordinator per device to avoid request bursts
- Stable Entity IDs - BLE-MAC-based identifiers survive IP changes
| Integration | Repository | Summary | Strengths | Tradeoffs |
|---|---|---|---|---|
| This integration | https://github.com/taurgis/has-marstek-local-api | Local UDP with centralized polling, scanner-based IP updates, strong HA patterns. | Shared UDP client, tiered polling, robust config flow/options/services, strict validation & typing. | Focused on per-device setup (no multi-device aggregation). |
| Marstek Local API | https://github.com/jaapp/ha-marstek-local-api | Feature-rich local API integration with multi-device aggregation. | Multi-device support, aggregate sensors, extensive diagnostics. | Heavier complexity; discovery may pause active clients. |
| MarstekEnergy reference | https://github.com/marstekEnergy/ha_marstek | Vendor reference implementation. | Simple setup, uses upstream py-marstek. | Less robust networking (per-entry sockets), fewer HA best-practice patterns. |
| Requirement | Version/Details |
|---|---|
| Home Assistant | Core 2025.10.0+ |
| Network | Same LAN segment as Marstek devices |
| Device Config | OPEN API must be enabled in the Marstek app |
| UDP Port | 30000 (default, must be reachable) |
Warning: This integration is currently not compatible with Venus E2.0 devices. Using this integration with Venus E2.0 may cause disconnection between the device and CT003.
- Open HACS in Home Assistant
- Click the three dots menu and select Custom repositories
- Add repository URL and select Integration as category
- Search for "Marstek" and install
- Restart Home Assistant
- Download or clone this repository
- Copy the
custom_components/marstekfolder to your Home Assistantconfig/custom_components/directory - Restart Home Assistant
# Example for Home Assistant OS/Supervised
cd /config
mkdir -p custom_components
cp -r /path/to/ha_marstek/custom_components/marstek custom_components/- Go to Settings then Devices and Services
- Click Add Integration
- Search for Marstek
- The integration will automatically discover devices on your network
- Select your device and complete the setup
After setup, you can adjust polling and request behavior in Device → Configure:
- Fast polling interval (default: 30s): ES.GetMode, ES.GetStatus, EM.GetStatus (real-time power)
- Medium polling interval (default: 60s): PV.GetStatus (solar data, Venus A/D only)
- Slow polling interval (default: 300s): Wifi.GetStatus, Bat.GetStatus (diagnostics)
- Parallel API requests (default: off): Send enabled status APIs concurrently with no inter-request delay (advanced; can be less stable on Wi-Fi)
- Request delay (default: 5s): Delay between consecutive UDP requests in sequential mode (ignored when parallel API requests is enabled)
- Request timeout (default: 10s): Per-request timeout before retry/fail
- Failures before unavailable (default: 3): Consecutive failures before entities become unavailable
These values can be tuned to reduce network traffic or improve responsiveness.
The integration uses a single DataUpdateCoordinator per device with tiered polling to avoid request bursts. Entities never perform their own I/O and always read from coordinator data.
Extended documentation (with screenshots) lives in docs/:
- Documentation index
- Installation
- Configuration
- Options
- Entities
- Energy Dashboard
- Services
- Repairs
- Troubleshooting
| Device | Status |
|---|---|
| Venus A 3.0 | Supported (PV supported) |
| Venus D 3.0 | Supported (PV supported) |
| Venus E 3.0 | Supported |
| Venus E 2.0 | Not compatible |
| Other OPEN API devices | May work (untested) |
The integration provides several services for advanced control:
Set the device to passive mode with specified power and duration.
- power: Target power in watts (-5000 to 5000). Negative charges, positive discharges.
- duration: Duration in seconds (default: 3600)
Configure a single manual schedule slot.
- schedule_slot: Slot number (0-9)
- start_time: Schedule start time
- end_time: Schedule end time
- power: Target power in watts
- days: Days of the week (mon, tue, wed, thu, fri, sat, sun)
- enable: Enable/disable the schedule
Configure multiple schedules via YAML:
service: marstek.set_manual_schedules
data:
device_id: YOUR_DEVICE_ID
schedules:
- schedule_slot: 0
start_time: "08:00"
end_time: "16:00"
days: ["mon", "tue", "wed", "thu", "fri"]
power: -2000
enable: true
- schedule_slot: 1
start_time: "18:00"
end_time: "22:00"
power: 800Clear all manual schedule slots on the device.
Trigger an immediate data refresh from the device.
ha_marstek/
├── custom_components/marstek/
│ ├── __init__.py # Integration setup and teardown
│ ├── config_flow.py # Config flow, discovery, reauth
│ ├── const.py # Constants and configuration
│ ├── coordinator.py # Data update coordinator
│ ├── device_action.py # Device automation actions
│ ├── discovery.py # UDP discovery helpers
│ ├── scanner.py # Background IP change detection
│ ├── select.py # Operating mode select entity
│ ├── sensor.py # All sensor entities
│ ├── services.py # Service implementations
│ ├── services.yaml # Service definitions
│ ├── strings.json # UI strings
│ ├── translations/ # Localization files
│ └── pymarstek/ # UDP client library
│ ├── udp.py # UDP client implementation
│ ├── command_builder.py# Protocol command builder
│ ├── data_parser.py # Response parser
│ └── const.py # Protocol constants
├── tests/ # Test suite
├── tools/ # Development utilities
│ ├── mock_device/ # Mock device for testing
│ ├── capture_device.py # Traffic capture tool
│ └── query_device.py # Device query tool
└── docs/ # Documentation
└── marstek_device_openapi.MD # Protocol reference
# Clone the repository
git clone https://github.com/your-username/ha_marstek.git
cd ha_marstek
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements_test.txt# Linting
python3 -m ruff check custom_components/marstek/
# Type checking
python3 -m mypy --strict custom_components/marstek/
# Tests with coverage
pytest tests/ -q --cov=custom_components/marstek --cov-fail-under=95
# Run specific test file
pytest tests/test_config_flow.py -vThis repository uses Changesets for release preparation.
# Install the release tooling once
npm install
# Add a release note for a change
npm run changesetMerge changesets into main and the Changesets GitHub Action will open or update a Release pull request that:
- bumps
package.json - updates
CHANGELOG.md - syncs
custom_components/marstek/manifest.json - syncs
pyproject.toml
When that PR is merged, the workflow creates and pushes the matching v* tag, and the existing release workflow publishes the GitHub release from CHANGELOG.md.
If you need to continue the current release-candidate flow, enter prerelease mode before merging the next release batch:
# Start generating RC versions
npm run changeset:pre:enter
# Leave prerelease mode before the final stable release
npm run changeset:pre:exitChangesets prerelease mode uses SemVer prerelease identifiers such as -rc.0.
A mock device is available for testing without physical hardware:
cd tools/mock_device
python mock_marstek.py- Ensure OPEN API is enabled in the Marstek app on your device
- Verify Home Assistant and device are on the same network segment
- Check that UDP port 30000 is not blocked by firewall
- Try restarting the device
- The integration uses UDP which may be affected by network instability
- Check WiFi signal strength (RSSI sensor) for connectivity quality
- Ensure only one client is communicating with the device at a time
- Check device connectivity and OPEN API status
- Review Home Assistant logs for error messages
- Expected behavior: brief UDP/API failures keep last known values until the "Failures before unavailable" threshold is reached (to avoid flapping on an unstable device API)
- Try the request_data_sync service
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing code style and patterns
- Add tests for new functionality
- Update documentation as needed
- Keep commits focused and well-described
This project is licensed under the MIT License - see the LICENSE file for details.
- Thanks to the Home Assistant community for their excellent documentation and patterns
- Protocol documentation: Marstek Open API Specification
This integration is provided "as is" without warranty of any kind. Use at your own risk. The authors are not responsible for any damage to your devices or data loss. This project is not affiliated with, endorsed by, or connected to Marstek in any way.