插件基础结构:从零搭建你的第一个插件
说实话,很多刚接触 Home Assistant 插件开发的朋友,第一反应都是:「这玩意儿到底长什么样?」
今天我就带你拆解一个插件的基本骨架。你想想看,盖房子得有地基、梁柱、门窗对吧?插件也一样。搞清楚了这些基础结构,后面写代码就顺风顺水了。
插件目录结构:约定大于配置
Home Assistant 的插件,说白了就是一个文件夹。但这个文件夹里的东西,得按规矩来放。我刚开始做的时候,就吃过乱放文件的亏——插件死活加载不上,查了半天才发现是少了个 __init__.py。
一个标准的插件目录长这样:
custom_components/
└── my_component/ # 插件根目录,名字就是你的域名
├── __init__.py # 入口文件,必须存在
├── manifest.json # 清单文件,描述插件信息
├── config_flow.py # 配置流程(可选,但推荐)
├── const.py # 常量定义
├── sensor.py # 传感器实体(示例)
├── switch.py # 开关实体(示例)
├── services.yaml # 服务定义
├── translations/ # 多语言翻译
│ └── zh-Hans.json
└── icons/ # 自定义图标(可选)
嗯,这里要注意:custom_components 这个目录名是固定的,不能改。你的插件就放在它下面,每个插件一个子目录。
核心原则:插件目录名 = 域名(domain),全局唯一。我建议你用「作者名_组件名」的格式,比如 john_weather,这样不容易跟别人的冲突。
manifest.json 详解:插件的身份证
这个文件是 Home Assistant 识别你插件的关键。没有它,系统根本不知道你是谁、能干什么。
来看一个实际例子:
{
"domain": "my_component",
"name": "我的自定义组件",
"version": "1.0.0",
"requirements": ["requests>=2.25.0"],
"dependencies": ["mqtt"],
"codeowners": ["@your_github"],
"config_flow": true,
"iot_class": "local_polling",
"documentation": "https://example.com/docs",
"issue_tracker": "https://github.com/your/repo/issues",
"integration_type": "hub",
"loggers": ["custom_components.my_component"]
}
每个字段我都踩过坑,给你说说重点:
| 字段 | 说明 | 我的经验 |
|---|---|---|
domain |
插件唯一标识,必须跟目录名一致 | 大小写敏感,全小写最安全 |
version |
语义化版本号 | 我习惯用 1.0.0 起步,别从 0.0.1 开始 |
requirements |
Python 依赖包列表 | 尽量少依赖,否则用户安装会卡住 |
iot_class |
设备通信方式 | 选错了会影响系统性能评估 |
config_flow |
是否支持 UI 配置 | 强烈建议设为 true |
我曾经踩过的坑:有一次我把 domain 写成了驼峰命名 MyComponent,结果 Home Assistant 加载时直接报错。记住:domain 必须全小写,用下划线分隔单词。
config.json 配置:其实它已经退役了
这里有个历史遗留问题要讲清楚。早期版本的 Home Assistant 确实用 config.json 来定义配置选项。但从 2021 年开始,官方推荐用 config_flow.py 替代了。
为什么?因为 config.json 只能做静态配置,用户得手动编辑 YAML 文件。而 config_flow.py 可以在 UI 上一步步引导用户完成配置,体验好太多了。
不过,如果你维护的是老插件,可能还会看到这样的 config.json:
{
"name": "My Component",
"version": "1.0.0",
"config": {
"type": "string",
"required": true,
"default": "default_value"
}
}
我个人建议:新插件一律用 config_flow.py。老插件如果还在用 config.json,趁早迁移吧。
入口文件 __init__.py:插件的启动引擎
这个文件是插件的灵魂。Home Assistant 启动时,会先加载 manifest.json,然后执行 __init__.py 里的代码。
一个最简的入口文件长这样:
"""我的第一个自定义组件"""
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType
DOMAIN = "my_component"
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""初始化插件"""
hass.states.async_set(f"{DOMAIN}.hello", "world")
return True
这里有几个关键点:
async_setup是异步函数,不能阻塞- 返回
True表示初始化成功 hass对象是整个系统的核心,所有操作都通过它
小技巧:我习惯在 async_setup 里先打印一条日志,确认插件被加载了。用 _LOGGER.info("插件已加载"),调试时特别有用。
知识体系结构图
下面这张图帮你理清插件各文件之间的关系:
实战建议:从模板开始
说了这么多理论,其实最好的学习方法就是动手。我建议你这样做:
- 在
custom_components下新建一个目录,比如my_first_plugin - 创建
manifest.json,只填必填字段 - 创建
__init__.py,写一个最简单的async_setup - 重启 Home Assistant,看日志里有没有你的插件
嗯,就这么简单。等你跑通了第一个插件,后面加实体、加服务就水到渠成了。
记住:插件开发不是写代码,而是搭积木。manifest 是说明书,__init__ 是发动机,config_flow 是操作面板。三样东西凑齐了,你的插件就能跑起来了。
好了,这一章的内容就到这里。下一章我们会深入 async_setup 的细节,看看怎么在里面注册实体、监听事件。但那是后话了,先把今天的基础结构吃透再说。