Project-specific patterns for the Marstek integration (config flow, coordinator, scanner, entities, translations)
This skill helps you make correct, repo-consistent changes to this Home Assistant custom integration.
| Task | File(s) |
|---|---|
| Setup / teardown / coordinator wiring | __init__.py |
| Config flow (user, dhcp, integration discovery) | config_flow.py |
| Central polling (tiered intervals) | coordinator.py |
| IP-change scanner | scanner.py |
| Sensors | sensor.py (EntityDescription pattern) |
| Binary sensors | binary_sensor.py (EntityDescription pattern) |
| Select entities | select.py |
| Services | services.py (idempotent registration) |
| Device automation actions | device_action.py |
| Device info helper | device_info.py |
| Mode configuration | mode_config.py |
| Diagnostics | diagnostics.py |
| Text / translations | strings.json, translations/en.json |
| Icons | icons.json |
| Local API reference | docs/marstek_device_openapi.MD |
| UDP client library | pymarstek/ |
Coordinator-only I/O
MarstekDataUpdateCoordinator.data._async_setup() for one-time initialization during first refresh.always_update=False if data supports __eq__ comparison.Async-only
async def _async_update_data(self):
try:
return await self.api.fetch_data()
except AuthError as err:
# Triggers reauth flow automatically
raise ConfigEntryAuthFailed from err
except RateLimitError:
# Backoff with retry_after
raise UpdateFailed(retry_after=60)
except ConnectionError as err:
raise UpdateFailed(f"Connection failed: {err}")
Avoid unavailable clutter
Use translation-aware config-flow errors
custom_components/marstek/strings.json.Stable identifiers
_attr_has_entity_name = True and set device_info for grouping.Steps:
coordinator.data (a plain dict[str, Any] coming from pymarstek).MarstekSensorEntityDescription to the SENSORS tuple in sensor.py.exists_fn to conditionally create entities (avoids permanent unavailable state).unique_id stable (BLE-MAC + sensor key).translations/en.json (and keep strings.json in sync).suggested_display_precision for numeric sensors.unavailable noise.class MarstekSensor(CoordinatorEntity, SensorEntity):
_attr_has_entity_name = True # MANDATORY
def __init__(self, coordinator, description):
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.ble_mac}_{description.key}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, coordinator.ble_mac)},
name=coordinator.device_name,
manufacturer="Marstek",
)
@dataclass(kw_only=True)
class MarstekSensorEntityDescription(SensorEntityDescription):
value_fn: Callable[[dict], StateType]
exists_fn: Callable[[dict], bool] = lambda _: True
SENSORS: tuple[MarstekSensorEntityDescription, ...] = (
MarstekSensorEntityDescription(
key="battery_soc",
translation_key="battery_soc",
device_class=SensorDeviceClass.BATTERY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda data: data.get("soc"),
),
MarstekSensorEntityDescription(
key="power",
device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.WATT,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda data: data.get("power"),
),
)
icon property)Create icons.json:
{
"entity": {
"sensor": {
"battery_soc": {
"default": "mdi:battery",
"state": {
"100": "mdi:battery",
"50": "mdi:battery-50"
}
}
}
}
}
EntityCategory.DIAGNOSTIC - RSSI, firmware version, temperatureEntityCategory.CONFIG - Settings the user can changeentity_registry_enabled_default = False for rarely-used sensorsSensorStateClass.MEASUREMENT - Instantaneous values (power, temperature)SensorStateClass.TOTAL - Values that can increase/decrease (net energy)SensorStateClass.TOTAL_INCREASING - Only increases, resets to 0 (lifetime energy)SensorDeviceClass.ENERGY_STORAGE for battery capacity (stored Wh)config_flow.py.When detecting connectivity issues or IP changes:
Example: The coordinator triggers MarstekScanner.async_request_scan() when it hits the failure threshold, enabling fast IP change detection without aggressive periodic scanning.
npx skills add taurgis/homeassistant-integration-patterns下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer