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. -
Configurable scan interval
Set how often the integration polls the API (10–3600 seconds) during initial setup or later via the Options menu. -
Battery metrics exposed as sensors
soc– State of charge (%)charge– Charge power (W)discharge– Discharge power (W)load– Load power (W)profit– Profit (€)version– Firmware versionsn– Serial numberreport_time– Timestamp of last reporttotal_charge– Total charge per device (kWh).
-
Cross-device total charge sensor
total_charge_all_devices– Sum of total charges across all batteries (kWh).
-
Diagnostic sensors
last_update– Time of last successful updateapi_latency– API call duration in millisecondsconnection_status– Online/offline status
-
Device registry integration
Each battery appears as a device in HA with model, serial number, firmware version, and manufacturer. -
Editable battery capacity
Configure the default capacity (in kWh) for each battery during setup or later via the Options menu. -
Smart device filtering
Automatically filters out non-compatible or irrelevant device types (e.g., "HME-3") from the device list.
- 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.
- Enter your Marstek cloud email, password, and desired scan interval.
- Scan interval can be set during initial setup and changed later via the integration’s Configure option.
- Default battery capacity (in kWh) can be set for each battery during setup or via the Options menu.
- Default capacity is 5.12 kWh.
- Minimum scan interval is 10 seconds, maximum is 3600 seconds.
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