插件基础结构:从零搭建你的第一个插件

说实话,很多刚接触 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("插件已加载"),调试时特别有用。

知识体系结构图

下面这张图帮你理清插件各文件之间的关系:

插件基础结构关系图 插件根目录 manifest.json __init__.py config_flow.py 功能: 定义插件元数据 版本、依赖、作者 功能: 插件启动入口 初始化逻辑 功能: UI配置流程 用户交互 核心流程 1. HA 读取 manifest.json → 验证插件合法性 2. 执行 __init__.py → 调用 async_setup() 3. 如果有 config_flow → 提供 UI 配置界面

实战建议:从模板开始

说了这么多理论,其实最好的学习方法就是动手。我建议你这样做:

  1. 在 custom_components 下新建一个目录,比如 my_first_plugin
  2. 创建 manifest.json,只填必填字段
  3. 创建 __init__.py,写一个最简单的 async_setup
  4. 重启 Home Assistant,看日志里有没有你的插件

嗯,就这么简单。等你跑通了第一个插件,后面加实体、加服务就水到渠成了。

记住:插件开发不是写代码,而是搭积木。manifest 是说明书,__init__ 是发动机,config_flow 是操作面板。三样东西凑齐了,你的插件就能跑起来了。

好了,这一章的内容就到这里。下一章我们会深入 async_setup 的细节,看看怎么在里面注册实体、监听事件。但那是后话了,先把今天的基础结构吃透再说。

可可精品资料库