This custom integration connects your Marstek battery system (via the Marstek cloud API) to Home Assistant, pulling live data and exposing it as sensor entities.
-
Automatic login & token refresh Logs in to the Marstek cloud API using your credentials, hashes your password (MD5) before sending, and automatically refreshes the token if it expires.
-
Re-authentication flow When credentials expire, Home Assistant automatically prompts you to re-enter them without needing to delete and re-add the integration.
-
Options flow with auto-reload Change scan interval and battery capacities through the Options menu. The integration automatically reloads when you save changes.
-
Robust error handling Gracefully handles API errors, network issues, and timeouts with intelligent retry logic and clear error messages.
-
Battery metrics exposed as sensors
soc– State of charge (%) with Battery device classcharge– Charge power (W) with Power device classdischarge– Discharge power (W) with Power device classload– Load power (W) with Power device classpv– Solar power (W) with Power device classgrid– Grid power (W) with Power device classprofit– Profit (€) with Monetary device classversion– Firmware versionsn– Serial numberreport_time– Timestamp of last report with Timestamp device classtotal_charge– Total stored energy per device (kWh) with Energy device class
-
Calculated power sensors
calculated_charge_power– Calculated charge power (pv - discharge) for accurate charge trackingcalculated_discharge_power– Calculated discharge power (discharge - pv) for accurate discharge tracking
-
Cross-device total sensors
total_charge_all_devices– Sum of total stored energy across all batteries (kWh)total_power_all_devices– Total power (charge - discharge) across all devices (W)
-
Diagnostic sensors
last_update– Time of last successful update with Timestamp device classapi_latency– API call duration with Duration device classconnection_status– Online/offline status
-
Device registry integration Each battery appears as a device in HA with model, serial number, firmware version, and manufacturer.
-
Smart device filtering Automatically filters out non-compatible or irrelevant device types (e.g., "HME-3") from the device list.
- Open HACS in Home Assistant
- Click the three dots menu → Custom repositories
- Add
https://github.com/thomasgriebner/marstek_cloudas an Integration - Click + Explore & Download Repositories and search for Marstek Cloud
- Download the integration
- Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration and search for Marstek Cloud Battery
- Copy the
marstek_cloudfolder into your Home Assistantcustom_componentsdirectory - Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration and search for Marstek Cloud Battery
- Go to Settings → Devices & Services → Add Integration and search for Marstek Cloud
- Enter your Marstek Cloud credentials (email and password)
- Configure scan interval (10-3600 seconds, default: 60 seconds)
- Set default battery capacity (default: 5.12 kWh)
- Click Submit - credentials are validated before saving
Access via Settings → Devices & Services → Marstek Cloud → Configure:
- Scan interval – Change how often data is fetched from the API
- Battery capacities – Adjust capacity for each discovered battery
- Changes take effect immediately with automatic integration reload
If your credentials expire or change:
- Home Assistant will display a notification
- Click Authenticate in the notification or go to the integration settings
- Enter your new credentials
- Integration continues working without losing entity IDs or automations
Here’s how the integration works internally:
config_flow.pycollects your email, password, scan interval, and default battery capacities.- These are stored securely in HA’s config entries.
__init__.pycreates:- An
aiohttpsession for async HTTP calls. - A
MarstekAPIinstance for talking to the cloud API. - A
MarstekCoordinator(subclass ofDataUpdateCoordinator) that schedules periodic updates.
- An
- On first run,
MarstekAPI._get_token():- MD5‑hashes your password.
- Sends a POST request to
https://eu.hamedata.com/app/Solar/v2_get_device.php. - Stores the returned
token.
- On each update,
MarstekAPI.get_devices():- Calls
https://eu.hamedata.com/ems/api/v1/getDeviceListwith the token. - If the API responds with an invalid/expired token, it refreshes and retries once.
- If the API responds with error code
8(no access permission), it clears the cached token and logs the error. A new token will be obtained automatically on the next update cycle.
- Calls
- The coordinator's
_async_update_data():- Records the start time.
- Calls
api.get_devices()to fetch the latest battery list. - Filters out ignored device types (e.g., "HME-3").
- Calculates API latency in milliseconds.
- Returns the filtered list of devices to all entities.
sensor.py:- For each device in the API response, creates:
- One
MarstekSensorper metric inSENSOR_TYPES. - One
MarstekDiagnosticSensorper metric inDIAGNOSTIC_SENSORS. - One
MarstekDeviceTotalChargeSensorfor the total charge per device.
- One
- Creates a
MarstekTotalChargeSensorfor the cross-device total charge. - Each entity has:
- A unique ID (
devid_fieldname). - Device info (name, model, serial, firmware, manufacturer).
- A unique ID (
- For each device in the API response, creates:
- HA calls
async_update()on entities when needed. - Entities pull their latest value from the coordinator’s cached data.
- The coordinator refreshes data on the configured interval or when manually triggered.
-
Login:
POST https://eu.hamedata.com/app/Solar/v2_get_device.php?pwd=<MD5_PASSWORD>&mailbox=<EMAIL> -
Get Devices:
GET https://eu.hamedata.com/ems/api/v1/getDeviceList?token=<TOKEN>
sequenceDiagram
participant HA as Home Assistant
participant CF as Config Flow
participant CO as Coordinator
participant API as Marstek API
participant ENT as Sensor Entities
HA->>CF: User enters email, password, scan interval, capacities
CF-->>HA: Store credentials, scan interval, capacities
HA->>CO: Create coordinator with API client
CO->>API: POST login (MD5 password)
API-->>CO: Return token
loop Every scan_interval seconds
CO->>API: GET device list (token)
alt Token expired
API-->>CO: Error (invalid token)
CO->>API: POST login (refresh token)
API-->>CO: Return new token
CO->>API: GET device list (retry)
end
API-->>CO: Return device data
CO-->>ENT: Update all sensor values
ENT-->>HA: Display updated metrics
end
- Cause: Incorrect email or password
- Solution: Double-check your Marstek Cloud credentials and try again
- Cause: Network issue or Marstek API temporarily unavailable
- Solution: Check your internet connection and try again in a few minutes
- Cause: API connection issues or integration not loaded properly
- Solution:
- Check Home Assistant logs: Settings → System → Logs
- Look for warnings or errors from
marstek_cloud - Try reloading the integration: Settings → Devices & Services → Marstek Cloud → ... → Reload
- Cause: Your Marstek Cloud account has no compatible devices registered
- Solution: Ensure at least one battery is registered in your Marstek Cloud account
- Cause: Invalid credentials or API token issues
- Solution:
- Click Authenticate in the notification
- Enter correct credentials
- If issue persists, remove and re-add the integration
To see detailed logs for troubleshooting:
- Add to
configuration.yaml:
logger:
default: info
logs:
custom_components.marstek_cloud: debug- Restart Home Assistant
- Check logs: Settings → System → Logs
- ✨ Added re-authentication flow for expired credentials
- ✨ Added options flow with auto-reload for scan interval and capacity changes
- ✨ Improved sensor device classes (TIMESTAMP, DURATION) for better Home Assistant integration
- ✨ Changed energy sensor state class from MEASUREMENT to TOTAL for proper statistics
- 🐛 Fixed error handling for API timeouts and network issues
- 🐛 Fixed entity creation logic (removed broken duplicate checking)
- 🐛 Improved logging with intelligent log levels (ERROR vs WARNING)
- 📚 Added German and English translations for all flows
- 🔧 Improved CI/CD with Python version matrix testing (3.11, 3.12)
- Initial HACS release
Contributions are welcome! Please feel free to submit issues or pull requests.
This project is provided as-is for personal use.