home / skills / openclaw / skills / ha-integration-patterns

ha-integration-patterns skill

/skills/usimic/ha-integration-patterns

This skill helps you implement Home Assistant integration patterns, enabling robust HTTP views, service responses, and storage using best practices for

npx playbooks add skill openclaw/skills --skill ha-integration-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
4.7 KB
---
name: ha-integration-patterns
description: Home Assistant custom integration patterns and architectural decisions. Use when building HACS integrations, custom components, or API bridges for Home Assistant. Covers service response data, HTTP views, storage APIs, and integration architecture.
---

# Home Assistant Integration Patterns

## Service Response Data Pattern

### The Problem
By default, HA services are "fire-and-forget" and return empty arrays `[]`.

### The Solution (HA 2023.7+)
Register service with `supports_response`:

```python
from homeassistant.helpers.service import SupportsResponse

hass.services.async_register(
    domain, 
    "get_full_config", 
    handle_get_full_config,
    schema=GET_CONFIG_SCHEMA,
    supports_response=SupportsResponse.ONLY,  # ← KEY PARAMETER
)
```

Call with `?return_response` flag:
```bash
curl -X POST "$HA_URL/api/services/your_domain/get_full_config?return_response"
```

### Response Handler
```python
async def handle_get_full_config(hass: HomeAssistant, call: ServiceCall):
    """Handle the service call and return data."""
    # ... your logic ...
    return {"entities": entity_data, "automations": automation_data}
```

---

## HTTP View vs Service: When to Use Each

| Use Case | Use | Don't Use |
|----------|-----|-----------|
| Return complex data | HTTP View | Service (without response support) |
| Fire-and-forget actions | Service | HTTP View |
| Trigger automations | Service | HTTP View |
| Query state/config | HTTP View | Internal storage APIs |

### HTTP View Pattern
For data retrieval APIs:

```python
from homeassistant.components.http import HomeAssistantView

class OpenClawConfigView(HomeAssistantView):
    """HTTP view for retrieving config."""
    url = "/api/openclaw/config"
    name = "api:openclaw:config"
    requires_auth = True

    async def get(self, request):
        hass = request.app["hass"]
        config = await get_config_data(hass)
        return json_response(config)

# Register in async_setup:
hass.http.register_view(OpenClawConfigView())
```

---

## Critical: Avoid Internal APIs

**Never use underscore-prefixed APIs** — they're private and change between versions.

❌ **Wrong:**
```python
storage_collection = hass.data["_storage_collection"]
```

✅ **Right:**
```python
# Use public APIs only
from homeassistant.helpers.storage import Store
store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
```

---

## Storage Patterns

### For Small Data (Settings, Cache)
```python
from homeassistant.helpers.storage import Store

STORAGE_KEY = "your_domain.storage"
STORAGE_VERSION = 1

store = Store(hass, STORAGE_VERSION, STORAGE_KEY)

# Save
data = {"entities": modified_entities}
await store.async_save(data)

# Load
data = await store.async_load()
```

### For Large Data (History, Logs)
Use external database or file storage, not HA storage helpers.

---

## Breaking Changes to Watch

| Change | Version | Migration |
|--------|---------|-----------|
| Conversation agents | 2025.x+ | Use `async_process` directly |
| Service response data | 2023.7+ | Add `supports_response` param |
| Config entry migration | 2022.x+ | Use `async_migrate_entry` |

**Always check:** https://www.home-assistant.io/blog/ for your target version range.

---

## HACS Integration Structure

```
custom_components/your_domain/
├── __init__.py          # async_setup_entry
├── config_flow.py       # UI configuration
├── manifest.json        # Dependencies, version
├── services.yaml        # Service definitions
└── storage_services.py  # Your storage logic
```

### Minimal manifest.json
```json
{
  "domain": "your_domain",
  "name": "Your Integration",
  "codeowners": ["@yourusername"],
  "config_flow": true,
  "dependencies": [],
  "requirements": [],
  "version": "1.0.0"
}
```

---

## Testing Checklist

- [ ] Service calls return expected data (with `?return_response`)
- [ ] HTTP views accessible with auth token
- [ ] No underscore-prefixed API usage
- [ ] Storage persists across restarts
- [ ] Config flow creates config entry
- [ ] Error handling returns meaningful messages

---

## Documentation Resources

- Integration basics: `developers.home-assistant.io/docs/creating_integration_index`
- Service calls: `developers.home-assistant.io/docs/dev_101_services`
- HTTP views: `developers.home-assistant.io/docs/api/webserver`
- Breaking changes: `home-assistant.io/blog/` (filter by version)
- HACS guidelines: `hacs.xyz/docs/publish/start`

---

## Lesson Learned

From HA-OpenClaw Bridge attempt:

> *"80% of our issues were discoverable with 30-60 minutes of upfront docs reading. We jumped straight to coding based on assumptions rather than reading how HA actually works."*

Use `skills/pre-coding-research/` methodology before starting.

Overview

This skill documents Home Assistant custom integration patterns and architectural decisions for building HACS integrations, custom components, and API bridges. It focuses on practical patterns: service response data, when to use HTTP views vs services, storage APIs, avoiding private HA internals, and HACS package structure. Use it to reduce integration breakage and speed up correct implementation.

How this skill works

The skill explains concrete code patterns and registration details you can copy into your integration. It shows how to register services that return data using supports_response, how to expose read-only endpoints with HomeAssistantView, and how to persist small vs large data safely using the public Store helper. It also lists breaking changes to watch and a minimal HACS layout to follow.

When to use it

  • When you need a service to return structured response data (use supports_response).
  • When exposing read-only data for external tools or dashboards (use HTTP view).
  • When triggering automations or fire-and-forget actions (use services without HTTP view).
  • When storing small configuration or caching inside Home Assistant (use Store).
  • When packaging a HACS-compatible integration or preparing a manifest and config flow.

Best practices

  • Always use public Home Assistant APIs; never rely on underscore-prefixed internals.
  • Register services with supports_response on HA 2023.7+ when callers need returned data.
  • Use HomeAssistantView for queries and complex payload returns, not for triggering automations.
  • Store small settings with helpers.Store; offload large history/log data to external DBs or files.
  • Follow HACS directory conventions and include config_flow, manifest, and services.yaml for smoother installs.

Example use cases

  • Expose a full device configuration dump via a service call that returns JSON when called with ?return_response.
  • Provide an authenticated HTTP endpoint to return aggregated status and diagnostics for external monitoring.
  • Implement a HACS custom component with a config flow, persistent settings via Store, and service triggers for actions.
  • Migrate config entries using async_migrate_entry when adapting to breaking changes across Home Assistant versions.
  • Avoid brittle code by checking breaking changes on the Home Assistant blog before upgrading integration dependencies.

FAQ

How do I return data from a service call?

Register the service with supports_response (Requires HA 2023.7+) and return a dict from the service handler; callers must include ?return_response when invoking the service API.

When should I use an HTTP view instead of a service?

Use an HTTP view for read-only queries and complex data retrievals that benefit from standard HTTP semantics and pagination; use services for actions, automation triggers, and fire-and-forget workflows.