ha-integration
Develop custom Home Assistant integrations, config flows, entities, and platforms. Use when working with manifest.json, custom components, config_flow.py, entity base classes, or device registry. Activates on keywords: integration, custom component, config flow, entity, platform, manifest.json, device_info.
What this skill does
# Home Assistant Integration Development
> Create professional-grade custom Home Assistant integrations with complete config flows and entity implementations.
## ⚠️ BEFORE YOU START
**This skill prevents 8 common integration errors and saves ~40% implementation time.**
| Metric | Without Skill | With Skill |
|--------|--------------|------------|
| Setup Time | 45 minutes | 12 minutes |
| Common Errors | 8 | 0 |
| Config Flow Issues | 5+ | 0 |
| Entity Registration Bugs | 4+ | 0 |
### Known Issues This Skill Prevents
1. **Missing manifest.json dependencies** - Forgetting to declare required Home Assistant components
2. **Async/await issues** - Not properly awaiting coordinator updates and entity initialization
3. **Entity state class mismatches** - Using wrong STATE_CLASS (measurement vs total) for sensor platforms
4. **Config flow schema errors** - Invalid vol.Schema definitions causing validation failures
5. **Device info not linked** - Entities created without proper device registry connections
6. **Coordinator errors** - Not handling data update failures gracefully
7. **Platform import timing** - Loading platform files before component initialization
8. **Missing unique ID generation** - Creating duplicate entities across restarts
## Quick Start
### Step 1: Create manifest.json
```json
{
"domain": "my_integration",
"name": "My Integration",
"codeowners": ["@username"],
"config_flow": true,
"documentation": "https://github.com/username/ha-my-integration",
"requirements": [],
"version": "0.0.1"
}
```
**Why this matters:** The manifest.json defines integration metadata, declares dependencies, and enables config flow UI in Home Assistant.
### Step 2: Create __init__.py with async setup
```python
import asyncio
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from .coordinator import MyDataUpdateCoordinator
DOMAIN = "my_integration"
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up the integration from config entry."""
hass.data.setdefault(DOMAIN, {})
# Create coordinator
coordinator = MyDataUpdateCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
hass.data[DOMAIN][entry.entry_id] = coordinator
# Forward setup to platforms
await hass.config_entries.async_forward_entry_setups(entry, ["sensor"])
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload the integration."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, ["sensor"])
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
```
**Why this matters:** Proper async initialization ensures Home Assistant waits for data loading and platform setup completes before continuing.
### Step 3: Create config_flow.py with validation
```python
from typing import Any, Dict, Optional
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigEntry
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from .const import DOMAIN
class MyIntegrationConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle config flow for my_integration."""
async def async_step_user(self, user_input: Optional[Dict[str, Any]] = None) -> FlowResult:
"""Handle user initiation of config flow."""
errors = {}
if user_input is not None:
# Validate user input
try:
# Validate connection or API call
pass
except Exception as exc:
errors["base"] = "invalid_auth"
if not errors:
# Create unique entry
await self.async_set_unique_id(user_input.get("host"))
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input.get("name"),
data=user_input
)
# Show form
return self.async_show_form(
step_id="user",
data_schema=vol.Schema({
vol.Required("name"): str,
vol.Required("host"): str,
}),
errors=errors
)
@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry):
"""Return options flow for this integration."""
return MyIntegrationOptionsFlow(config_entry)
```
**Why this matters:** Config flows provide user-friendly setup UI and validate input before creating config entries.
## Critical Rules
### ✅ Always Do
- ✅ Use async/await throughout (async_setup_entry, async_added_to_hass, async_update_data)
- ✅ Generate unique_id for each entity (prevents duplicates on restart)
- ✅ Link entities to devices via device_info property
- ✅ Handle coordinator update failures gracefully (log, mark unavailable)
- ✅ Declare all external dependencies in manifest.json requirements
- ✅ Use type hints for better IDE support and Home Assistant compliance
- ✅ Register entities via coordinator patterns (DataUpdateCoordinator)
### ❌ Never Do
- ❌ Use synchronous network calls (requests library) - use aiohttp
- ❌ Import platform files at component level - let Home Assistant forward setup
- ❌ Create entities without unique_id - causes duplicates on restart
- ❌ Ignore coordinator update failures - mark entities unavailable
- ❌ Hardcode API endpoints - use config flow to store them
- ❌ Forget device_info when implementing multi-device integrations
- ❌ Use STATE_CLASS incorrectly (measurement vs total vs total_increasing)
### Common Mistakes
**❌ Wrong:**
```python
# Synchronous network call - blocks event loop
import requests
data = requests.get("https://api.example.com/data").json()
# No unique_id - duplicate entities on restart
class MySensor(SensorEntity):
pass
# Missing await
coordinator.async_refresh()
```
**✅ Correct:**
```python
# Async network call - doesn't block
async with aiohttp.ClientSession() as session:
async with session.get("https://api.example.com/data") as resp:
data = await resp.json()
# Proper unique_id generation
class MySensor(SensorEntity):
@property
def unique_id(self) -> str:
return f"{self.coordinator.data['id']}_sensor"
# Proper await
await coordinator.async_request_refresh()
```
**Why:** Synchronous calls block Home Assistant's event loop, causing UI freezes. Missing unique_id causes entity duplicates. Missing await means code continues before async operation completes.
## Known Issues Prevention
| Issue | Root Cause | Solution |
|-------|-----------|----------|
| **Duplicate entities on restart** | No unique_id set | Implement `unique_id` property with stable identifier |
| **Config flow validation fails silently** | Missing error handling in async_step_user | Wrap validation in try/except, set errors dict |
| **Entity state doesn't update** | Coordinator not refreshing or entity not subscribed | Use @callback decorator for update listeners |
| **Device not appearing** | Missing device_info or device_identifier mismatch | Set device_info with identifiers matching registry |
| **UI freezes during setup** | Synchronous network calls in async_setup_entry | Use aiohttp for all async network operations |
| **Platform imports fail** | Importing platform files in __init__.py | Let Home Assistant handle via async_forward_entry_setups |
## Manifest Configuration Reference
### manifest.json
```json
{
"domain": "integration_name",
"name": "Integration Display Name",
"codeowners": ["@github_username"],
"config_flow": true,
"documentation": "https://github.com/username/repo",
"homeassistant": "2024.1.0",
"requirements": ["requests>=2.25.0"],
"version": "1.0.0",
"issue_tracker": "https://github.com/username/repo/issues"
}
```
**Key settings:**
- `domain`: Unique identifier (alphanuRelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.